summaryrefslogtreecommitdiff
path: root/frontend/gamma
authorGiulio Cesare Solaroli <giulio.cesare@clipperz.com>2011-10-02 23:56:18 (UTC)
committer Giulio Cesare Solaroli <giulio.cesare@clipperz.com>2011-10-02 23:56:18 (UTC)
commitef68436ac04da078ffdcacd7e1f785473a303d45 (patch) (side-by-side diff)
treec403752d66a2c4775f00affd4fa8431b29c5b68c /frontend/gamma
parent597ecfbc0249d83e1b856cbd558340c01237a360 (diff)
downloadclipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.zip
clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.gz
clipperz-ef68436ac04da078ffdcacd7e1f785473a303d45.tar.bz2
First version of the newly restructured repository
Diffstat (limited to 'frontend/gamma') (more/less context) (ignore whitespace changes)
-rw-r--r--frontend/gamma/css/clipperz/clipperz.css4520
-rw-r--r--frontend/gamma/css/clipperz/compact.css162
-rw-r--r--frontend/gamma/css/clipperz/iPhone.css464
-rw-r--r--frontend/gamma/css/clipperz/ie.css356
-rw-r--r--frontend/gamma/graphics/CoverActions.opacitybin0 -> 25547 bytes
-rw-r--r--frontend/gamma/graphics/Features.opacitybin0 -> 140849 bytes
-rw-r--r--frontend/gamma/graphics/GridSorting.opacitybin0 -> 14681 bytes
-rw-r--r--frontend/gamma/graphics/Logo.opacitybin0 -> 10647 bytes
-rw-r--r--frontend/gamma/graphics/Marks.opacitybin0 -> 25340 bytes
-rw-r--r--frontend/gamma/graphics/RegisterButton.opacitybin0 -> 44806 bytes
-rw-r--r--frontend/gamma/graphics/Star.opacitybin0 -> 16210 bytes
-rw-r--r--frontend/gamma/graphics/Tips.opacitybin0 -> 46046 bytes
-rw-r--r--frontend/gamma/html/exitPage_template.html140
-rw-r--r--frontend/gamma/html/index_template.html62
-rw-r--r--frontend/gamma/html/mobile_template.html87
-rw-r--r--frontend/gamma/js/Bookmarklet.js801
-rw-r--r--frontend/gamma/js/BookmarkletHash.js47
-rw-r--r--frontend/gamma/js/Bookmarklet_1.js400
-rw-r--r--frontend/gamma/js/Bookmarklet_2.js767
-rw-r--r--frontend/gamma/js/Bookmarklet_IE.js23
-rw-r--r--frontend/gamma/js/Clipperz/Async.js707
-rw-r--r--frontend/gamma/js/Clipperz/Base.js531
-rw-r--r--frontend/gamma/js/Clipperz/ByteArray.js1501
-rw-r--r--frontend/gamma/js/Clipperz/CSVProcessor.js349
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/AES.js869
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/Base.js1852
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/BigInt.js1760
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/BigInt_scoped.js1649
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Curve.js550
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js526
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Point.js67
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Value.js386
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/ECC/StandardCurves.js239
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/PRNG.js855
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/RSA.js151
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/SHA.js301
-rw-r--r--frontend/gamma/js/Clipperz/Crypto/SRP.js331
-rw-r--r--frontend/gamma/js/Clipperz/DOM.js139
-rw-r--r--frontend/gamma/js/Clipperz/Date.js305
-rw-r--r--frontend/gamma/js/Clipperz/KeePassExportProcessor.js196
-rw-r--r--frontend/gamma/js/Clipperz/KeyValueObjectStore.js176
-rw-r--r--frontend/gamma/js/Clipperz/Logging.js42
-rw-r--r--frontend/gamma/js/Clipperz/PM/BookmarkletProcessor.js196
-rw-r--r--frontend/gamma/js/Clipperz/PM/Connection.js619
-rw-r--r--frontend/gamma/js/Clipperz/PM/Crypto.js513
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/DirectLogin.js1076
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/DirectLoginBinding.js125
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/DirectLoginFormValue.js107
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/DirectLoginInput.js203
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/EncryptedRemoteObject.js551
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/OneTimePassword.js357
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/Record.Version.Field.js167
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/Record.Version.js336
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/Record.js881
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/User.Header.Legacy.js187
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js128
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/User.Header.Preferences.js53
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js705
-rw-r--r--frontend/gamma/js/Clipperz/PM/DataModel/User.js817
-rw-r--r--frontend/gamma/js/Clipperz/PM/Date.js201
-rw-r--r--frontend/gamma/js/Clipperz/PM/Proxy.js172
-rwxr-xr-xfrontend/gamma/js/Clipperz/PM/Proxy/Proxy.JSON.js94
-rw-r--r--frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js811
-rw-r--r--frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.js67
-rw-r--r--frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Test.js167
-rw-r--r--frontend/gamma/js/Clipperz/PM/Strings.js295
-rw-r--r--frontend/gamma/js/Clipperz/PM/Strings/MessagePanelConfigurations.js389
-rw-r--r--frontend/gamma/js/Clipperz/PM/Strings/Strings_defaults.js390
-rw-r--r--frontend/gamma/js/Clipperz/PM/Strings/Strings_en-US.js1341
-rw-r--r--frontend/gamma/js/Clipperz/PM/Toll.js194
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/CoverActions/download.js120
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/CoverActions/look.js208
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/directLogin.js209
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/protect.js237
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/share.js1719
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/store.js310
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/GraphicFunctions.js68
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/Logo/normal.js65
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/Marks/exclamationMark.js280
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/Marks/info.js391
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/Marks/questionMark.js438
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/RegisterButton/normal.js403
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/Star/normal.js153
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/Tips/close.js156
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Canvas/Tips/open.js163
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Components/BaseComponent.js611
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Components/Button.js108
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Components/ComponentSlot.js64
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Components/FaviconComponent.js91
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Components/MessagePanelWithProgressBar.js164
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js140
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Components/ProgressBar.js73
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js282
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Components/TabPanelComponent.js69
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Components/Tooltip.js216
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Components/TranslatorWidget.js170
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js267
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/ProgressBarController.js143
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/TabPanelController.js188
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/WizardController.js31
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Compact/MainController.js59
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js148
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/AppPage.js78
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/BookmarkletComponent.js109
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogComponent.js881
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogRecordDirectLoginComponent.js182
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js190
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/ColumnManager.js203
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/CreateNewCardSplashComponent.js71
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js111
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/DateColumnManager.js72
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/DeleteObjectColumnManager.js70
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginColumnManager.js90
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingBindingComponent.js168
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingComponent.js481
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingFormValueComponent.js179
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginsColumnManager.js271
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/FaviconColumnManager.js89
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/GridComponent.js262
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/ImageColumnManager.js68
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/LinkColumnManager.js92
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginForm.js203
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginPage.js206
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js155
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/NewUserCreationComponent.js430
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/Page.js71
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/PageFooter.js71
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/PageHeader.js184
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/PasswordTooltip.js164
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/RulerComponent.js324
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/TabSidePanel.js193
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/TextColumnManager.js53
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js113
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/UnlockPasswordComponent.js184
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Components/UserInfoBox.js346
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js329
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardDialogController.js652
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardsController.js207
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginWizardController.js611
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginsController.js145
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/FilterController.js158
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js374
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/LoginController.js259
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/MainController.js218
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/NewUserWizardController.js469
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardDetail.js166
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardList.js204
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/LoginForm.js181
-rw-r--r--frontend/gamma/js/Clipperz/PM/UI/iPhone/Controllers/MainController.js372
-rw-r--r--frontend/gamma/js/Clipperz/Set.js167
-rw-r--r--frontend/gamma/js/Clipperz/Signal.js71
-rw-r--r--frontend/gamma/js/Clipperz/Style.js94
-rw-r--r--frontend/gamma/js/Clipperz/Visual.js368
-rw-r--r--frontend/gamma/js/Clipperz/YUI/DomHelper.js481
-rw-r--r--frontend/gamma/js/Clipperz/YUI/DomQuery.js714
-rw-r--r--frontend/gamma/js/Clipperz/YUI/Utils.js98
-rw-r--r--frontend/gamma/js/JSON/json2.js481
-rw-r--r--frontend/gamma/js/MochiKit/Async.js640
-rw-r--r--frontend/gamma/js/MochiKit/Base.js1452
-rw-r--r--frontend/gamma/js/MochiKit/Color.js832
-rw-r--r--frontend/gamma/js/MochiKit/DOM.js1144
-rw-r--r--frontend/gamma/js/MochiKit/DateTime.js173
-rw-r--r--frontend/gamma/js/MochiKit/DragAndDrop.js766
-rw-r--r--frontend/gamma/js/MochiKit/Format.js309
-rw-r--r--frontend/gamma/js/MochiKit/Iter.js790
-rw-r--r--frontend/gamma/js/MochiKit/Logging.js262
-rw-r--r--frontend/gamma/js/MochiKit/LoggingPane.js327
-rw-r--r--frontend/gamma/js/MochiKit/MochiKit.js136
-rw-r--r--frontend/gamma/js/MochiKit/MockDOM.js115
-rw-r--r--frontend/gamma/js/MochiKit/Position.js218
-rw-r--r--frontend/gamma/js/MochiKit/Selector.js387
-rw-r--r--frontend/gamma/js/MochiKit/Signal.js888
-rw-r--r--frontend/gamma/js/MochiKit/Sortable.js569
-rw-r--r--frontend/gamma/js/MochiKit/Style.js558
-rw-r--r--frontend/gamma/js/MochiKit/Test.js144
-rw-r--r--frontend/gamma/js/MochiKit/Text.js577
-rw-r--r--frontend/gamma/js/MochiKit/Visual.js1975
-rw-r--r--frontend/gamma/js/MochiKit/__package__.js18
-rw-r--r--frontend/gamma/js/main.js109
-rw-r--r--frontend/gamma/js/main_iPhone.js60
-rw-r--r--frontend/gamma/properties/creditsAndCopyrights.txt336
-rw-r--r--frontend/gamma/properties/gamma.properties.json189
-rw-r--r--frontend/gamma/properties/mobile.properties.json119
-rw-r--r--frontend/gamma/tests/SimpleTest/SimpleTest.Async.js169
-rw-r--r--frontend/gamma/tests/SimpleTest/SimpleTest.js424
-rw-r--r--frontend/gamma/tests/SimpleTest/TestRunner.js233
-rw-r--r--frontend/gamma/tests/SimpleTest/test.css28
-rwxr-xr-xfrontend/gamma/tests/index.html56
-rw-r--r--frontend/gamma/tests/tests/Bookmarklet/Bookmarklet.css201
-rw-r--r--frontend/gamma/tests/tests/Bookmarklet/Fail.html113
-rw-r--r--frontend/gamma/tests/tests/Bookmarklet/Twitter.html113
-rwxr-xr-xfrontend/gamma/tests/tests/Bookmarklet/ZeroClipboard.swfbin0 -> 1071 bytes
-rw-r--r--frontend/gamma/tests/tests/Bookmarklet/background.pngbin0 -> 10335 bytes
-rw-r--r--frontend/gamma/tests/tests/Bookmarklet/close.pngbin0 -> 3984 bytes
-rw-r--r--frontend/gamma/tests/tests/Bookmarklet/close_selected.pngbin0 -> 3995 bytes
-rw-r--r--frontend/gamma/tests/tests/Bookmarklet/copy.pngbin0 -> 5241 bytes
-rw-r--r--frontend/gamma/tests/tests/Bookmarklet/copy_selected.pngbin0 -> 5169 bytes
-rw-r--r--frontend/gamma/tests/tests/Bookmarklet/error.pngbin0 -> 4682 bytes
-rw-r--r--frontend/gamma/tests/tests/Bookmarklet/hint.pngbin0 -> 3999 bytes
-rw-r--r--frontend/gamma/tests/tests/Bookmarklet/index.html42
-rw-r--r--frontend/gamma/tests/tests/Bookmarklet/info.pngbin0 -> 4781 bytes
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Async.html53
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Async.test.js687
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Base.html55
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Base.test.js367
-rw-r--r--frontend/gamma/tests/tests/Clipperz/ByteArray.html71
-rw-r--r--frontend/gamma/tests/tests/Clipperz/ByteArray.test.js893
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/AES.html292
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/AES.performance.html344
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/Base.html428
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/BigInt.html478
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/ECC.B283.deferred.html155
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/ECC.BinaryField.FiniteField.B283.html209
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/ECC.BinaryField.FiniteField.html183
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/ECC.BinaryField.Value.html496
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/ECC.K283.deferred.html160
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/JSCrypto_vs_Clipperz.html70
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/JSCrypto_vs_Clipperz.test.js418
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/PRNG.html117
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/RSA.html90
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/SHA.html175
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/SHA.test.js84
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/SRP.html161
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/Usage.html122
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/index.html58
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Crypto/jscrypto.js1577
-rw-r--r--frontend/gamma/tests/tests/Clipperz/DOM.html58
-rw-r--r--frontend/gamma/tests/tests/Clipperz/DOM.test.js82
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Date.html54
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Date.test.js66
-rw-r--r--frontend/gamma/tests/tests/Clipperz/KeePassExportProcessor.data.js910
-rw-r--r--frontend/gamma/tests/tests/Clipperz/KeePassExportProcessor.html59
-rw-r--r--frontend/gamma/tests/tests/Clipperz/KeePassExportProcessor.test.js141
-rw-r--r--frontend/gamma/tests/tests/Clipperz/KeyValueObjectStore.html52
-rw-r--r--frontend/gamma/tests/tests/Clipperz/KeyValueObjectStore.test.js255
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/BookmarkletProcessor.html59
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/BookmarkletProcessor.test.js132
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/Connection.data.js841
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/Connection.html71
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/Connection.test.js255
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/Crypto.html281
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/Crypto_performanceEvaluation.html153
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/Crypto_test.html169
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLogin.html103
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLogin.test.js195
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLoginConfigurations.data.js33
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/EncryptedRemoteObject.html66
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/EncryptedRemoteObject.test.js225
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/OneTimePassword.html105
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/OneTimePassword.test.js198
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.html98
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.test.js1285
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.data.js1941
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.data.old.js172
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.html106
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.test.js2082
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/DataModel/index.html47
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/Date.html59
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/Date.test.js90
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/Proxy.html65
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/Proxy.test.js117
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/Toll.html62
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/Toll.test.js202
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/UI/Web/Controllers/MainController.html64
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/UI/Web/Controllers/MainController.test.js90
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/UI/Web/Controllers/index.html46
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/UI/Web/index.html45
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/UI/index.html45
-rw-r--r--frontend/gamma/tests/tests/Clipperz/PM/index.html56
-rw-r--r--frontend/gamma/tests/tests/Clipperz/RoboFormExportProcessor.html210
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Set.html54
-rw-r--r--frontend/gamma/tests/tests/Clipperz/Set.test.js165
-rw-r--r--frontend/gamma/tests/tests/Clipperz/index.html49
-rw-r--r--frontend/gamma/tests/tests/Clipperz/index_googleCode.html50
-rw-r--r--frontend/gamma/tests/tests/Clipperz/index_testECC.html50
-rw-r--r--frontend/gamma/tests/tests/Components/CardDialogEditing/CardDialogEditing_test.js238
-rw-r--r--frontend/gamma/tests/tests/Components/CardDialogEditing/User.data.js1881
-rw-r--r--frontend/gamma/tests/tests/Components/CardDialogEditing/dragAndDrop_test.js128
-rw-r--r--frontend/gamma/tests/tests/Components/CardDialogEditing/index.html133
-rw-r--r--frontend/gamma/tests/tests/Components/CardDialogNew/User.data.js977
-rw-r--r--frontend/gamma/tests/tests/Components/CardDialogNew/cardDialogNew_test.js127
-rw-r--r--frontend/gamma/tests/tests/Components/CardDialogNew/index.html117
-rw-r--r--frontend/gamma/tests/tests/Components/FullApp/README.txt1
-rw-r--r--frontend/gamma/tests/tests/Components/FullApp/User.data.js1044
-rw-r--r--frontend/gamma/tests/tests/Components/FullApp/index.html243
-rw-r--r--frontend/gamma/tests/tests/Components/FullApp/main_test.js114
-rw-r--r--frontend/gamma/tests/tests/Components/GridLayout/GridLayout_test.js119
-rw-r--r--frontend/gamma/tests/tests/Components/GridLayout/TestPageComponent.js102
-rw-r--r--frontend/gamma/tests/tests/Components/GridLayout/User.data.js977
-rw-r--r--frontend/gamma/tests/tests/Components/GridLayout/index.html135
-rw-r--r--frontend/gamma/tests/tests/Components/GridLayout/test.css43
-rw-r--r--frontend/gamma/tests/tests/Components/ProgressBar/index.html120
-rw-r--r--frontend/gamma/tests/tests/Components/ProgressBar/progressBar_test.js125
-rw-r--r--frontend/gamma/tests/tests/Components/SimpleMessagePanel/index.html115
-rw-r--r--frontend/gamma/tests/tests/Components/SimpleMessagePanel/simpleMessagePanel_test.js95
-rw-r--r--frontend/gamma/tests/tests/Components/Tooltips/index.html143
-rw-r--r--frontend/gamma/tests/tests/Components/Tooltips/tooltips_test.js117
-rw-r--r--frontend/gamma/tests/tests/Components/UnlockPassword/User.data.js977
-rw-r--r--frontend/gamma/tests/tests/Components/UnlockPassword/index.html117
-rw-r--r--frontend/gamma/tests/tests/Components/UnlockPassword/unlockPassword_test.js136
-rw-r--r--frontend/gamma/tests/tests/Components/crossWindowsBookmarklet/CrossWindowsBookmarklet_test.js66
-rw-r--r--frontend/gamma/tests/tests/Components/crossWindowsBookmarklet/index.html73
-rw-r--r--frontend/gamma/tests/tests/index.html48
303 files changed, 95919 insertions, 0 deletions
diff --git a/frontend/gamma/css/clipperz/clipperz.css b/frontend/gamma/css/clipperz/clipperz.css
new file mode 100644
index 0000000..dba4d57
--- a/dev/null
+++ b/frontend/gamma/css/clipperz/clipperz.css
@@ -0,0 +1,4520 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+/* @override
+ https://www.example.com/DEVELOPMENT/css/clipperz.css
+ http://www.example.com/DEVELOPMENT/css/clipperz.css
+ https://www.clipperz.com/gamma/css/clipperz.css
+ https://www.example.com/iPHONE/css/clipperz.css
+*/
+
+/*
+Color list:
+- login box:
+ light #ff9955
+ dark #ff6622
+- login button:
+ regular #dd5500
+ hover #773311
+- login translations:
+ box: #cc6622;
+ not-selected:
+ color: #ddaa99
+ background: #994422
+ selected: #772211;
+
+*/
+
+html {
+ height: 100%;
+}
+
+body {
+/* margin-left: 15px; margin-right: 15px;*/
+ font-family: Helvetica, Arial, Geneva, sans-serif;
+ margin: 0px;
+/*
+ min-width: 600px;
+*/
+ height: 100%;
+}
+
+img.favicon {
+ height: 16px;
+ width: 16px;
+}
+
+/* @group Misc */
+
+.clear {
+ clear: both;
+}
+
+.hidden_none {
+ display: none;
+ visibility: hidden;
+}
+
+.keepTogether {
+ display: inline-block;
+ white-space: nowrap;
+}
+
+body.ext-gecko .keepTogether {
+ display: -moz-inline-box;
+}
+
+/* @end */
+
+/* @group Loading */
+
+div#loading {
+ margin-left: auto;
+ margin-right: auto;
+ text-align: center;
+ margin-top: 60px;
+ width: 200px;
+}
+
+div#loading img {
+ border: 0px;
+}
+
+div#loading h5 {
+ font-size: 16pt;
+ padding: 0px;
+ color: #333366;
+}
+
+div#loading h2 {
+ padding-left: 20px;
+ color: #ff9200;
+}
+
+
+/* @end */
+
+/* @group Login page */
+
+/* @group Header */
+
+div.pageHeader {
+ background-color: #1f2148;
+ min-width: 1013px;
+}
+
+div#logoFrame {
+ padding: 16px 16px 60px 16px;
+ min-height: 44px;
+}
+
+
+div#logoFrame div#logo {
+ background: url(../images/old/logo.png);
+ width: 150px;
+ height: 39px;
+}
+
+
+div#loading div#logo {
+ background: url(../images/old/logo_blue.png);
+ width: 193px;
+ height: 58px;
+ display: block;
+}
+
+h5.clipperzPayoff {
+ color: white;
+ font-size: 13pt;
+ font-weight: normal;
+ padding-left: 20px;
+ white-space: nowrap;
+ margin: 0px;
+ padding-left: 4px;
+}
+
+
+/* @group Misc links */
+
+div#miscLinks {
+ float: right;
+}
+
+div#miscLinks ul {
+ margin: 12px 0px 0px;
+ padding: 15px;
+}
+
+div#miscLinks ul li {
+ display: inline;
+ margin: 0px; padding: 0px; border: 0px;
+}
+
+div#miscLinks ul li a {
+/*
+ color: #ccccff;
+*/
+ color: white;
+ margin: 0px; padding: 0px; border: 0px;
+ font-weight: normal;
+ text-decoration: none;
+ font-size: 12pt;
+ border-left: 1px solid #45486b;
+ padding: 15px;
+ margin: 0px;
+ min-width: 70px;
+}
+
+div#miscLinks ul li a#donateHeaderLink {
+ border-left: 0px;
+}
+
+div#miscLinks ul li a:hover {
+ color: #ff9200;
+}
+
+
+
+/* @end */
+
+
+/* @group Features Tabs */
+#featureTabs table {
+ width: 100%;
+ padding: 6px;
+ padding-bottom: 46px;
+}
+
+#featureTabs table tr td {
+ width: 25%;
+ vertical-align: top;
+ font-size: 11pt;
+ color: white;
+}
+
+#featureTabs table tr td img {
+ float: left;
+}
+
+#featureTabs table tr td span {
+ display: block;
+ padding: 5 10 5 85;
+}
+
+div#featureTabs canvas.featureIcon {
+ width: 76px;
+ height: 76px;
+ display: block;
+ float: left;
+
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ff9955), to(#ff6622), color-stop(1,#333333));
+ background: -moz-linear-gradient(0% 100% 90deg,#ff6622, #ff9955);
+
+ -webkit-border-radius: 38px;
+ -moz-border-radius: 38px;
+ border-radius: 38px;
+}
+/*
+div#featureTabs div.featureIcon.storeIcon {
+ background-image: url(../images/old/home/features/store.png);
+}
+
+div#featureTabs div.featureIcon.protectIcon {
+ background-image: url(../images/old/home/features/protect.png);
+}
+
+div#featureTabs div.featureIcon.directLoginIcon {
+ background-image: url(../images/old/home/features/directLogin.png);
+}
+
+div#featureTabs div.featureIcon.shareIcon {
+ background-image: url(../images/old/home/features/share.png);
+}
+*/
+/*
+./images/home/features/store.png
+./images/home/features/protect.png
+./images/home/features/directLogin.png
+./images/home/features/share.png
+*/
+
+/* @end */
+
+/* @group Feature bullets */
+
+div#featurePoints {
+ min-width: 400px;
+ padding-left: 20px;
+ padding-right: 330px;
+ padding-top: 15px;
+ padding-bottom: 20px;
+}
+
+div#featurePoints table tbody tr td {
+ width: 50%;
+ vertical-align: top;
+}
+
+div#featurePoints table tbody tr td.separator {
+ width: 1px;
+ border-left: 1px solid #bebebe;
+}
+
+div#featurePoints div.block {
+ padding: 10px;
+ color: #8e8e8e;
+}
+
+div#featurePoints div.block h3 {
+ font-weight: normal;
+ font-size: 12pt;
+ margin: 0px;
+ padding: 5px 0px;
+}
+
+div#featurePoints div.block ul {
+ margin: 0px;
+ margin-left: 20px;
+ padding: 0px;
+ list-style-position: outside;
+ list-style-image: url(../images/old/home/features/bullet.png);
+}
+
+div#featurePoints div.block ul li {
+ font-size: 10pt;
+ padding: 3px 0px;
+}
+
+/* @end */
+
+
+
+/* @end */
+
+/* @group Login box */
+
+div#loginBox {
+ width: 273px;
+/* z-index: 40000; */
+ z-index: 19000;
+ position: relative;
+ top: -30px;
+ right: 30px;
+ float: right;
+}
+
+div#loginBox div.header {
+ height: 25px;
+ width: 273px;
+/* background-image: url(../images/old/home/box/box_top.png); */
+/* background-color: #fe965f; */
+ background-color: #ff9955;
+
+ -webkit-border-top-left-radius: 20px;
+ -webkit-border-top-right-radius: 20px;
+ -moz-border-radius-topleft: 20px;
+ -moz-border-radius-topright: 20px;
+ border-top-left-radius: 20px;
+ border-top-right-radius: 20px;
+}
+
+div#loginBox div.body {
+ background-color: #ff9955;
+
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ff9955), to(#ff6622), color-stop(1,#333333));
+ background: -moz-linear-gradient(0% 100% 90deg,#ff6622, #ff9955);
+
+/* background: url(../images/old/home/box/box_body.png) repeat-x; */
+}
+
+div#loginBox div.body h3.loading {
+ margin: 0px;
+ text-align: center;
+ padding-top: 60px;
+ color: white;
+ font-size: 30pt;
+ padding-left: 20px;
+}
+
+div#loginBox div.footer {
+ height: 37px;
+ width: 273px;
+/* background-image: url(../images/old/home/box/box_bottom.png); */
+ background-color: #ff6622;
+
+ -webkit-border-bottom-left-radius: 20px;
+ -webkit-border-bottom-right-radius: 20px;
+ -moz-border-radius-bottomleft: 20px;
+ -moz-border-radius-bottomright: 20px;
+ border-bottom-left-radius: 20px;
+ border-bottom-right-radius: 20px;
+}
+
+/* @group Login form */
+
+div#loginBox h4 {
+ color: white;
+ font-size: 16pt;
+ font-weight: normal;
+ padding-left: 20px;
+ margin: 0px;
+}
+
+div#loginBox form.loginForm {
+ padding: 5px 20px 0px;
+ margin-bottom: 0px;
+}
+
+div#loginBox form.loginForm label {
+ color: white;
+ font-size: 10pt;
+ display: block;
+ padding-top: 5px;
+}
+
+div#loginBox form.loginForm input {
+ width: 230px;
+ font-size: 14pt;
+ border: 1px solid #bb4924;
+ color: #333366;
+ background-color: white;
+ padding: 2px 5px;
+ height: 28px;
+}
+
+div#loginBox form.loginForm label.checkbox {
+ display: inline;
+}
+
+div#loginBox form.loginForm .checkbox:hover {
+ cursor: pointer;
+}
+
+div#loginBox form.loginForm input.checkbox {
+ margin: 10px 8px 0px 0px;
+ height: auto;
+ width: auto;
+ border: 0px;
+}
+
+div#loginBox form.loginForm ul {
+ list-style-type: none;
+ padding: 0px;
+ margin: 0px;
+}
+
+div#loginBox form.loginForm ul li {
+ display: block;
+}
+
+div#loginBox form.loginForm input.otp {
+ width: 57px;
+ display: inline;
+ padding-left: 0px;
+ padding-right: 0px;
+ height: 28px;
+ font: 8pt monospace;
+}
+
+
+
+div#loginBox form.loginForm input.submit {
+ margin: 0px 45px;
+ width: 140px;
+ border: 1px solid white;
+ color: white;
+ background-color: #dd5500;
+ padding: 6px;
+ font-size: 12pt;
+ height: auto;
+}
+
+div#loginBox form.loginForm input.submit:hover {
+ background-color: #773311;
+ color: white;
+ cursor: pointer;
+}
+
+
+/* @group language chooser */
+
+div#loginBox form.loginForm div.translations {
+ margin: 15px -20px;
+ background-color: #cc6622;
+}
+
+div#loginBox form.loginForm div.translations h4 {
+ font-size: 9pt;
+ padding: 6px 20px 0px;
+}
+
+div#loginBox form.loginForm div.translations ul {
+ margin: 0px;
+ padding: 5px 10px 10px;
+ margin-bottom: 15px;
+}
+
+div#loginBox form.loginForm div.translations ul li {
+ font-size: 8pt;
+ color: #ddaa99;
+ display: inline-block;
+ padding: 2px 4px;
+ background-color: #994422;
+ margin: 1px;
+}
+
+body.ext-gecko div#loginBox form.loginForm div.translations ul li {
+ display: -moz-inline-box;
+}
+
+div#loginBox form.loginForm div.translations ul li.selected {
+ background-color: #772211;
+ color: white;
+}
+
+div#loginBox form.loginForm div.translations ul li.selected:hover {
+ cursor: default;
+}
+
+div#loginBox form.loginForm div.translations ul li:hover {
+ cursor: pointer;
+ color: white;
+}
+
+/* @end */
+
+/* @end */
+
+/* @end */
+
+/* @group Create/Look/Offline */
+
+div.activeFeatures {
+ float: left;
+ margin-left: 20px;
+ height: 100px;
+}
+
+div.activeFeatures a {
+ display: inline-block;
+
+ padding-left: 46px;
+ color: #ff5906;
+ text-decoration: none;
+ font-size: 10pt;
+}
+
+
+div.activeFeatures .keepTogether a {
+ padding-left: 0px;
+}
+
+div.activeFeatures a span.payoff {
+ display: block;
+ font-size: 13pt;
+ font-weight: lighter;
+ color: #9b9689;
+ margin: 0px;
+ padding: 0px;
+}
+
+/*body.ext-gecko div.activeFeatures a {
+ display: -moz-inline-box;
+}*/
+div.activeFeatures a:hover span.payoff {
+ color: #666666;
+}
+
+div.activeFeatures a:hover span.link {
+/* font-weight: bold;*/
+}
+
+div.activeFeatures div.keepTogether div {
+ display: inline-block;
+ padding-right: 15px;
+}
+
+/*body.ext-gecko div.activeFeatures div.keepTogether div {
+ display: -moz-inline-box;
+}*/
+
+div.activeFeatures div.createAccountLink {
+ display: inline-block;
+ width: 282;
+ height: 65px;
+/* background-image: url(../images/old/home/register.png); */
+ margin-right: 20px;
+}
+
+/*body.ext-gecko div.activeFeatures div.createAccountLink {
+ display: -moz-inline-box;
+}*/
+
+div.activeFeatures a.createAccountLink {
+ position: relative;
+ top: -92px;
+ left: 5px;
+}
+
+div.activeFeatures div.createAccountLink a.createAccountLink span.payoff {
+ margin-top: 23px;
+ margin-left: 40px;
+ font-size: 17pt;
+ color: #64626c;
+}
+
+div.activeFeatures div.createAccountLink a.createAccountLink span.link {
+ padding-left: 40px;
+ padding-right: 50px;
+ padding-bottom: 10px;
+ font-size: 12pt;
+}
+
+div.activeFeatures div.createAccountLink:hover {
+/* background-image: url(../images/old/home/register_selected.png);*/
+}
+
+div.activeFeatures div.createAccountLink:hover a.createAccountLink span.payoff {
+ color: #54535a;
+}
+
+div.activeFeatures div.createAccountLink:hover a.createAccountLink span.link {
+ color: white;
+}
+
+/*
+div.activeFeatures div.screenshotLink {
+ background: url(../images/old/home/look.png) no-repeat 0 -3px;
+}
+
+div.activeFeatures div.offlineLink {
+ background: url(../images/old/home/download.png) no-repeat 10px -4px;
+}
+*/
+
+div.createAccountLink canvas {
+ width: 282px;
+ height: 93px;
+}
+div.activeFeatures .keepTogether canvas {
+ width: 46px;
+ height: 46px;
+ vertical-align: bottom;
+}
+
+/* @end */
+
+
+
+/* @end */
+
+/* @group Footer */
+
+div.pageHeaderAndBody {
+ height: 100%;
+}
+
+body > div.pageHeaderAndBody {
+ height: auto; min-height: 100%;
+}
+
+div#pageBody {
+ min-width: 1013px;
+ padding-bottom: 90px;
+}
+
+
+
+div.pageFooter {
+ margin-top: -90px;
+ height: 90px;
+ clear: both;
+}
+
+div.footerWrapper {
+ clear: both;
+ padding-top: 10px;
+}
+div.footerContent {
+ background-color: #eaebe6;
+ padding: 20px;
+ font-size: 8pt;
+}
+
+/*div.pageFooter div.footerContent div.footerStarIcon {*/
+div.pageFooter div.footerContent canvas.footerStarIcon {
+/* background-image: url(../images/old/footer/star.png); */
+ width: 40px;
+ height: 40px;
+ float: left;
+}
+
+div.pageFooter div.footerContent span.copyright {
+ padding-left: 10px;
+ color: #a0a0a0;
+}
+
+div.pageFooter div.footerContent a {
+ padding-left: 50px;
+ display: block;
+ color: #888888;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+div.pageFooter div.footerContent span.applicationVersion {
+ padding: 8px;
+ color: #888888;
+ background-color: #d2d2d2;
+ position: relative;
+ top: -40px;
+ float: right;
+}
+
+
+/* @end */
+
+/* @group Javascript Alert */
+
+div#javaScriptAlert div.mask {
+ position: fixed;
+ top: 0px;
+ left: 0px;
+ right: 0px;
+ bottom: 0px;
+
+ background-color: black;
+ z-index:1001;
+ -moz-opacity: 0.7;
+ opacity:.70;
+ filter: alpha(opacity=70);
+}
+
+div#javaScriptAlert div.header {
+ height: 34px;
+ width: 468;
+ background-image: url(../images/old/alert/header.png);
+}
+
+div#javaScriptAlert div.body {
+ background-image: url(../images/old/alert/body.png);
+ padding: 0px 20px 10px 20px;
+}
+/*
+div#javaScriptAlert div.body div.alert {
+ padding-left: 100px;
+ background: url(../images/old/alert/alert.png) no-repeat;
+}
+*/
+
+/*div#javaScriptAlert div.body img.alert {*/
+div#javaScriptAlert div.body div.alertLogo {
+ float: left;
+ background-image: url(../images/old/alert/alert.png);
+ width: 88px;
+ height: 88px;
+}
+
+div#javaScriptAlert div.body div.alert {
+ padding-left: 100px;
+}
+
+div#javaScriptAlert div.footer {
+ height: 34px;
+ width: 468;
+ background-image: url(../images/old/alert/footer.png);
+}
+
+
+
+div#javaScriptAlert div.message {
+ position: relative;
+ top: -150px;
+ z-index:1002;
+/*
+ left: 100px;
+ right: 100px;
+*/
+ margin-left: auto;
+ margin-right: auto;
+ max-width: 468px;
+}
+
+div#javaScriptAlert div.message h1 {
+ font-size: 16pt;
+ margin: 0px;
+ color: #ff5930;
+}
+
+div#javaScriptAlert div.message p {
+ margin-top: 0px;
+ color: #999999;
+}
+
+div#javaScriptAlert div.message h3 {
+ font-size: 12pt;
+ margin-bottom: 0px;
+ color: #ff5930;
+}
+
+div#javaScriptAlert div.message h5 {
+ margin: 0px;
+ color: #999999;
+}
+
+/* @end */
+
+/* @group Components
+ */
+
+
+/* @group LoginProgress */
+
+div.LoginProgress {
+ position: relative;
+ left: -190px;
+ top: -100px;
+ width: 380px;
+ height: 200px;
+/* background: url(../images/old/loginProgress/background.png); */
+ background-color: #d7d7c0;
+ -webkit-border-radius: 20px;
+ -moz-border-radius: 20px;
+ border-radius: 20px;
+
+ -webkit-box-shadow: 5px 5px 7px rgba(0,0,0,0.6);
+ -moz-box-shadow: 5px 5px 7px rgba(0,0,0,0.6);
+ box-shadow: 5px 5px 7px rgba(0,0,0,0.6);
+}
+
+div.LoginProgress div.header {
+ height: 40px;
+}
+
+div.LoginProgress div.header h3 {
+ font-size: 12pt;
+ font-weight: normal;
+ margin: 0px;
+ color: #777777;
+ padding-top: 13px;
+ padding-left: 18px;
+}
+
+div.LoginProgress div.body {
+ height: 120px;
+ overflow: auto;
+ padding-left: 20px;
+ padding-right: 20px;
+
+ background-color: #f1f1e9;
+/*
+ margin-left: 19px;
+ margin-right: 18px;
+*/
+}
+
+div.LoginProgress div.body div.img {
+ margin: 10px;
+ width: 50px;
+ height: 50px;
+ float: left;
+}
+
+div.LoginProgress div.body div.img.ALERT {
+/* background-image: url(../images/old/simpleMessageBox/Alert.png); */
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ff9955), to(#ff6622), color-stop(1,#333333));
+ background: -moz-linear-gradient(0% 100% 90deg,#ff6622, #ff9955);
+ -webkit-border-radius: 25px;
+ -moz-border-radius: 25px;
+ border-radius: 25px;
+
+}
+
+div.LoginProgress div.body div.img.ALERT canvas {
+ width: 50px;
+ height: 50px;
+/* background-image: url(../images/old/simpleMessageBox/excalmationPoint.png); */
+}
+
+div.LoginProgress div.body div.loadingBar {
+ position: relative;
+ top: 51px;
+ left: 60px;
+}
+
+div.LoginProgress div.body div.errorBox p {
+ color: #787872;
+ padding-top: 20px;
+ padding-left: 80px;
+}
+
+div.LoginProgress div.footer {
+ margin-left: 19px;
+ margin-right: 18px;
+}
+
+div.LoginProgress div.footer a {
+ text-decoration: none;
+ text-align: center;
+ color: #787872;
+ display: block;
+ font-weight: bold;
+ font-size: 11pt;
+ width: 100px;
+ margin-top: 11px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+div.LoginProgress div.footer div.button.default {
+ text-decoration: underline;
+}
+
+div.LoginProgress div.buttonArea {
+ text-align: center;
+}
+
+div.LoginProgress div.button {
+ display: inline-block;
+}
+
+div.LoginProgress div.footer a:hover {
+ color: #515247;
+}
+
+
+
+/* @end */
+
+/* @group SimpleMessagePanel */
+
+div.SimpleMessagePanel {
+ position: relative;
+ left: -225px;
+ top: -70px;
+ width: 450px;
+ height: 140px;
+/*
+ background: url(../images/old/loginProgress/background.png);
+*/
+}
+
+div.SimpleMessagePanel div.header {
+ height: 17px;
+ background: url(../images/old/simpleMessageBox/background_header.png) no-repeat;
+}
+
+div.SimpleMessagePanel div.body {
+/*
+ height: 120px;
+ overflow: auto;
+ margin-left: 19px;
+ margin-right: 18px;
+*/
+ background: url(../images/old/simpleMessageBox/background_body.png) repeat-y;
+ padding-left: 25px;
+ padding-right: 25px;
+ padding-top: 10px;
+}
+
+div.SimpleMessagePanel div.body h3 {
+ font-size: 14pt;
+ font-weight: normal;
+ margin: 0px;
+ padding-top: 4px;
+ color: #787872;
+}
+
+div.SimpleMessagePanel div.body div.img {
+ width: 66px;
+ height: 60px;
+ float: left;
+}
+
+div.SimpleMessagePanel div.body p {
+ margin: 0;
+ font-size: 10pt;
+ font-weight: normal;
+ color: #787872;
+ padding-top: 10px;
+ padding-bottom: 5px;
+ line-height: 1.3;
+}
+
+div.SimpleMessagePanel div.body div.img.ALERT {
+ background: url(../images/old/simpleMessageBox/Alert.png) no-repeat;
+}
+
+div.SimpleMessagePanel div.body div.img.INFO {
+ background: url(../images/old/simpleMessageBox/Info.png) no-repeat;
+}
+
+div.SimpleMessagePanel div.body div.buttonArea {
+ height: 40px;
+ clear: both;
+}
+
+div.SimpleMessagePanel div.body div.buttonArea > div {
+ float: right;
+ margin-left: 15px;
+ margin-top: 10px;
+}
+
+div.SimpleMessagePanel div.footer {
+ height: 25px;
+ background: url(../images/old/simpleMessageBox/background_footer.png) no-repeat;
+}
+
+div.SimpleMessagePanel div.passphrase {
+ padding-left: 65px;
+}
+
+div.SimpleMessagePanel div.passphrase input {
+ width: 250px;
+ font-size: 14pt;
+ border: 1px solid #bb4924;
+ color: #333366;
+ background-color: white;
+ padding: 2px 5px;
+ height: 28px;
+}
+
+div.SimpleMessagePanel div.progressBarWrapper {
+ margin-left: 80px;
+}
+
+/* @end */
+
+/* @group Button */
+
+div.button_wrapper {
+ height: 32px;
+ background: url(../images/old/button/default_left.png) no-repeat;
+ cursor: pointer;
+}
+
+div.button_wrapper.hover {
+ background: url(../images/old/button/hover_left.png) no-repeat;
+}
+
+div.button_wrapper.clicked {
+ background: url(../images/old/button/clicked_left.png) no-repeat;
+}
+
+div.button_bodyWrapper {
+ height: 32px;
+ margin-left: 6px;
+ padding-right: 6px;
+ background: url(../images/old/button/default_main.png) repeat-x right 0;
+}
+
+div.button_wrapper.hover div.button_bodyWrapper {
+ background: url(../images/old/button/hover_main.png) repeat-x right 0;
+}
+
+div.button_wrapper.clicked div.button_bodyWrapper {
+ background: url(../images/old/button/clicked_main.png) repeat-x right 0;
+}
+
+div.button_body {
+ text-align: center;
+ min-width: 60px;
+ padding: 0px 7px;
+ padding-top: 8px;
+}
+
+div.button_body span {
+ font-size: 11pt;
+ color: white;
+}
+
+div.button_wrapper.default div.button_body span {
+ font-weight: bold;
+}
+
+/*
+div.button_footer {
+ margin: 0px;
+ height: 31px;
+ width: 6px;
+ background: green url(../images/old/button/default_right.png) no-repeat;
+}
+*/
+/* @end */
+
+/* @group Password enthropy */
+
+input.entropyLevelIndicator {
+ background: url(../images/old/passwordField/background.png) no-repeat 0 26px;
+}
+
+div.passwordEntropyWrapper {
+ padding: 0px;
+ border: 1px solid #bb4924;
+ border-top: 0px;
+ margin-bottom: 4px;
+ background-color: white;
+ margin-right: 3px;
+ margin-top: -2;
+}
+
+div.passwordEntropy {
+ height: 4px;
+ font-size: 1pt;
+ background: url(../images/old/entropyBackground.gif) repeat-x 0 0;
+ line-height: 3px;
+}
+
+
+
+/* @end */
+
+
+
+/* @end */
+
+/* @group Main page */
+
+/* @group User Info Box */
+
+div.userInfoBox {
+ position: absolute;
+ width: 160px;
+ height: 120px;
+
+ top: 100px;
+ left: 15px;
+/* background-image: url(../images/old/main/userInfoBackground.png); */
+
+ background-color: #ff9955;
+ background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ff9a56), to(#ff6723), color-stop(1,#333333));
+ background: -moz-linear-gradient(0% 100% 90deg,#ff6723, #ff9a56);
+
+ -webkit-border-radius: 10px;
+ -moz-border-radius: 10px;
+ border-radius: 10px;
+
+ -webkit-box-shadow: 2px 2px 9px rgba(0,0,0,0.6);
+ -moz-box-shadow: 2px 2px 9px rgba(0,0,0,0.6);
+ box-shadow: 2px 2px 9px rgba(0,0,0,0.6);
+
+ color: white;
+}
+
+div.userInfoBox div.body {
+ padding: 0px 12px;
+}
+
+div.userInfoBox div.header {
+ height: 30px;
+}
+
+div.userInfoBox div.header h1 {
+ font-size: 8pt;
+ font-weight: normal;
+ margin: 0px;
+ padding-top: 12px;
+ padding-left: 12px;
+}
+
+div.userInfoBox div.header a.lockButton {
+ position: absolute;
+ top: 8px;
+ right: 12px;
+ display: block;
+ width: 15px;
+ height: 20px;
+ text-decoration: none;
+ background: url(../images/old/lock/unlocked.png) no-repeat -5px -2px;
+}
+
+div.userInfoBox div.header a.lockButton:hover {
+ background: url(../images/old/lock/unlocked_hover.png) no-repeat -5px -2px;
+}
+
+div.userInfoBox.locked {
+ z-index:19001;
+}
+
+div.modalDialogMask.userInfoBoxMask {
+ -moz-opacity: 0.0;
+ opacity: .0;
+ filter: alpha(opacity=0);
+ z-index:19000;
+}
+
+div.userInfoBox.locked div.header a.lockButton {
+ background: url(../images/old/lock/locked.png) no-repeat -5px -2px;
+}
+
+div.userInfoBox.locked div.header a.lockButton:hover {
+ background: url(../images/old/lock/locked_hover.png) no-repeat -5px -2px;
+}
+
+div.userInfoBox div.body h3 {
+ font-size: 11pt;
+ font-weight: bold;
+ margin: 0px;
+}
+
+div.userInfoBox div.body ul {
+ /* ##### */
+ list-style-image: url(../images/old/main/userInfoBullet.png);
+ font-size: 8pt;
+ padding: 0px;
+ margin: 4px 0px;
+ list-style-position: inside;
+ text-shadow: #000000 0 0 0;
+}
+
+div.userInfoBox div.body ul li span.number {
+ font-weight: bold;
+ padding-right: 3px;
+}
+
+div.userInfoBox div.body a {
+ display: block;
+ margin-top: 8
+ px;
+ border-top: 1px solid white;
+ padding-top: 6px;
+ font-size: 10pt;
+ font-weight: bold;
+ color: #d15a22;
+ text-decoration: none;
+ border-color: #fe9a5f;
+}
+
+div.userInfoBox div.body a:hover {
+ color: #8c3b15;
+}
+
+div.userInfoBox.locked div.body a {
+ display: none;
+}
+
+/* @end */
+
+
+/* @group Message Box */
+
+div.messageBox {
+ position: absolute;
+ width: 409px;
+ height: 29px;
+ top: 23px;
+ left: 204px;
+ background: url(../images/old/main/messageBoxBackground.png);
+}
+
+div.messageBox h3 {
+ display: inline-block;
+ color: #342f6b;
+ font-weight: bold;
+ margin: 7px 2px 0px 12px;
+ font-size: 10pt;
+
+}
+
+body.ext-gecko div.messageBox h3 {
+ display: -moz-inline-box;
+}
+
+div.messageBox h1 {
+ color: #342f6b;
+ display: inline;
+ font-weight: normal;
+ margin: 0px 1px;
+ font-size: 9pt;
+}
+
+div.messageBox a {
+ display: block;
+ width: 20px;
+ height: 20px;
+ float: right;
+ position: absolute;
+ right: 5px;
+ top: 4px;
+ background-image: url(../images/old/main/messageBoxCloseButton.png);
+}
+
+div.messageBox a:hover {
+ background-image: url(../images/old/main/messageBoxCloseButtonActive.png);
+}
+
+/* @end */
+
+/* @group Side panels */
+
+div.sidePanels {
+/*
+ position: relative;
+ top: 110px;
+*/
+ float: left;
+ margin-top: 106px;
+ margin-left: 20px;
+ width: 160px;
+
+}
+
+/* @group Tab Side Panel */
+
+div.tabSidePanel {
+ margin-right: -10px;
+/*
+ position: absolute;
+ width: 250px;
+ height: 250px;
+ top: 250px;
+ left: 10px;
+*/
+}
+
+div.tabSidePanel ul {
+ margin: 0px;
+ padding-left: 0px;
+ list-style-type: none;
+ color: #f78b46;
+}
+
+/* @group Main tabs */
+
+div.tabSidePanel ul.mainTabs {
+ margin: 0px;
+}
+
+div.tabSidePanel ul.mainTabs li {
+/* margin-bottom: 6px;*/
+}
+
+div.tabSidePanel ul.mainTabs li a {
+ display: block;
+ line-height: 30px;
+ height: 43px;
+ padding-left: 40px;
+ color: #ff6621;
+ margin: 0px;
+ font-weight: normal;
+ font-size: 13pt;
+ text-decoration: none;
+}
+
+div.tabSidePanel ul.mainTabs li div.selectionHighlighter {
+ display: none;
+}
+
+div.tabSidePanel ul.mainTabs li.selected div.selectionHighlighter {
+ display: block;
+ position: absolute;
+ left: 154px;
+ margin-top: -43px;
+}
+
+/*
+div.tabSidePanel ul.mainTabs li.selected div.selectionHighlighter div.selectionHighlighterIcon {
+ background-image: url(../images/main/tabs/selectionHighligher.png);
+ width: 50px;
+ height: 34px;
+ float: left;
+ z-index: 35000;
+ border: 1px solid red;
+}
+*/
+
+div.tabSidePanel ul.mainTabs li.selected div.selectionHighlighter a.add {
+ font-size: 14pt;
+ font-weight: bold;
+ position: relative;
+ top: -34px;
+ right: 16px;
+ background: none;
+ color: #c0531b;
+ padding-left: 15px;
+}
+
+div.tabSidePanel ul.mainTabs li.selected div.selectionHighlighter a.add:hover {
+ color: white;
+}
+
+div.tabSidePanel ul.mainTabs li.selected div.selectionHighlighter a.add span {
+ font-size: 8pt;
+ vertical-align: middle;
+}
+
+div.tabSidePanel ul.mainTabs li.selected div.selectionHighlighter a.add h3 {
+ display: inline;
+ padding-left: 5px;
+}
+
+div.tabSidePanel ul.mainTabs li.cards.selected a {
+ margin-left: -10px;
+ padding-left: 50px;
+ color: white;
+ background: url(../images/old/main/tabs/cardsBackground.png) -9px -14px;
+}
+
+div.tabSidePanel ul.mainTabs li.cards.selected a:hover {
+ background: url(../images/old/main/tabs/cardsBackground.png) -9px -14px;
+}
+
+div.tabSidePanel ul.mainTabs li.cards a {
+ background: url(../images/old/main/tabs/cardsBackground.png) -19px -63px;
+}
+
+div.tabSidePanel ul.mainTabs li.cards a:hover {
+ background: url(../images/old/main/tabs/cardsBackground.png) -19px -110px;
+}
+
+
+
+div.tabSidePanel ul.mainTabs li.directLogins.selected a {
+ margin-left: -10px;
+ padding-left: 50px;
+ color: white;
+/* background: url(../images/old/main/tabs/directLoginBackground.png) 0 -1px; */
+ background: url(../images/old/main/tabs/directLoginBackground.png) -9px -14px;
+}
+
+div.tabSidePanel ul.mainTabs li.directLogins.selected a:hover {
+ color: white;
+/* background: url(../images/old/main/tabs/directLoginBackground.png) 0 -1px; */
+ background: url(../images/old/main/tabs/directLoginBackground.png) -9px -14px;
+}
+
+div.tabSidePanel ul.mainTabs li.directLogins a {
+/* background: url(../images/old/main/tabs/directLoginBackground.png) 0 -34px; */
+ background: url(../images/old/main/tabs/directLoginBackground.png) -19px -63px;
+}
+
+div.tabSidePanel ul.mainTabs li.directLogins a:hover {
+/* background: url(../images/old/main/tabs/directLoginBackground.png) 0 -67px; */
+ background: url(../images/old/main/tabs/directLoginBackground.png) -19px -110px;
+}
+
+
+
+
+
+/* @end */
+
+/* @group Other tabs */
+
+div.tabSidePanel ul.otherTabs {
+ margin: 10px 0px;
+}
+
+div.tabSidePanel ul.otherTabs li {
+ margin-top: -4px;
+}
+
+div.tabSidePanel ul.otherTabs li div.selectionHighlighter {
+ display: none;
+}
+
+div.tabSidePanel ul.otherTabs li.selected div.selectionHighlighter {
+ display: block;
+ position: absolute;
+ left: 154px;
+ margin-top: -42px;
+}
+
+div.tabSidePanel ul.otherTabs a {
+ display: block;
+ line-height: 36px;
+ height: 43px;
+ padding-left: 40px;
+ color: #ff6621;
+ text-decoration: none;
+/* background: url(../images/old/main/tabs/itemsBackground.png) -10px -49px; */
+}
+
+div.tabSidePanel ul.otherTabs li.selected a {
+/* background: url(../images/old/main/tabs/itemsBackground.png) 0 -1px; */
+/* background: url(../images/old/main/tabs/itemsBackground.png) 0 -67px; */
+ margin-left: -10px;
+ padding-left: 50px;
+ background: url(../images/old/main/tabs/itemsBackground.png) 1px -96px;
+ color: white;
+}
+
+div.tabSidePanel ul.otherTabs a:hover {
+/* background: url(../images/old/main/tabs/itemsBackground.png) 0 -34px; */
+ background: url(../images/old/main/tabs/itemsBackground.png) -10px -49px;
+}
+
+/* @end */
+
+/* @end */
+
+/* @group Tag Side Panel */
+
+div.tagSidePanel {
+/*
+ position: relative;
+ width: 250px;
+ min-height: 100px;
+ left: 10px;
+*/
+
+ margin-right: -8px;
+}
+
+div.tagSidePanel div.header {
+ height: 50px;
+ background-image: url(../images/old/main/tabs/tagsBackground.png);
+}
+
+div.tagSidePanel div.header h1 {
+ padding-left: 52px;
+ padding-top: 14px;
+ font-size: 14pt;
+ font-weight: normal;
+ color: #888888;
+}
+
+div.tagSidePanel div.body {
+ background: url(../images/old/main/tabs/tagsBackground.png) -255px;
+}
+
+div.tagSidePanel div.footer {
+ height: 10px;
+ background: url(../images/old/main/tabs/tagsBackground.png) -510px -40px;
+}
+
+div.tagSidePanel ul.tags {
+ margin: 0px;
+ list-style-type: none;
+ padding: 0px;
+}
+
+div.tagSidePanel ul.tags li a {
+ display: block;
+ font-size: 9pt;
+ text-decoration: none;
+ color: #ff6621;
+ padding: 0px 4px 0px 15px;
+ line-height: 20px;
+}
+
+div.tagSidePanel ul.tags li a:hover {
+ background-color: #dddddd;
+}
+
+div.tagSidePanel ul.tags li.selected a:hover {
+}
+
+div.tagSidePanel ul.tags li span.tagCardinality {
+ float: right;
+ font-size: 8pt;
+ color: #999999;
+ margin-right: 15px;
+ margin-top: -17px;
+}
+
+div.tagSidePanel ul.tags li.selected a {
+ background-color: #d4d5cf;
+}
+
+div.tagSidePanel ul.tags li.selected a:hover {
+ background-color: #d4d5cf;
+}
+
+div.tagSidePanel ul.tags li.selected a {
+ font-weight: bold;
+}
+
+/* @end */
+
+
+/* @group Group Side Panel */
+
+div.groupSidePanel {
+ margin-right: -10px;
+/*
+ position: relative;
+ width: 250px;
+ min-height: 100px;
+ left: 10px;
+*/
+}
+
+div.groupSidePanel div.header {
+ height: 50px;
+ background-image: url(../images/old/main/tabs/groupsBackground.png);
+}
+
+div.groupSidePanel div.header h1 {
+ padding-left: 52px;
+ padding-top: 14px;
+ font-size: 14pt;
+ font-weight: normal;
+ color: white;
+}
+
+div.groupSidePanel div.header a {
+ float: right;
+ margin-top: -30px;
+ margin-right: 20px;
+ text-decoration: none;
+ color: #666666;
+ font-size: 9pt;
+ line-height: 18px;
+}
+
+div.groupSidePanel div.header a:hover {
+ color: #444444;
+}
+
+div.groupSidePanel div.body {
+ background: url(../images/old/main/tabs/groupsBackground.png) -255px;
+}
+
+div.groupSidePanel div.footer {
+ height: 10px;
+ background: url(../images/old/main/tabs/groupsBackground.png) -510px -39px;
+}
+
+
+
+div.groupSidePanel ul.groups {
+ margin: 0px;
+ list-style-type: none;
+ padding: 0px;
+}
+
+div.groupSidePanel ul.groups li a {
+ display: block;
+ font-size: 9pt;
+ text-decoration: none;
+ color: white;
+ padding: 0px 4px 0px 15px;
+ line-height: 20px;
+}
+
+div.groupSidePanel ul.groups li a:hover {
+ background-color: #aaaaaa;
+}
+
+div.groupSidePanel ul.groups li.selected a:hover {
+}
+
+div.groupSidePanel ul.groups li span.groupCardinality {
+ float: right;
+ font-size: 8pt;
+ color: #dddddd;
+ margin-right: 15px;
+ margin-top: -17px;
+}
+
+div.groupSidePanel ul.groups li.selected a {
+ background-color: #bbbbbb;
+}
+
+div.groupSidePanel ul.groups li.selected a:hover {
+ background-color: #bbbbbb;
+}
+
+div.groupSidePanel ul.groups li.selected a {
+ font-weight: bold;
+}
+
+/* @end */
+
+
+
+/* @end */
+
+/* @group MainPanels */
+
+div.mainPanels {
+ float: left;
+ width: 833px;
+ margin-top: -38px;
+/*
+ position: relative;
+ width: 100%;
+ min-height: 600px;
+ top: -40px;
+ left: 250px;
+*/
+}
+
+div.mainFooter {
+ clear: both;
+}
+
+/* @end */
+
+/* @group Grids */
+
+/* @group grid Component */
+
+/* @group delete */
+
+div.gridComponent table.rows tbody tr td.delete {
+}
+
+/*div.body div.rows table.rows tbody tr td.delete */
+div.delete,
+div.new {
+ padding-left: 5px;
+ height: 19px;
+}
+
+div.new span,
+div.delete span {
+ margin: 0px;
+ padding: 0px;
+ border: 0px;
+ display: inline-block;
+ height: 19px;
+ padding-right: 6px;
+}
+
+div.new span a,
+div.delete span a {
+ white-space: nowrap;
+}
+
+div.delete:hover {
+ background: url(../images/old/delete_background_left.png) no-repeat 0;
+}
+div.delete:hover span {
+ background: url(../images/old/delete_background.png) no-repeat right 0;
+}
+
+div.new:hover {
+ background: url(../images/old/new_background_left.png) no-repeat 0;
+}
+div.new:hover span {
+ background: url(../images/old/new_background.png) no-repeat right 0;
+}
+
+/*
+tr.selected div.delete {
+ background: url(../images/old/delete_background_left.png) no-repeat 0;
+}
+tr.selected div.delete span {
+ background: url(../images/old/delete_background.png) no-repeat right 0;
+}
+*/
+div.body div.rows table.rows tbody tr td.delete div.delete span a {
+ visibility: hidden;
+ font-size: 8pt;
+ vertical-align: -13px;
+ color: black;
+}
+
+div.body div.rows table.rows tbody tr.selected td.delete div.delete span a {
+ visibility: visible;
+}
+
+div.body div.rows table.rows tbody tr:hover td.delete div.delete span a {
+ visibility: visible;
+}
+
+div.body div.rows table.rows tbody tr:hover td.delete div.delete:hover span a {
+ color: white;
+}
+/*
+div.body div.rows table.rows tbody tr.selected td.delete div.delete span a {
+ color: white;
+}
+*/
+/* @end */
+
+/* @group header */
+
+div.gridComponent table.rows thead tr th {
+ text-align: left;
+ height: 30px;
+ vertical-align: bottom;
+}
+
+div.gridComponent table.rows thead tr th.sortable span {
+ cursor: pointer;
+}
+
+div.gridComponent table.rows thead tr th.sortable span a {
+ margin-left: 5px;
+ padding-left: 10px;
+}
+
+div.gridComponent table.rows thead tr th.directLoginTH {
+ width: 420px;
+}
+
+div.gridComponent table.rows thead tr th.latestUpdateTH {
+ width: 100px;
+}
+
+div.gridComponent table.rows thead tr th.commandsTH {
+ width: 150px;
+}
+
+div.gridComponent table.rows thead a {
+ text-decoration: none;
+}
+
+div.gridComponent table.rows thead span {
+ font-weight: normal;
+ font-size: 9pt;
+ line-height: 20px;
+}
+
+div.gridComponent div.header div.headerSlot {
+ float: right;
+}
+
+/* @end */
+
+div.mainPanels div.gridComponent div.body table.rows td.favicon {
+ padding-left: 25px;
+}
+
+div.mainPanels div.gridComponent div.body table.rows td.favicon img {
+ width: 16px;
+ height: 16px;
+ border: 0px;
+}
+
+
+
+/* @end */
+
+/* @group Card Grid */
+
+/* @group DirectLogin links */
+
+div.gridComponent th.directLoginTH span {
+ margin-left: 7px;
+}
+
+td.card_directLogins div {
+ display: inline-table;
+}
+
+td.card_directLogins span {
+ display: inline-block;
+}
+/*
+td.card_directLogins a {
+ display: inline-table;
+ height: 19px;
+
+ padding-right: 7px;
+}
+
+td.card_directLogins a:hover {
+ background: url(../images/old/directLink_background.png) right 0;
+}
+*/
+
+div.card_directLogin {
+ display: inline-block;
+ height: 19px;
+ padding-left: 7px;
+}
+
+div.card_directLogin_ellipses span {
+ padding-bottom: 2px;
+}
+
+div.card_directLogin div.card_directLogin_body {
+ display: inline-block;
+ height: 19px;
+ padding-right: 8px;
+ background-position: left;
+}
+
+div.card_directLogin div.card_directLogin_body a{
+ vertical-align: -14px;
+}
+
+/*div.card_directLogin:hover {*/
+div.card_directLogin:hover {
+ background: url(../images/old/directLink_background_left.png) no-repeat 0 0;
+}
+
+/*div.card_directLogin:hover div {*/
+div.card_directLogin:hover div.card_directLogin_body {
+ background: url(../images/old/directLink_background.png) right 0;
+}
+
+/* @group DirectLogin Popup */
+
+div.DirectLoginListPopup {
+ position: absolute;
+ width: 184px;
+}
+
+div.DirectLoginListPopup div.DirectLoginListPopup_body {
+ background-image: url(../images/old/directLogins_background.png);
+ padding-top: 8px;
+}
+
+div.DirectLoginListPopup div.DirectLoginListPopup_footer {
+ height: 8px;
+ background-image: url(../images/old/directLogins_background_bottom.png);
+}
+
+div.DirectLoginListPopup div.DirectLoginListPopup_body ul {
+ margin: 0px;
+ padding-left: 13px;
+ list-style: none;
+}
+
+div.DirectLoginListPopup div.DirectLoginListPopup_body ul li {
+ padding-top: 4px;
+ height: 20px;
+ padding-right: 10px;
+ white-space: nowrap;
+}
+
+div.DirectLoginListPopup div.DirectLoginListPopup_body ul li div {
+ padding-right: 10px;
+ overflow: hidden;
+}
+div.DirectLoginListPopup div.DirectLoginListPopup_body ul li img.favicon {
+ padding-left: 9px;
+ padding-right: 5px;
+}
+
+div.DirectLoginListPopup div.DirectLoginListPopup_body ul li a {
+ text-decoration: none;
+ color: white;
+ font-weight: normal;
+ font-size: 10pt;
+ vertical-align: 3px;
+ white-space: nowrap;
+ padding-right:8px;
+}
+
+div.DirectLoginListPopup div.DirectLoginListPopup_body ul li:hover {
+/* background-color: #a5a696; */
+/* background-color: #7b7d70; */
+ background-color: rgba(123,125,112,0.5);
+}
+
+div.DirectLoginListPopup div.DirectLoginListPopup_body ul li:hover a {
+ background: url(../images/old/directLink_no_background.png) right;
+}
+
+/* @end */
+
+
+/* @end */
+
+div.mainPanels div.gridComponent div.header {
+/*
+ height: 90px;
+ background: url(../images/old/main/blocks/cardGridBackground.png) no-repeat;
+*/
+ background: url(../images/old/main/blocks/cardGridBackground.png) no-repeat;
+ padding-left: 40px;
+ padding-right: 40px;
+ padding-top: 20px;
+ padding-bottom: 10px;
+}
+
+div.mainPanels div.gridComponent div.header form.search {
+ height: 32px;
+ margin: 0px;
+}
+
+div.mainPanels div.gridComponent div.header form.search div.clearSearchButton {
+ position: absolute;
+ margin-left: 192px;
+ width: 22px;
+ height: 22px;
+ margin-top: 6px;
+ background: url(../images/old/filter/clearFilter_notSelected.png) no-repeat;
+}
+
+div.mainPanels div.gridComponent div.header form.search div.clearSearchButton:hover {
+ background: url(../images/old/filter/clearFilter_selected.png) no-repeat;
+ cursor: pointer;
+}
+
+div.mainPanels div.gridComponent div.header form.search div.search {
+ display: block;
+ float: left;
+ width: 217px;
+}
+
+div.mainPanels div.gridComponent div.header form.search input.search {
+ border: 1px solid #76786a;
+ color: #666666;
+ font-size: 12pt;
+ width: 100%;
+ padding: 4px;
+ padding-left: 24px;
+ padding-right: 26px;
+ background: #e8ecde url(../images/old/main/grid/search.png) no-repeat 2px 4px;
+}
+
+div.mainPanels div.gridComponent div.header form.search input.search.disabled {
+ disabled:disabled;
+}
+
+div.mainPanels div.gridComponent div.header form.search input.search.running {
+ background: #e8ecde url(../images/old/main/grid/running_search.gif) no-repeat 4px 5px;
+}
+
+div.mainPanels div.gridComponent div.body {
+ clear: both;
+ background: url(../images/old/main/blocks/cardGridBackground.png) repeat-y -836px;
+}
+
+div.mainPanels div.gridComponent div.footer {
+ background: url(../images/old/main/blocks/cardGridBackground.png) 834px -28px;
+ height: 35px;
+}
+
+div.mainPanels div.gridComponent div.body h1 {
+ margin: 0px;
+}
+
+div.mainPanels div.gridComponent div.body div.rows {
+ margin-left: 9px;
+ margin-right: 6px;
+ min-height: 582px;
+ background: url(../images/old/main/blocks/cardGridStripes.png) 0 7px;
+}
+
+div.mainPanels div.gridComponent.noRows div.body table.rows thead,
+div.mainPanels div.gridComponent.empty div.body table.rows thead {
+ visibility: hidden;
+}
+
+div.mainPanels div.gridComponent.empty div.body div.rows {
+ background: #eaebe6 url(../images/old/lock/background_star.png) no-repeat center center;
+}
+
+div.mainPanels div.gridComponent.noRows div.body div.rows {
+ background: #eaebe6;
+}
+
+div.mainPanels div.gridComponent div.body table.rows {
+ display: block;
+ width: 100%;
+}
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr.odd.selected {
+ background-color: #a5a696;
+}
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr.even.selected {
+ background-color: #a5a696;
+}
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr.selected td a {
+ color: #f3f4eb;
+}
+
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr.odd {
+ background-color: #d4d5cf;
+}
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr.even {
+ background-color: #eaebe6;
+}
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr.odd:hover {
+ background-color: #a5a696;
+}
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr.even:hover {
+ background-color: #a5a696;
+}
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr td {
+ height: 23px;
+ max-height: 23px;
+/*
+ white-space: nowrap;
+ overflow: hidden;
+*/
+}
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr td span {
+ color: #828479;
+ font-size: 10pt;
+}
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr td a {
+ color: #828479;
+ font-size: 10pt;
+ text-decoration: none;
+}
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr:hover td span {
+ color: #f3f4eb;
+}
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr.selected td span {
+ color: #f3f4eb;
+}
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr:hover td a {
+ color: #f3f4eb;
+}
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr td.title a {
+ font-weight: bold;
+}
+
+div.mainPanels div.gridComponent div.body table.rows tbody tr td img.favicon {
+ float: right;
+ padding-right: 6px;
+}
+
+/* @group header */
+
+div.gridComponent table.rows thead img {
+ padding-left: 10px;
+ vertical-align: middle;
+}
+
+div.gridComponent table.rows thead tr th {
+ background-color: #eaebe6;
+ border-bottom: 1px solid #b3b4af;
+}
+
+div.gridComponent table.rows thead span {
+ color: #8c8f7e;
+}
+
+div.gridComponent table.rows thead tr th.unsorted span.sortable a {
+ background-image: url(../images/old/main/grid/unsorted.png);
+}
+
+div.gridComponent table.rows thead tr th.descending span.sortable a {
+ background-image: url(../images/old/main/grid/descending.png);
+}
+
+div.gridComponent table.rows thead tr th.ascending span.sortable a {
+ background-image: url(../images/old/main/grid/ascending.png);
+}
+
+div.gridComponent table.rows thead tr th.faviconTH {
+ width: 53px;
+}
+
+div.gridComponent table.rows thead tr th.titleTH {
+ width: 200px;
+ max-width: 200px;
+}
+
+div.gridComponent table.rows thead tr th.deleteTH {
+ width: 50px;
+}
+
+
+/* @end */
+
+
+/* @end */
+
+/* @group Direct login Grid */
+/*
+div.mainPanels div.directLoginGrid div.header {
+/*
+ height: 90px;
+ background: url(../images/old/main/blocks/cardGridBackground.png) no-repeat;
+* /
+}
+
+div.mainPanels div.directLoginGrid div.header form.search {
+ background: url(../images/old/main/blocks/directLoginGridBackground.png) no-repeat;
+ padding-left: 40px;
+ padding-top: 20px;
+ padding-bottom: 10px;
+ margin: 0px;
+}
+
+div.mainPanels div.directLoginGrid div.header form.search input.search {
+ border: 1px solid #76786a;
+ color: #666666;
+ font-size: 12pt;
+ padding: 4px;
+ background-color: #e8ecde;
+}
+
+div.mainPanels div.directLoginGrid div.header form.search input.searchButton {
+ background-color: #858877;
+ border: 0px;
+ color: white;
+ font-size: 10pt;
+}
+
+div.mainPanels div.directLoginGrid div.body {
+ background: url(../images/old/main/blocks/directLoginGridBackground.png) repeat-y -836px;
+}
+
+div.mainPanels div.directLoginGrid div.footer {
+ background: url(../images/old/main/blocks/directLoginGridBackground.png) 834px -28px;
+ height: 35px;
+}
+
+div.mainPanels div.directLoginGrid div.body h1 {
+ margin: 0px;
+}
+
+div.mainPanels div.directLoginGrid div.body div.rows {
+ margin-left: 9px;
+ margin-right: 6px;
+ min-height: 582px;
+ background: url(../images/old/main/blocks/directLoginGridStripes.png) 0 7px;
+}
+
+div.mainPanels div.directLoginGrid div.body table.rows {
+ display: block;
+ width: 100%;
+}
+
+div.mainPanels div.directLoginGrid div.body table.rows img {
+ border: 0px;
+}
+
+div.mainPanels div.directLoginGrid div.body table.rows tbody tr.even {
+ background-color: #787666;
+}
+
+div.mainPanels div.directLoginGrid div.body table.rows tbody tr.odd {
+ background-color: #646351;
+}
+
+div.mainPanels div.directLoginGrid div.body table.rows tbody tr.odd:hover {
+ background-color: #d1d4c6;
+}
+
+div.mainPanels div.directLoginGrid div.body table.rows tbody tr.even:hover {
+ background-color: #d1d4c6;
+}
+
+div.mainPanels div.directLoginGrid div.body table.rows tbody tr td {
+ height: 23px;
+ color: #e1e0d6;
+ font-size: 10pt;
+}
+
+div.mainPanels div.directLoginGrid div.body table.rows tbody tr:hover td {
+ color: #777867;
+}
+
+div.mainPanels div.directLoginGrid div.body table.rows tbody tr td.title {
+ font-weight: bold;
+}
+
+div.directLoginGrid div.body table.rows tbody tr a {
+ color: #e1e0d6;
+ text-decoration: none;
+}
+
+div.directLoginGrid div.body table.rows tbody tr:hover a {
+ color: #777867;
+}
+*/
+
+/* @group DirectLogin links */
+/*
+td.card_directLogins div {
+ display: inline-table;
+}
+
+td.card_directLogins span {
+ display: inline-table;
+}
+*/
+div.directLogin_directLogin {
+ display: inline-block;
+ height: 19px;
+ padding-left: 7px;
+}
+
+div.directLogin_directLogin div.directLogin_directLogin_body {
+ display: inline-block;
+ height: 19px;
+ padding-right: 8px;
+ background-position: left;
+}
+
+div.directLogin_directLogin div.directLogin_directLogin_body a {
+ vertical-align: -14px;
+}
+
+div.directLogin_directLogin:hover {
+ background: url(../images/old/directLink_background_left.png) no-repeat 0 0;
+}
+
+div.directLogin_directLogin:hover div.directLogin_directLogin_body {
+ background: url(../images/old/directLink_background.png) right 0;
+}
+
+table.rows tbody tr td div.directLogin_directLogin:hover div.directLogin_directLogin_body a {
+ color: #f3f4eb;
+}
+
+
+
+/* @end */
+
+
+
+/* @group header */
+
+div.directLoginGrid table.rows thead span {
+ color: #e1e0d6;
+}
+
+div.directLoginGrid table.rows thead tr th {
+ background-color: #787762;
+ border-bottom: 1px solid #999883;
+}
+
+div.directLoginGrid table.rows thead tr th.faviconTH {
+ min-width: 53px;
+ width: 53px;
+}
+
+div.directLoginGrid table.rows thead tr th.titleTH {
+ min-width: 250px;
+ width: 250px;
+}
+
+div.directLoginGrid table.rows thead tr th.titleTH span {
+ margin-left: 7px;
+}
+
+div.directLoginGrid table.rows thead tr th.strengthTH {
+ width: 100px;
+}
+
+div.directLoginGrid table.rows thead tr th.cardTitleTH {
+ width: 400px;
+}
+
+div.directLoginGrid table.rows thead tr th.bookmarkableLinkTH {
+ width: 64px;
+}
+
+div.directLoginGrid table.rows thead tr th.deleteTH {
+ width: 50px;
+}
+
+div.directLoginGrid table.rows thead tr th.latestAccessTH {
+ width: 100px;
+}
+
+div.directLoginGrid table.rows thead tr th.commandsTH {
+ width: 100px;
+}
+/*
+div.directLoginGrid table.rows thead a {
+ font-weight: normal;
+ text-decoration: none;
+ color: #e9e9df;
+ font-size: 9pt;
+ line-height: 20px;
+}
+*/
+div.directLoginGrid table.rows thead img {
+ padding-left: 10px;
+ vertical-align: middle;
+}
+
+div.directLoginGrid table.rows thead tr th.unsorted span.sortable a {
+ background: url(../images/old/main/grid/directLogins/unsorted.png) no-repeat;
+}
+
+div.directLoginGrid table.rows thead tr th.descending span.sortable a {
+ background: url(../images/old/main/grid/directLogins/descending.png) no-repeat;
+}
+
+div.directLoginGrid table.rows thead tr th.ascending span.sortable a {
+ background: url(../images/old/main/grid/directLogins/ascending.png) no-repeat;
+}
+
+/* @end */
+
+
+
+/* @end */
+
+
+
+/* @end */
+
+
+/* @end */
+
+/* @group other Panels */
+
+/* @group common styles */
+div.subPanelTabs {
+}
+
+div.subPanelTabs ul {
+ margin: 0px;
+ margin-right: 7px;
+ padding: 0px;
+}
+
+div.subPanelTabs ul li.first {
+}
+
+div.subPanelTabs ul li {
+ display: inline-block;
+ vertical-align: middle;
+/* width: 130px; */
+ height: 50px;
+/* border-right: 1px solid #a5a79c;
+ border-bottom: 1px solid #a5a79c;*/
+ border-right: 1px solid #eef0e3;
+ border-bottom: 1px solid #d5d5bc;
+}
+
+div.subPanelTabs ul li.first:hover {
+/* background: url(../images/old/main/blocks/otherPanelBackground_selected.png) no-repeat -9px -5px; */
+}
+
+div.subPanelTabs ul li:hover {
+/* background: url(../images/old/main/blocks/otherPanelBackground_selected.png) no-repeat -45px -5px; */
+ border-right: 1px solid #d5d5bc;
+ background-color: #eef0e3;
+}
+
+div.subPanelTabs ul li a {
+ color: #787872;
+ text-decoration: none;
+ display: block;
+ text-align: center;
+ padding-top: 15px;
+ padding-left: 20px;
+ padding-right: 20px;
+ font-size: 13pt;
+}
+
+div.subPanelTabs ul li.first {
+/* background: url(../images/old/main/blocks/otherPanelBackground_selected.png) no-repeat -9px -5px; */
+ -webkit-border-top-left-radius: 20px;
+ -moz-border-radius-topleft: 20px;
+ border-top-left-radius: 20px;
+}
+
+div.subPanelTabs ul li.selected {
+/* background: url(../images/old/main/blocks/otherPanelBackground_selected.png) no-repeat -45px -5px; */
+ background-color: #eef0e3;
+ border-bottom: 1px solid #eef0e3;
+ border-right: 1px solid #d5d5bc;
+}
+
+div.subPanelTabs ul li.selected:hover {
+ border-right: 1px solid #d5d5bc;
+}
+
+
+div.subPanelTabs ul li.selected a {
+ color: #444440;
+}
+
+
+
+
+
+
+div.subPanelContent {
+ padding-top: 20px;
+ padding-left: 30px;
+ padding-right: 30px;
+ min-height: 280px;
+ color: #787872;
+ margin: 0px 6px 0 9px;
+}
+
+div.subPanelContent ul {
+ margin: 0px;
+ padding: 0px;
+ list-style-type: none;
+}
+
+div.subPanelContent ul li.selected {
+ display: block;
+}
+
+div.subPanelContent ul li {
+ display: none;
+}
+
+div.subPanelContent h3 {
+ margin: 0px;
+ border: 0px;
+ padding: 0px;
+}
+
+/* @end */
+
+/* @group mainPanels otherPanel */
+div.mainPanels div.otherPanel {
+ margin: 5px 10px;
+ background-color: #eef0e3;
+
+ -webkit-border-radius: 20px;
+ -moz-border-radius: 20px;
+ border-radius: 20px;
+
+ -webkit-box-shadow: 2px 2px 9px rgba(0,0,0,0.6);
+ -moz-box-shadow: 2px 2px 9px rgba(0,0,0,0.6);
+ box-shadow: 2px 2px 9px rgba(0,0,0,0.6);
+}
+div.mainPanels div.otherPanel div.header {
+/* background: url(../images/old/main/blocks/otherPanelBackground.png) no-repeat; */
+/*
+ height: 90px;
+*/
+ background-color: #d5d5bc;
+
+/* padding-left: 9px;
+ padding-top: 5px; */
+ margin: 0px;
+ margin-bottom: 0px;
+
+ -webkit-border-top-left-radius: 20px;
+ -webkit-border-top-right-radius: 20px;
+ -moz-border-radius-topleft: 20px;
+ -moz-border-radius-topright: 20px;
+ border-top-left-radius: 20px;
+ border-top-right-radius: 20px;
+}
+
+div.mainPanels div.otherPanel div.body {
+/* background: url(../images/old/main/blocks/otherPanelBackground.png) repeat-y -836px; */
+ margin: 0px;
+ border: 0px;
+ padding: 0px;
+}
+
+div.mainPanels div.otherPanel div.footer {
+/* background: url(../images/old/main/blocks/otherPanelBackground.png) 834px -18px; */
+ height: 45px;
+}
+
+div.mainPanels div.otherPanel div.body h1 {
+ margin: 0px;
+}
+
+/* @end */
+
+/* @group Account */
+
+form.changePassphrase {
+}
+
+form.changePassphrase div.currentCredentials,
+form.changePassphrase div.newPassphrase {
+ float: left;
+ padding: 10px 20px;
+}
+
+form.changePassphrase label {
+ display: inline-block;
+ width: 150px;
+}
+
+form.changePassphrase div.confirm {
+ clear: both;
+ padding: 10px 20px;
+}
+
+form.changePassphrase div.confirm label {
+ width: 500px;
+}
+
+div.currentCredentials {
+}
+
+div.accountPanel h3.manageOTP {
+ margin-top: 20px;
+ margin-left: -20px;
+ padding-top: 10px;
+ padding-left: 20px;
+ border-top: 1px solid #aaaaaa;
+}
+
+/* @end */
+
+
+
+/* @end */
+
+/* @group Message Panel (?) */
+/*
+div.messagePanelWrapper div.mask {
+ position: fixed;
+ top: 0px;
+ left: 0px;
+ right: 0px;
+ bottom: 0px;
+
+ background-color: black;
+ z-index:50001;
+
+ -moz-opacity: 0.0;
+ opacity:.0;
+ filter: alpha(opacity=0);
+/ *
+ -moz-opacity: 0.7;
+ opacity:.70;
+ filter: alpha(opacity=70);
+* /
+}
+
+div.messagePanelFrame {
+ border: 1px solid white;
+ z-index:50002;
+/ *
+ width: 443px;
+ height: 155px;
+ position: fixed;
+ top: 205px;
+ left: 260px;
+ margin-left: auto;
+ margin-right: auto;
+ max-width: 468px;
+* /
+}
+
+
+div.messagePanel {
+ position: fixed;
+ z-index:50003;
+ top: 0px;
+ left: 0px;
+/ *
+ margin-left: auto;
+ margin-right: auto;
+ max-width: 468px;
+ top: 200px;
+ left: 250px;
+ left: 100px;
+ right: 100px;
+* /
+}
+
+div.messagePanel div.header {
+ height: 34px;
+ width: 468;
+ background-image: url(../images/old/alert/header.png);
+}
+
+div.messagePanel div.body {
+ background-image: url(../images/old/alert/body.png);
+ padding: 0px 20px 10px 20px;
+ min-height: 100px;
+}
+/ *
+div#javaScriptAlert div.body div.alert {
+ padding-left: 100px;
+ background: url(../images/old/alert/alert.png) no-repeat;
+}
+* /
+
+div.messagePanel div.body img.alert {
+ float: left;
+}
+
+div.messagePanel div.body div.alert {
+ padding-left: 100px;
+}
+
+div.messagePanel div.footer {
+ height: 34px;
+ width: 468;
+ background-image: url(../images/old/alert/footer.png);
+}
+
+div.messagePanel div.message h1 {
+ font-size: 16pt;
+ margin: 0px;
+ color: #ff5930;
+}
+
+div.messagePanel div.message p {
+ margin-top: 0px;
+ color: #999999;
+}
+
+div.messagePanel div.message h3 {
+ font-size: 12pt;
+ margin-bottom: 0px;
+ color: #ff5930;
+}
+
+div.messagePanel div.message h5 {
+ margin: 0px;
+ color: #999999;
+}
+
+
+*/
+/* @end */
+
+/* @group LoginProgress (?) */
+/*
+div#loginProgress {
+ position: relative;
+ left: -198px;
+ top: -118px;
+ width: 397px;
+ height: 236px;
+ background: url(../images/old/loginProgress/background.png);
+}
+
+div#loginProgress div.header {
+ height: 52px;
+}
+
+div#loginProgress div.header h3 {
+ font-size: 12pt;
+ font-weight: normal;
+ margin: 0px;
+ color: #787872;
+ padding-top: 25px;
+ padding-left: 35px;
+}
+
+div#loginProgress div.body {
+ height: 120px;
+ overflow: auto;
+ margin-left: 19px;
+ margin-right: 18px;
+}
+
+div#loginProgress div.footer {
+ margin-left: 19px;
+ margin-right: 18px;
+}
+
+div#loginProgress div.footer a {
+ font-weight: bold;
+ text-decoration: none;
+ text-align: center;
+ color: #787872;
+ display: block;
+ font-size: 11pt;
+ width: 100px;
+ margin-top: 13px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+div#loginProgress div.footer a:hover {
+ color: #515247;
+}
+
+*/
+
+/* @end */
+
+
+
+div#modalDialogMask,
+div.modalDialogMask {
+ z-index: 20000;
+/* position: absolute; */
+ position: fixed;
+ top:0;
+ left:0;
+ -moz-opacity: 0.5;
+ opacity: .50;
+ filter: alpha(opacity=50);
+/* background-color: #cccccc; */
+ background-color: #000000;
+ width: 100%;
+ height: 100%;
+ zoom: 1;
+}
+
+div#modalDialogFrame,
+div.modalDialogFrame {
+ position: absolute;
+/* border: 1px solid white; */
+ -moz-opacity: 0.5;
+ opacity: .50;
+ filter: alpha(opacity=50);
+ background-color: #333333;
+ z-index: 20001;
+
+ -webkit-border-radius: 20px;
+ -moz-border-radius: 20px;
+ border-radius: 20px;
+}
+
+div#modalDialog,
+div.modalDialog {
+ z-index: 20001;
+}
+
+/*div#modalDialog.scrollable,*/
+div.modalDialog.scrollable {
+ position: absolute;
+ top: 0;
+ left: 50%;
+}
+
+/*div#modalDialog.fixed,*/
+div.modalDialog.fixed {
+ position: fixed;
+ top: 40%;
+ left: 50%;
+}
+
+div#modalDialog div,
+div.modalDialog div {
+ z-index: 20002;
+ list-style-type: circle;
+}
+
+
+
+div.modalDialogMask.simpleMessagePanelMask {
+ z-index: 20010;
+}
+
+div.modalDialogFrame.simpleMessagePanelMask {
+ z-index: 20011;
+}
+
+div.modalDialog.simpleMessagePanelMask {
+ z-index: 20011;
+}
+
+div.modalDialog.simpleMessagePanelMask div {
+ z-index: 20012;
+}
+
+
+/* @group Bookmarklet */
+
+div.bookmarklet {
+}
+
+div.bookmarklet div.bookmarklet_link {
+/*
+ padding-top: 5px;
+ padding-left: 4px;
+ padding-right: 3px;
+
+ float: right;
+ margin-top: 12px;
+ margin-right: 13px;
+*/
+ height: 34px;
+}
+
+div.bookmarklet div.bookmarklet_link a {
+ color: #838975;
+ text-decoration: none;
+ font-weight: bold;
+ font-size: 10pt;
+/*
+ display: block;
+ text-align: right;
+ padding-top: 7px;
+ padding-right: 11px;
+ padding-bottom: 6px;
+*/
+}
+
+div.bookmarklet div.bookmarklet_link a div.icon {
+ background: url(../images/old/bookmarklet/placeholder_icon.png) no-repeat 0 0;
+ float: left;
+ width: 34px;
+ height: 34px;
+}
+
+div.bookmarklet div.bookmarklet_link a:hover div.icon {
+ background: url(../images/old/bookmarklet/placeholder_selected_icon.png) no-repeat 0 0;
+}
+
+div.bookmarklet div.bookmarklet_link a div.text {
+ display: block;
+ float: right;
+ background: url(../images/old/bookmarklet/placeholder.png) no-repeat right 0;
+ white-space: nowrap;
+ height: 34px;
+}
+
+div.bookmarklet div.bookmarklet_link a:hover div.text {
+ background: url(../images/old/bookmarklet/placeholder_selected.png) no-repeat right 0;
+}
+div.bookmarklet div.bookmarklet_link a div.text span {
+ display: block;
+ padding-top: 10px;
+ padding-right: 10px;
+ padding-left: 6px;
+
+ clear: both;
+}
+
+/* @end */
+
+/* @group Tooltip */
+
+/*
+div#Clipperz_PM_UI_Common_Components_Tooltip_wrapperNode {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+}
+*/
+
+div.tooltip {
+ position: absolute;
+ z-index: 30001;
+}
+
+
+div.tooltip div.tooltip_body {
+ position: absolute;
+}
+
+div.tooltip div.tooltip_arrow {
+ position: absolute;
+}
+
+div.tooltip.BELOW div.tooltip_arrow {
+ background: url(../images/old/tooltips/top_arrow.png) no-repeat;
+}
+
+div.tooltip.ABOVE div.tooltip_arrow {
+ background: url(../images/old/tooltips/bottom_arrow.png) no-repeat;
+}
+
+div.tooltip.LEFT div.tooltip_arrow {
+ background: url(../images/old/tooltips/right_arrow.png) no-repeat;
+}
+
+div.tooltip.RIGHT div.tooltip_arrow {
+/* margin-top: 7px; */
+ background: url(../images/old/tooltips/left_arrow.png) no-repeat;
+}
+div.tooltip.RIGHT div.tooltip_body {
+/* padding-left: 13px; */
+}
+
+
+div.tooltip div.tooltip_body div.tooltip_text {
+ width: 171px;
+ background: url(../images/old/tooltips/body.png) no-repeat center top;
+}
+
+div.tooltip.LEFT div.tooltip_body div.tooltip_text,
+div.tooltip.RIGHT div.tooltip_body div.tooltip_text {
+ min-height: 45px;
+}
+
+div.tooltip div.tooltip_body span {
+ display: block;
+ padding: 10px;
+ padding-bottom: 4px;
+ font-size: 10pt;
+ color: white;
+}
+
+div.tooltip div.tooltip_footer {
+ height: 7px;
+ background: url(../images/old/tooltips/body_bottom.png) no-repeat;
+}
+
+/* @end */
+
+/* @group News */
+/*
+div#news {
+ top: 11px;
+ left: 240px;
+ width: 353px;
+ height: 85px;
+ padding-top: 4px;
+ position: absolute;
+ overflow: hidden;
+ background: url(../images/old/note.png) 1px 3px;
+}
+
+div#news.hidden {
+ display: none;
+}
+
+div#news div.close {
+ display: inline;
+ margin-top: 6px;
+ margin-left: 17px;
+ float: left;
+ width: 15px;
+}
+
+div#news div.close a {
+ text-decoration: none;
+ color: #929c1b;
+}
+
+div#news div.close a:hover {
+ text-decoration: none;
+ color: #3d420b;
+}
+
+div#news div#newsframe {
+ display: block;
+ overflow: hidden;
+ width: 305px;
+ height: 70px;
+}
+
+div#news div#newsframe iframe {
+ border: 0px;
+}
+*/
+/* --------------------------------------- */
+
+div#news {
+ top: -82px;
+ left: 240px;
+ width: 310px;
+ height: 90px;
+ position: absolute;
+/* background: url(../images/old/tips/Tips_background.png) 0 -5px; */
+
+ background-color: #616474;
+
+ -webkit-border-bottom-right-radius: 8px;
+ -webkit-border-bottom-left-radius: 8px;
+ -moz-border-radius-bottomright: 8px;
+ -moz-border-radius-bottomleft: 8px;
+ border-bottom-right-radius: 8px;
+ border-bottom-left-radius: 8px;
+
+ -webkit-box-shadow: 2px 2px 9px rgba(0,0,0,0.6);
+ -moz-box-shadow: 2px 2px 9px rgba(0,0,0,0.6);
+ box-shadow: 2px 2px 9px rgba(0,0,0,0.6);
+}
+/*
+div#news.open {
+ background: url(../images/old/tips/Tips_open.png) 0 -5px;
+}
+
+div#news.hidden {
+ background: url(../images/old/tips/Tips_close.png) 0 -5px;
+}
+*/
+div#news div#newsframe {
+ margin-left: 10px;
+ margin-right: 10px;
+ height: 75px;
+ overflow: hidden;
+}
+
+div#news div#newsframe.loading {
+ background: url(../images/old/loading/news.gif) no-repeat center center;
+}
+
+div#news div#newsframe iframe {
+ width: 290px;
+ border: 0px;
+ color: #616474;
+ background-color: #616474;
+}
+
+div#news div.grip {
+ width: 310px;
+ height: 12px;
+ margin-top: 2px;
+ cursor: pointer;
+}
+
+div#news.open div.grip {
+ background: url(../images/old/tips/close.png) no-repeat center 6px;
+}
+
+div#news.hidden div.grip {
+ background: url(../images/old/tips/open.png) no-repeat center 6px;
+}
+
+/* @end */
+
+/* @group mainDialog */
+div.mainDialog {
+ position: relative;
+ left: -263px;
+ width: 525px;
+ height: 325px;
+}
+
+div.scrollable div.mainDialog {
+ top: 0px;
+}
+
+div.fixed div.mainDialog {
+ top: -118px;
+}
+
+div.mainDialog div.header {
+ height: 55px;
+ background: url(../images/old/cardDialog/background_header.png) no-repeat;
+}
+
+div.mainDialog div.header div.title {
+ padding-top: 16px;
+ padding-left: 20px;
+ padding-right: 20px;
+}
+
+div.mainDialog div.header div.title input {
+ width: 100%;
+ display: block;
+ font-size: 16pt;
+ margin: 0px;
+ border: 0px;
+ padding: 3px 10px;
+ color: #787872;
+ border: 1px solid #cccec0;
+ background-color: #cccec0;
+}
+
+div.mainDialog div.header div.title h3 {
+ display: block;
+ font-size: 16pt;
+ color: #787872;
+ margin: 0px;
+ border: 0px;
+ padding: 3px 10px;
+}
+
+div.mainDialog div.header div.title.selectedField input,
+div.mainDialog div.header div.title:hover input {
+ border: 1px solid #515247;
+ background-color: #b5b7ab;
+}
+
+div.mainDialog div.header div.title.disabled:hover input {
+ border: 1px solid #cccec0;
+ background-color: #cccec0;
+}
+
+div.mainDialog div.body {
+ padding-top: 0px;
+ padding-left: 10px;
+ padding-right: 9px;
+ min-height: 200px;
+ background: url(../images/old/cardDialog/background_body.png) repeat-y;
+}
+
+div.mainDialog div.body div.mask {
+ display: none;
+}
+
+div.mainDialog.loading div.body div.mask {
+ display: block;
+ position: absolute;
+ top: 55px;
+ left: 10px;
+ right: 9px;
+ bottom: 70px;
+ z-index:1001;
+ background-color: white;
+ padding-left: 146px;
+ padding-right: 146px;
+ padding-top: 70px;
+}
+
+div.mainDialog.loading div.body .tabPanels {
+ display: none;
+}
+
+div.mainDialog.loading div.body div.mask h3.progressDescription {
+ margin: 0px;
+ text-align: center;
+ padding-bottom: 10px;
+ color: #cccec0;
+ font-size: 14pt;
+ font-weight: normal;
+}
+
+div.loadingBar {
+ height: 22px;
+ width: 214px;
+ background: url(../images/old/loading/loadingBar.gif) no-repeat center top;
+}
+
+div.loadingBar div.loadingBarProgressBox {
+ padding: 2px;
+}
+
+div.loadingBar div.loadingBarProgress {
+ height:18px;
+ width: 0%;
+/* background-repeat: no-repeat; */
+ background-color: rgba(248,79,0,0.6);
+ -webkit-border-radius: 9px;
+ -moz-border-radius: 9px;
+ border-radius: 9px;
+}
+
+/*
+div.loadingBar div.loadingBarProgress div.loadingBarProgress_left {
+ height: 100%;
+ max-width: 8px;
+ background: url(../images/old/loading/loadingBarProgress.png) no-repeat 0;
+}
+
+div.loadingBar div.loadingBarProgress div.loadingBarProgress_right {
+ position: relative;
+ height: 100%;
+ margin-left: 8px;
+ background: url(../images/old/loading/loadingBarProgress.png) no-repeat right;
+ top: -22px;
+}
+*/
+
+div.mainDialog div.body div ul {
+ padding: 0px;
+ clear: both;
+ margin: 0px;
+ list-style-type: none;
+}
+
+div.mainDialog div.body div.tabs {
+ height: 20px;
+}
+
+div.mainDialog div.body div.tabs ul.tabs {
+ height: 33px;
+/* border-bottom: 1px solid #515247;*/
+/* background: #cccec0 url(../images/old/cardDialog/tabs_shadow.png) repeat-x 0 -5px;*/
+ background: url(../images/old/cardDialog/tabs_background.png) repeat-x;
+}
+
+div.mainDialog div.body div.tabs ul.tabs li {
+/* width: 150px; */
+ height: 32px;
+ font-size: 11pt;
+ text-align: center;
+ border-right: 1px solid #515247;
+ float: left;
+ color: #787872;
+ border-bottom: 1px solid #515247;
+
+ background: #cccec0 url(../images/old/cardDialog/tabs_shadow.png) repeat-x 0 -5px;
+ cursor: pointer;
+}
+
+div.mainDialog div.body div.tabs ul.tabs li div {
+ display: none;
+}
+
+div.mainDialog div.body div.tabs ul.tabs li span {
+ display: block;
+ padding-top: 9px;
+ padding-bottom: 6px;
+ padding-left: 40px;
+ padding-right: 40px;
+}
+
+div.mainDialog div.body div.tabs ul.tabs li:hover {
+ color: #515247;
+}
+
+div.mainDialog div.body div.tabs ul.tabs li.disabled:hover {
+ color: #787872;
+ cursor: default;
+}
+
+div.mainDialog div.body div.tabs ul.tabs li.selected {
+ color: #515247;
+ background-color: #f1f2e9;
+ border-bottom: 1px solid #f1f2e9;
+ cursor: default;
+}
+
+div.mainDialog div.body div.tabs ul.tabs li.selected.disabled:hover {
+ color: #515247;
+}
+
+div.mainDialog div.body div.tabs ul.tabs li.selected div.backToDirectLoginList {
+ position: absolute;
+ display: block;
+ top: 63px;
+ left: 140;
+ width: 20px;
+}
+
+div.mainDialog div.body div.tabs ul.tabs li.selected div.addDirectLoginButton {
+ position: absolute;
+ display: block;
+ top: 63px;
+ left: 265px;
+
+ width: 20px;
+}
+
+div.mainDialog div.body div.tabs ul.tabs li.selected div span {
+ padding: 0px;
+ margin: 0px;
+}
+
+div.mainDialog div.body div.tabs ul.tabs li.selected div:hover {
+ cursor: pointer;
+}
+
+div.mainDialog div.body .tabPanels {
+ clear: both;
+}
+
+div.mainDialog div.body ul.tabPanels li.tabPanel {
+ display: none;
+}
+
+div.mainDialog div.body ul.tabPanels li.tabPanel.selected {
+ display: block;
+}
+
+div.mainDialog div.body ul.tabPanels li.tabPanel.selected h2 {
+ margin: 0px;
+ text-align: center;
+ padding-top: 50px;
+ color: #787872;
+}
+
+div.mainDialog div.body ul.tabPanels li.tabPanel.selected div.wizardStepDescription {
+ margin: 0px 20px 10px;
+ font-size: 10pt;
+ color: b0b0b0;
+ font-style: italic;
+ text-align: center;
+}
+
+div.mainDialog div.footer {
+ height: 70px;
+ background: url(../images/old/cardDialog/background_footer.png) no-repeat 0 -14px;
+}
+
+div.mainDialog div.footer div.buttonArea {
+ padding-left: 40px;
+ padding-right: 40px;
+ padding-top: 15px;
+}
+
+div.mainDialog div.footer div.buttonArea div {
+ padding-left: 20px;
+ padding-right: 20px;
+ float: left;
+
+ font-weight: bold;
+ color: #787872;
+}
+
+div.mainDialog div.footer div.buttonArea div.disabled {
+ color: #b1b1a8;
+}
+
+div.mainDialog div.footer div.buttonArea div.disabled:hover {
+ color: #b1b1a8;
+ cursor: default;
+}
+
+div.mainDialog div.footer div.buttonArea div:hover {
+ color: #515247;
+ cursor: pointer;
+}
+
+div.mainDialog div.footer div.buttonArea div.save {
+ float: right;
+}
+
+
+/* @end */
+
+/* @group Card Dialog */
+
+div.addDirectLoginButton {
+ height: 20px;
+ width: 20px ;
+ background: url(../images/old/cardDialog/addDirectLogin_disabled_background.png) no-repeat -9px -9px;
+ color: white;
+ font-weight: bold;
+}
+
+div.addDirectLoginButton span {
+ display: block;
+ height: 20px;
+ width: 20px ;
+}
+
+div.addDirectLoginButton:hover {
+ background: url(../images/old/cardDialog/addDirectLogin_background.png) no-repeat -9px -9px;
+}
+
+/* @group Card Dialog - Direct Login */
+
+div.directLoginsComponentContainer {
+ overflow: hidden;
+/* background-color: green; */
+}
+
+div.CardDialog div.directLogins {
+/* background-color: yellow; */
+ padding-top: 2px;
+}
+
+div.CardDialog div.addNewDirectLoginSplash {
+ margin: 0px 80px;
+}
+
+div.CardDialog div.addNewDirectLoginSplash h3 {
+ color: #aaaaaa;
+ text-align: center;
+ font-weight: normal;
+ font-size: 11pt;
+}
+
+div.CardDialog div.addNewDirectLoginSplash a {
+ display: block;
+ text-decoration: none;
+ margin-left: auto;
+ margin-right: auto;
+ width: 190px;
+/* color: #787878; */
+ color: rgba(255,98,6,0.75);
+ text-transform: uppercase;
+ background: url(../images/old/cardDialog/addDirectLogin_disabled_background.png) no-repeat right;
+}
+
+div.CardDialog div.addNewDirectLoginSplash a span {
+ text-align: center;
+}
+
+div.CardDialog div.addNewDirectLoginSplash a:hover {
+ color: #ff6206;
+ background: url(../images/old/cardDialog/addDirectLogin_background.png) no-repeat right;
+}
+
+div.CardDialog div.directLoginItem {
+ clear: both;
+ min-height: 32px;
+ padding-left: 10px;
+ padding-top: 4px;
+ padding-bottom: 2px;
+
+/* width: 100px; */
+ max-height: 32px;
+ overflow: hidden;
+}
+
+div.CardDialog div.directLoginItem:hover {
+ background-color: #cccec0;
+}
+
+div.CardDialog div.addDirectLoginListItem {
+ min-height: 32px;
+ padding-left: 10px;
+ padding-top: 4px;
+ padding-bottom: 2px;
+
+ max-height: 32px;
+ overflow: hidden;
+
+ background: url(../images/old/cardDialog/addDirectLogin_disabled_background.png) no-repeat 22px 0;
+}
+
+div.CardDialog div.addDirectLoginListItem a {
+ display: block;
+ font-size: 11pt;
+ padding-top: 6px;
+ padding-left: 50px;
+ color: rgba(255,98,6,0.75);
+ text-decoration: none;
+ text-transform: uppercase;
+}
+
+div.CardDialog div.addDirectLoginListItem:hover {
+ background: url(../images/old/cardDialog/addDirectLogin_background.png) no-repeat 22px 0;
+ color: #ff6206;
+ background-color: #cccec0;
+}
+
+div.CardDialog div.addDirectLoginListItem:hover {
+}
+
+
+div.CardDialog div.directLoginItem div.cardDialogRecordDirectLoginComponent_favicon img.favicon {
+ width: 32px;
+ height: 32px;
+ float: left;
+}
+div.CardDialog div.directLoginItem div.cardDialogRecordDirectLoginComponent_label input {
+ float: left;
+ font-size: 11pt;
+ border: 0px;
+ padding: 5px;
+ color: #787872;
+ border: 1px solid #ededeb;
+ background-color: #ededeb;
+ height: 30px;
+ margin-left: 10px;
+ width: 68%;
+ margin-right: 5px;
+}
+
+div.CardDialog div.directLoginItem:hover div.cardDialogRecordDirectLoginComponent_label input {
+ border: 1px solid #515247;
+ background-color: #b5b7ab;
+}
+
+div.CardDialog div.directLoginItem > div.open {
+ float: left;
+ margin-top: 5px;
+ margin-right: 2px;
+ padding-left: 5px;
+ visibility: hidden;
+}
+
+div.CardDialog div.directLoginItem > div.edit,
+div.CardDialog div.directLoginItem > div.delete {
+ float: left;
+ margin-top: 5px;
+ margin-left: 3px;
+ padding-left: 5px;
+ visibility: hidden;
+}
+
+div.CardDialog div.directLoginItem > div.open a {
+ display: block;
+ width: 22px;
+ height: 22px;
+ background: url(../images/old/cardDialog/openDirectLogin.png) no-repeat 0 -2px;
+}
+
+div.CardDialog div.directLoginItem > div.open a:hover {
+ background: url(../images/old/cardDialog/openDirectLogin_selected.png) no-repeat 0 -2px;
+}
+
+div.CardDialog div.directLoginItem:hover > div.open,
+div.CardDialog div.directLoginItem:hover > div.edit,
+div.CardDialog div.directLoginItem:hover > div.delete {
+ visibility: visible;
+}
+
+div.CardDialog div.directLoginItem div.edit span {
+ padding-right: 6px;
+ display: block;
+}
+
+div.CardDialog div.directLoginItem div.open span a,
+div.CardDialog div.directLoginItem div.edit span a,
+div.CardDialog div.directLoginItem div.delete span a {
+ font-size: 8pt;
+ color: #666666;
+ text-decoration: none;
+ line-height: 19px;
+}
+
+div.CardDialog div.directLoginItem div.edit:hover {
+ background: url(../images/old/new_background_left.png) no-repeat;
+}
+
+div.CardDialog div.directLoginItem div:hover span a {
+ color: white;
+}
+
+div.CardDialog div.directLoginItem div.edit:hover span {
+ background: url(../images/old/new_background.png) no-repeat right center;
+}
+
+div.CardDialog div.directLoginItem div.delete:hover {
+ background: url(../images/old/delete_background_left.png) no-repeat;
+}
+
+div.CardDialog div.directLoginItem div.delete:hover span {
+ background: url(../images/old/delete_background.png) right;
+}
+
+/* @group Direct Login Editing */
+
+div.CardDialog div.directLoginEditDetail {
+ position: relative;
+/* background-color: red; */
+}
+
+/*
+div.CardDialog div.directLoginEditDetail div.back {
+ float: left;
+ width: 30px;
+}
+
+div.CardDialog div.directLoginEditDetail div.back a {
+ display: block;
+ padding: 5px;
+ text-decoration: none;
+ font-weight: bold;
+ font-size: 14pt;
+ color: #cccec0;
+
+ background: url(../images/old/cardDialog/back.png) no-repeat 5px 14px;
+ width: 20px;
+ height: 200px;
+}
+
+div.CardDialog div.directLoginEditDetail div.back a:hover {
+ color: #7f7872;
+ background: url(../images/old/cardDialog/back_selected.png) no-repeat 5px 14px;
+}
+*/
+
+
+form.directLoginEditingForm div.title,
+form.directLoginEditingForm div.favicon {
+ padding: 5px 10px;
+}
+
+form.directLoginEditingForm div.title.disabled:hover {
+ background-color: #f1f2e9;
+}
+
+form.directLoginEditingForm div.title:hover,
+form.directLoginEditingForm div.favicon:hover {
+ background-color: #cccec0;
+}
+
+form.directLoginEditingForm div.title input {
+/* width: 100%; */
+ margin: 0px;
+ margin-left: 10px;
+ width: 440px;
+}
+
+form.directLoginEditingForm div.favicon {
+ padding-left: 10px;
+}
+
+/*form.directLoginEditingForm div.favicon img.favicon {*/
+form.directLoginEditingForm img.favicon {
+ float: left;
+ width: 32px;
+ height: 32px;
+}
+
+form.directLoginEditingForm div.favicon input {
+ margin-top: 1px;
+ width: 465px;
+}
+
+form.directLoginEditingForm div.disabled:hover input,
+form.directLoginEditingForm div input {
+ font-size: 11pt;
+ border: 0px;
+ padding: 5px;
+ color: #787872;
+ border: 1px solid #ededeb;
+ background-color: #ededeb;
+ height: 30px;
+}
+
+form.directLoginEditingForm div:hover input {
+ border: 1px solid #515247;
+ background-color: #b5b7ab;
+}
+
+/* @group Bindings */
+
+div.bindings div.binding > span.formFieldName {
+ display: inline-block;
+ width: 140px;
+ overflow: hidden;
+ margin-right: 10px;
+ color: #6b5147;
+ text-overflow:ellipsis;
+}
+
+div.bindings div.binding {
+ padding-bottom: 3px;
+}
+
+div.bindings div.binding > input {
+ margin-right: 10px;
+ background: #cccec0;
+ width: 150px;
+ border: 1px solid #cccec0;
+}
+
+div.bindings div.binding:hover > input {
+ border: 1px solid #cccec0;
+}
+
+div.bindings div.binding > select {
+ font-size: 13pt;
+}
+
+div.bindings div.binding span.fieldLock {
+ display: inline-block;
+ width: 20px;
+ height: 20px;
+ margin-right: 3px;
+}
+
+div.bindings div.binding.showLocked input {
+ background: url(../images/old/cardDialog/password_background.png) no-repeat 2px 3px;
+/* color: black; */
+ overflow: hidden;
+
+ background: #cccec0 url(../images/old/cardDialog/password_background.png) no-repeat 2px 3px;
+ color: rgba(237,237,235,0.1);
+}
+
+div.bindings div.binding span.fieldLock a {
+ display: none;
+}
+
+div.bindings div.binding.locked span.fieldLock {
+}
+
+div.bindings div.binding.locked span.fieldLock a {
+ display: block;
+ width: 20px;
+ height: 20px;
+ text-decoration: none;
+
+ background-image: url(../images/old/cardDialog/lock_open.png);
+}
+
+div.bindings div.binding.locked.showLocked span.fieldLock a {
+ background-image: url(../images/old/cardDialog/lock_closed.png);
+ text-decoration: none;
+}
+
+/* @end */
+
+/* @group FormValues */
+
+div.formValues {
+ padding-top: 15px;
+}
+
+div.formValues div.formValue div {
+ margin: 0px;
+ display: inline-block;
+}
+
+div.formValues div.formValue > span.formFieldName {
+ display: inline-table;
+ width: 160px;
+ overflow: hidden;
+ margin-right: 10px;
+ color: #6b5147;
+}
+
+/* @end */
+
+
+/* @group FormValues */
+/*
+div.formValues {
+ padding-top: 15px;
+}
+
+div.formValues div.formValue > span.formFieldName {
+ display: inline-table;
+ width: 150px;
+ overflow: hidden;
+ margin-right: 35px;
+ color: #6b5147;
+}
+
+div.formValues div.formValue > select {
+ padding-left: 20px;
+}
+*/
+/* @end */
+
+/* @group Panels */
+
+div.directLoginEditing {
+ padding-top: 2px;
+}
+
+div.directLoginEditing div.tabContainer {
+ min-height: 150px;
+ height: 200px;
+}
+
+div.directLoginEditing div.tabContainer > ul.tabs {
+ display: none;
+}
+
+/*
+div.directLoginEditing li.configuration,
+div.directLoginEditing li.bindings,
+div.directLoginEditing li.favicon {
+ padding: 10px;
+}
+*/
+div.directLoginEditing li {
+ padding: 10px;
+}
+
+div.directLoginEditing li.configuration > .bookmarkletConfigurationWrapper > textarea {
+ float: left;
+ width: 320px;
+ height: 125px;
+ font-family: monospace;
+ font-weight: normal;
+ font-size: 8pt;
+ border: 1px solid #ccc;
+}
+
+div.directLoginEditing li.configuration > .bookmarkletConfigurationWrapper .bookmarkletComponent {
+ float: right;
+}
+
+div.directLoginEditing li.configuration > textarea.error {
+ border: 1px solid red;
+ background-color: rgba(255,0,0,0.1);
+}
+
+/*
+div.directLoginEditing > form.directLoginEditingForm > div.tabContainer {
+ padding-top: 10px;
+}
+
+div.directLoginEditing > form.directLoginEditingForm > div.tabContainer > ul.tabs > li {
+ float: left;
+ padding-left: 10px;
+ padding-right: 10px;
+ display: block;
+ font-size: 10pt;
+ color: #787872;
+ cursor: pointer;
+
+ height: 22px;
+ text-align: center;
+ border-right: 1px solid #aaa;
+ border-bottom: 1px solid #aaa;
+ border-top: 1px solid #aaa;
+
+ background-color: #cccec0;
+}
+
+div.directLoginEditing > form.directLoginEditingForm > div.tabContainer > ul.tabs > li:first-child {
+ border-left: 1px solid #aaa;
+}
+
+div.directLoginEditing > form.directLoginEditingForm > div.tabContainer > ul.tabs {
+ height: 23px;
+ padding-left: 10px;
+ border-bottom: 1px solid #aaa;
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+div.directLoginEditing > form.directLoginEditingForm > div.tabContainer > ul.tabs > li > span {
+ line-height: 23px;
+}
+
+div.directLoginEditing > form.directLoginEditingForm > div.tabContainer > ul.tabs > li.selected {
+ color: #6a5147;
+ cursor: default;
+ border-bottom: 1px solid #f1f2e9;
+ background-color: #f1f2e9;
+}
+
+div.directLoginEditing > form.directLoginEditingForm > div.tabContainer > ul.tabs > li:hover {
+ color: #6a5147;
+}
+
+div.directLoginEditing > form.directLoginEditingForm > div.tabContainer > ul.tabPanels {
+ padding-bottom: 5px;
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+div.directLoginEditing > form.directLoginEditingForm > div.tabContainer > ul.tabPanels > li.selected {
+ border-bottom: 1px solid #aaa;
+ border-left: 1px solid #aaa;
+ border-right: 1px solid #aaa;
+}
+
+div.directLoginEditing li.configuration {
+ padding: 5px;
+}
+
+div.directLoginEditing li.configuration > textarea {
+ width: 100%;
+ height: 100px;
+ font-family: monospace;
+ font-weight: normal;
+ font-size: 8pt;
+}
+*/
+/* @end */
+
+/* @end */
+
+/* @end */
+
+/* @group Card Dialog FIELDS */
+
+div.CardDialog div.body {
+ padding-bottom: 1px;
+}
+
+div.CardDialog div.body table.fields {
+ width: 100%;
+ padding-top: 8px;
+ padding-bottom: 1px;
+}
+
+div.CardDialog div.body table.fields thead {
+ background: url(../images/old/cardDialog/dottedLine_background.png) repeat-x 0 15px;
+}
+
+div.CardDialog div.body table.fields tfoot {
+ background: url(../images/old/cardDialog/dottedLine_background.png) repeat-x 0 bottom;
+}
+
+div.CardDialog div.body table.fields thead th {
+ text-align: left;
+ font-weight: normal;
+ font-size: 9pt;
+ color: #787872;
+ padding-left: 10px;
+ padding-bottom: 3px;
+
+/*
+ border-bottom: 1px dotted;
+*/
+}
+
+
+div.CardDialog div.body table.fields thead th.fieldStateTH {
+ width: 10px;
+}
+
+div.CardDialog div.body table.fields thead th.fieldLabelTH {
+}
+
+div.CardDialog div.body table.fields tbody td.fieldLabel input {
+ width: 130px;
+}
+
+div.CardDialog div.body table.fields thead th.fieldLockTH {
+ width: 10px;
+}
+
+
+div.CardDialog div.body table.fields thead th.fieldValueTH {
+}
+
+div.CardDialog div.body table.fields tbody td.fieldValue input {
+ width: 280px;
+}
+
+div.CardDialog div.body table.fields thead th.fieldActionTH {
+ width: 30px;
+}
+
+div.CardDialog div.body table.fields tbody td.fieldAction div {
+}
+
+div.CardDialog div.body table.fields thead th.fieldDeleteTH {
+ width: 40px;
+}
+
+div.CardDialog div.body table.fields tbody tr:hover,
+div.CardDialog div.body table.fields tbody tr.selectedField {
+ background-color: #cccec0;
+}
+
+div.CardDialog div.body table.fields tbody tr td {
+ font-size: 11pt;
+ color: #787872;
+ height: 35px;
+}
+
+
+div.CardDialog div.body table.fields tbody tr td input {
+ font-size: 11pt;
+ border: 0px;
+ padding: 5px;
+ color: #787872;
+ border: 1px solid #ededeb;
+ background-color: #ededeb;
+ height: 30px;
+}
+/*
+div.CardDialog div.body table.fields tbody tr td.fieldValue div {
+ margin-right: 10px;
+}
+
+div.CardDialog div.body table.fields tbody tr td.fieldValue div input {
+ width: 100%;
+}
+*/
+div.CardDialog div.body table.fields tbody tr td.fieldValue div.locked input {
+ background: #ededeb url(../images/old/cardDialog/password_background.png) no-repeat 2px 3px;
+ color: #ededeb;
+ color: rgba(237,237,235,0.1);
+/* color: black; */
+/* line-height: 100px; */
+ overflow: hidden;
+}
+
+div.locked input.value::-moz-selection {
+ background: #ff0000;
+}
+
+div.locked input.value::selection {
+ background: #ff0000;
+}
+
+
+div.CardDialog div.body table.fields tbody tr.new.selectedField td input,
+div.CardDialog div.body table.fields tbody tr.new:hover td input,
+div.CardDialog div.body table.fields tbody tr:hover td input,
+div.CardDialog div.body table.fields tbody tr.selectedField td input {
+ border: 1px solid #515247;
+ background-color: #b5b7ab;
+}
+
+div.CardDialog div.body table.fields tbody tr:hover td.fieldValue div.locked input,
+div.CardDialog div.body table.fields tbody tr.selectedField td.fieldValue div.locked input {
+ background: #b5b7ab url(../images/old/cardDialog/password_background.png) no-repeat 2px 3px;
+ color: #b5b7ab;
+ color: rgba(237,237,235,0.1);
+}
+
+
+
+div.CardDialog div.body table.fields tbody td.fieldLock div {
+ width: 20px;
+ height: 19px;
+ cursor: pointer;
+}
+
+div.CardDialog div.body table.fields tbody tr:hover td.fieldLock div.locked {
+ background-image: url(../images/old/cardDialog/lock_closed.png);
+}
+
+div.CardDialog div.body table.fields tbody tr:hover td.fieldLock div.unlocked {
+ background-image: url(../images/old/cardDialog/lock_open.png);
+}
+
+div.CardDialog div.body table.fields tbody tr td.fieldAddDelete div span a {
+ text-decoration: none;
+ visibility: hidden;
+ font-size: 8pt;
+ vertical-align: -13px;
+ color: black;
+}
+
+div.CardDialog div.body table.fields tbody tr.selectedField td.fieldAddDelete div span a {
+ visibility: visible;
+}
+
+div.CardDialog div.body table.fields tbody tr:hover td.fieldAddDelete div span a {
+ visibility: visible;
+}
+
+div.CardDialog div.body table.fields tbody tr:hover td.fieldAddDelete div:hover span a {
+ color: white;
+}
+
+
+div.CardDialog div.body div.notes {
+ background: url(../images/old/cardDialog/dottedLine_background.png) repeat-x 0 0;
+ padding-top: 2px;
+}
+
+div.CardDialog div.body div.notes div {
+ padding-left: 20px;
+ padding-right: 20px;
+ padding-top: 4px;
+ padding-bottom: 4px;
+}
+
+div.CardDialog div.body div.notes div:hover,
+div.CardDialog div.body div.notes.selectedField div {
+ background-color: #cccec0;
+}
+
+div.CardDialog.loading div.body div.notes div textarea {
+ display: none;
+}
+
+div.CardDialog div.body div.notes div textarea {
+ border: 0;
+ width: 470px;
+/*
+ width: 100%;
+ height: 100px;
+ min-height: 400px;
+ overflow: hidden;
+*/
+ color: #787872;
+ border: 1px solid #ededeb;
+ background-color: #ededeb;
+ display: block;
+ line-height: 12pt;
+ min-height: 50px;
+}
+
+div.CardDialog div.body div.notes div:hover textarea,
+div.CardDialog div.body div.notes.selectedField div textarea {
+ border: 1px solid #515247;
+ background-color: #b5b7ab;
+}
+
+
+div.CardDialog div.body table.fields tbody tr td.fieldAction {
+/* background-color: red; */
+ padding-left: 4px
+}
+
+div.CardDialog div.body table.fields tbody tr td.fieldAction a {
+ display: inline-block;
+ text-decoration: none;
+ text-align: center;
+ width: 16px;
+ height: 16px;
+}
+
+div.CardDialog div.body table.fields tbody tr td.fieldAction a.email {
+ background: url(../images/old/cardDialog/fieldTypes/email.png) no-repeat 0 0;
+}
+
+div.CardDialog div.body table.fields tbody tr td.fieldAction a.email:hover {
+ background: url(../images/old/cardDialog/fieldTypes/email_selected.png) no-repeat 0 0;
+}
+
+div.CardDialog div.body table.fields tbody tr td.fieldAction a.url {
+ background: url(../images/old/cardDialog/fieldTypes/url.png) no-repeat 0 0;
+}
+
+div.CardDialog div.body table.fields tbody tr td.fieldAction a.url:hover {
+ background: url(../images/old/cardDialog/fieldTypes/url_selected.png) no-repeat 0 0;
+}
+
+div.CardDialog div.body table.fields tbody tr td.fieldAction a.password {
+ background: url(../images/old/cardDialog/fieldTypes/password.png) no-repeat 0 0;
+}
+
+div.CardDialog div.body table.fields tbody tr td.fieldAction a.password:hover {
+ background: url(../images/old/cardDialog/fieldTypes/password_selected.png) no-repeat 0 0;
+}
+
+/*
+/ *div.CardDialog div.body table.fields tbody* / tr.new {
+ background: yellow;
+}
+
+div.CardDialog div.body table.fields tbody tr.new td input {
+ border: 1px solid red;
+ background-color: green;
+}
+*/
+/* @end */
+
+
+
+/* @end */
+
+div#disabledZone {
+ display: block;
+ visibility: visible;
+}
+
+div#messageZone {
+ display: block;
+ visibility: visible;
+}
+
+
+div.CardDialog div.error div.img {
+ margin: 10px;
+ width: 50px;
+ height: 50px;
+ float: left;
+
+ background-image: url(../images/old/simpleMessageBox/Alert.png);
+}
+
+/* @group Ruler */
+/*
+div.rulerExtraWrapper {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ background-color: rgba(255, 0, 0, 0.2);
+ z-index: 24999;
+}
+*/
+
+div.rulerWrapper {
+ left: -1000px;
+ margin-top: -30px;
+ margin-left: 50%;
+ z-index: 25000;
+}
+
+div.rulerWrapper.fixed {
+ position: fixed;
+}
+
+div.rulerWrapper.scrollable {
+ position: absolute;
+}
+
+div.ruler {
+/* position: absolute; */
+ width: 541px;
+ height: 96px;
+ margin-left: -270px;
+
+ background: url(../images/old/ruler/ruler.png) no-repeat;
+}
+
+div.ruler a {
+ position: absolute;
+ display: block;
+
+ width: 15px;
+ height: 15px;
+ top: 3px;
+ text-decoration: none;
+}
+
+div.ruler a.exit {
+ margin-left: 2px;
+ background: url(../images/old/ruler/exit.png) no-repeat;
+}
+
+div.ruler a.exit:hover {
+ background: url(../images/old/ruler/exit_selected.png) no-repeat;
+}
+
+div.ruler a.smallButton.previous {
+ right: 16px;
+ background: url(../images/old/ruler/small_previous.png) no-repeat;
+}
+
+div.ruler a.smallButton.previous:hover {
+ cursor: pointer;
+ background: url(../images/old/ruler/small_previous_selected.png) no-repeat;
+}
+
+div.ruler a.smallButton.previous.disabled,
+div.ruler a.smallButton.previous.disabled:hover {
+ cursor: default;
+ background: url(../images/old/ruler/small_previous_disabled.png) no-repeat;
+}
+
+div.ruler a.smallButton.next {
+ right: 3px;
+ background: url(../images/old/ruler/small_next.png) no-repeat;
+}
+
+div.ruler a.smallButton.next:hover {
+ cursor: pointer;
+ background: url(../images/old/ruler/small_next_selected.png) no-repeat;
+}
+
+div.ruler a.smallButton.next.disabled,
+div.ruler a.smallButton.next.disabled:hover {
+ cursor: default;
+ background: url(../images/old/ruler/small_next_disabled.png) no-repeat;
+}
+
+div.ruler div.steps, div.ruler div.dots {
+ position: absolute;
+ background-color: rgba(255,255,255,0);
+
+ margin-left: 30px;
+ margin-right: 30px;
+}
+
+div.ruler div.steps {
+ top: 25px;
+ height: 30px;
+}
+
+div.ruler div.dots {
+ top: 58px;
+ height: 25px;
+}
+
+div.ruler div ul {
+ list-style-type: none;
+ margin: 0px;
+ padding: 0px;
+}
+
+div.ruler div ul li {
+ display: inline-block;
+ vertical-align: top;
+}
+
+div.ruler > div.steps > ul > li:first-child,
+div.ruler > div.dots > ul > li:first-child {
+ margin-left: 0px;
+}
+
+div.ruler div.steps_3 ul li {
+ margin-left: 135px;
+}
+
+div.ruler div.steps_4 ul li {
+ margin-left: 67px;
+}
+
+div.ruler div.steps_5 ul li {
+ margin-left: 32px;
+}
+
+div.ruler div.steps_6 ul li {
+ margin-left: 12px;
+}
+
+div.ruler div ul li span {
+ font-weight: bold;
+ text-align: center;
+ width: 70px;
+ display: block;
+ font-size: 8pt;
+ overflow: hidden;
+ color: rgba(0, 0, 0, 0.3);
+}
+
+div.ruler div ul li.selected span {
+ color: black;
+}
+
+div.ruler div.steps ul li span {
+}
+
+div.ruler div.dots ul li span {
+/*
+ text-align: center;
+ width: 26px;
+ margin-left: 22px;
+ margin-right: 22px;
+ height: 25px;
+ background-color: #e57218;
+*/
+ font-size: 40pt;
+ line-height: 47px;
+}
+
+div.ruler div.marker {
+ position: absolute;
+ top: -3px;
+/* left: -246px; */
+}
+div.ruler div.marker div.markerBody {
+ width: 77px;
+ height: 97px;
+ background: url(../images/old/ruler/marker.png) no-repeat;
+}
+
+div.ruler div.marker div.next {
+ position: absolute;
+ top: 25px;
+ left: 76px;
+ width: 27px;
+ height: 65px;
+ background: url(../images/old/ruler/next.png) no-repeat -13px;
+
+ z-index: 26000;
+}
+
+div.ruler div.marker div.next:hover {
+ cursor: pointer;
+ background: url(../images/old/ruler/next.png) no-repeat -2px;
+}
+
+div.ruler div.marker div.disabled {
+ display: none;
+}
+
+div.ruler div.marker div.previous {
+ position: absolute;
+ top: 25px;
+ left: -24px;
+ width: 27px;
+ height: 65px;
+/* background: url(../images/old/ruler/previous.png) no-repeat 13px 1px; */
+ background: url(../images/old/ruler/previous.png) no-repeat 18px 1px;
+
+ z-index: 26000;
+}
+
+div.ruler div.marker div.previous:hover {
+ cursor: pointer;
+/* background: url(../images/old/ruler/previous.png) no-repeat 2px 1px; */
+ background: url(../images/old/ruler/previous.png) no-repeat 7px 1px;
+}
+
+/* @end */
+
+div.createNewCardSplash {
+ margin-top: -450px;
+ margin-left: 250px;
+ width: 354px;
+ float: left;
+ height: 186px;
+
+ text-align: center;
+ background: url(../images/old/main/grid/createNewCardSplash.png) no-repeat;
+}
+
+div.createNewCardSplash:hover {
+ cursor: pointer;
+ background: url(../images/old/main/grid/createNewCardSplash_selected.png) no-repeat;
+}
+
+div.createNewCardSplash span {
+ display: block;
+ padding-top: 130px;
+ font-size: 14pt;
+ color: #9a9586;
+}
+
+div.createNewCardSplash:hover span {
+ color: #605c4e;
+}
+
+
+
+/*=============================================*/
+
+div.NewUserCreation div.tabContainer {
+ min-height: 150px;
+ height: 200px;
+}
+
+div.NewUserCreation div.tabContainer > ul.tabs {
+ display: none;
+}
+
+ul.createUserStates li.creating {
+ background: url(../images/old/creatingUser.gif) no-repeat center center;
+}
+
+ul.createUserStates li {
+ height: 100px;
+}
+
+ul.createUserStates li span {
+ display: block;
+ width: 100%;
+ text-align: center;
+ color: #999;
+ font-style: italic;
+}
+
+div.NewUserCreation form.newUserCreationForm ul.tabPanels {
+ padding-top: 10px;
+}
+
+div.NewUserCreation form.newUserCreationForm ul ul {
+ margin-left: auto;
+ margin-right: auto;
+ width: 400px;
+}
+
+div.NewUserCreation form.newUserCreationForm ul.credentials li {
+ height: 45px;
+}
+
+div.NewUserCreation form.newUserCreationForm ul.credentials span.label {
+ text-align: right;
+ display: inline-block;
+ font-size: 12pt;
+ color: #787872;
+ width: 110px;
+ vertical-align: baseline;
+}
+
+div.NewUserCreation form.newUserCreationForm ul.credentials input {
+ font-size: 13pt;
+ color: #787872;
+ height: 35px;
+ margin-left: 15px;
+ padding-left: 5px;
+}
+
+div.NewUserCreation form.newUserCreationForm ul.termsOfService li {
+ padding: 0 0 15 0;
+}
+
+div.NewUserCreation form.newUserCreationForm ul.termsOfService input {
+ display: inline-block;
+}
+
+div.NewUserCreation form.newUserCreationForm ul.termsOfService .label {
+ display: inline-block;
+ text-align: left;
+ font-size: 12pt;
+ color: #787872;
+ width: 350px;
+ vertical-align: top;
+ padding-left: 10px
+}
+
+div.NewUserCreation form.newUserCreationForm ul.termsOfService a {
+ font-weight: bold;
+ color: #787872;
+ text-decoration: none;
+}
+div.NewUserCreation form.newUserCreationForm ul.termsOfService a:hover {
+ color: #444;
+}
+
+div.NewUserCreation form.newUserCreationForm ul.createUserStates li.done span {
+ font-size: 16pt;
+ color: green;
+}
+
+div.NewUserCreation form.newUserCreationForm ul.createUserStates li.fail span {
+ font-size: 16pt;
+ color: red;
+} \ No newline at end of file
diff --git a/frontend/gamma/css/clipperz/compact.css b/frontend/gamma/css/clipperz/compact.css
new file mode 100644
index 0000000..7c9252a
--- a/dev/null
+++ b/frontend/gamma/css/clipperz/compact.css
@@ -0,0 +1,162 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+/* @override https://www.example.com/css/compact.css */
+
+body.compact div#mainDiv {
+/*
+ width: 250px;
+ height: 95%;
+ border: 1px solid #333366;
+*/
+ padding: 0px;
+}
+
+body.compact div#compactHeader {
+ background-color: #333366;
+}
+
+body.compact div#compactHeader img {
+ padding: 2px 20px 2px 4px;
+ width: 60;
+}
+
+body.compact div#compactHeader a {
+ color: white;
+ text-decoration: none;
+ font-size: 10pt;
+/* position: absolute; */
+ right: 10px;
+ top: 6px;
+}
+
+body.compact div#compactHeader a:hover {
+ color: #ff9400;
+}
+
+body.compact h4 {
+ color: #999999;
+ text-align: center;
+ padding: 20px;
+ font-weight: normal;
+ font-size: 12pt;
+ font-style: italic;
+}
+
+body.compact div.loginPanel form {
+ padding: 10px;
+}
+
+body.compact div.loginPanel dt {
+ color: #aaaaaa;
+ font-size: 10pt;
+}
+
+body.compact div.loginPanel input {
+ width: 180px;
+}
+
+body.compact ul#directLogins {
+ background-image: none;
+ padding: 4px 0px;
+}
+
+body.compact ul#directLogins li {
+ width:auto;
+}
+
+body.compact ul#directLogins li.hover {
+ width:auto;
+ padding-right: 0px;
+}
+
+body.compact div.lockPanel {
+ color: #999999;
+ font-size: 10pt;
+ padding: 10px;
+}
+
+div#compactMiscLinks ul {
+/* text-align: center; */
+ display: block;
+ padding-left: 22px;
+ background-color: #ff9400;
+}
+
+div#compactMiscLinks ul li {
+ display: inline;
+ padding: 2px 5px;
+}
+
+div#compactHeader div#compactMiscLinks ul li a {
+ font-size: 9pt;
+}
+
+div#compactHeader div#compactMiscLinks ul li a:hover {
+ color: #333366;
+}
+
+div#lockBlock {
+ position: absolute;
+ right: 10px;
+ top: 6px;
+}
+
+div#lockBlock input {
+ width: auto;
+ padding-bottom: 2px;
+}
+
+div#lockBlock span {
+ font-size: 9pt;
+ padding: 0px 5px 0px 4px;
+ color: #aaaaaa;
+}
+
+div#lockBlock a#lock {
+ font-size: 9pt;
+}
+
+/* @group Donate */
+
+a#donateHeaderLink {
+ font-weight: bold;
+}
+
+div#compactMiscLinks a#donateHeaderIconLink img#donateHeaderLinkIcon {
+ display: inline;
+ position: absolute;
+ top: 22px;
+ left: 1px;
+ width: 12px;
+ height: 12px;
+}
+
+
+
+/* @end */ \ No newline at end of file
diff --git a/frontend/gamma/css/clipperz/iPhone.css b/frontend/gamma/css/clipperz/iPhone.css
new file mode 100644
index 0000000..a15f22f
--- a/dev/null
+++ b/frontend/gamma/css/clipperz/iPhone.css
@@ -0,0 +1,464 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+/* @override
+ https://www.example.com/iPHONE/css/iPhone.css
+ https://www.example.com/DEVELOPMENT/css/iPhone.css
+ https://www.example.com/WIZARD/css/iPhone.css
+*/
+
+/* ---------------------------------------- */
+
+body {
+ margin: 0;
+ font-family: Helvetica;
+ background: #FFFFFF;
+ color: #000000;
+ overflow-x: hidden;
+ -webkit-user-select: none;
+ -webkit-text-size-adjust: none;
+}
+
+
+div.toolbar {
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ border-bottom: 1px solid #2d3642;
+ border-top: 1px solid #6d84a2;
+ padding: 10px;
+ height: 45px;
+/* background: url(../images/old/iPhone/toolbar.png) #6d84a2 repeat-x; */
+ background: url(data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAArCAIAAAA2QHWOAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAE1JREFUCNddjDEOgEAQAgn//5qltYWFnb1GB4vdSy4WBAYStKyb9+O0FJMYyjMyMWCC35lJM71r6vF1P07/lFSfPx6ZxNLcy1HtihzpA/RWcOj0zlDhAAAAAElFTkSuQmCCCg==) #6d84a2 repeat-x;
+}
+
+div.toolbar h1#pageTitle {
+ overflow: hidden;
+ margin-top: 1px;
+ margin-bottom: 0px;
+ margin-left: auto;
+ margin-right: auto;
+ width: 150px;
+ height: 25px; /* 45px */
+ font-size: 20px;
+ width: 150px;
+ font-weight: bold;
+ text-shadow: rgba(0, 0, 0, 0.4) 0px -1px 0;
+ text-align: center;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ color: #FFFFFF;
+}
+
+div.toolbar a.button {
+ position: absolute;
+ overflow: hidden;
+ top: 8px;
+ right: 6px;
+ margin: 0;
+ border-width: 0 5px;
+ padding: 0 3px;
+ width: auto;
+ height: 30px;
+ line-height: 30px;
+ font-family: inherit;
+ font-size: 12px;
+ font-weight: bold;
+ color: #FFFFFF;
+ text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0;
+ text-overflow: ellipsis;
+ text-decoration: none;
+ white-space: nowrap;
+ background: none;
+/* -webkit-border-image: url(../images/old/iPhone/toolButton.png) 0 5 0 5; */
+}
+
+div.toolbar a#backButton {
+/* display: none; */
+ left: 6px;
+ right: auto;
+ padding: 0px;
+ max-width: 55px;
+ border-width: 0 8px 0 14px;
+/* -webkit-border-image: url(../images/old/iPhone/backButton.png) 0 8 0 14; */
+ -webkit-border-image: url(data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAACsAAAAeCAIAAAA6iHCJAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAtJJREFUeNrEV21P01AYbbtubNExBnXDbYjjZYI4BMdgEANDQoTElw/+Rw0mBs0UiSGaoJFEQEPwjRhFCW/JxrZ2Xdu1fe71bpAhCHzqupPnS5ObPOeec+5zb+lHLxao05HPiwvzr3/++J7N7FFGgaaDLe034+O+wCXyxSKET1u5+Wc98XTK39zeOzjudLmNIoAR2tlaf/Zkqm9gKNI/RBigE9dtb23MJKZj8fvuC16b3WGxsJRxOFfHeQOtH+ZnOI+XRfgEBoLAzz6fjo7ebfD4GYYhMiEdDGRAW6xOt6d7YGzl4xIL/7mgyPL044edkVt19T4EFAJEVQYud+MvOCkHc7MJ3+VrXGOzXrHeZS1s9trjOVj7tiqpONTWBRgD6BVmQFls9iMaSHnx/bu3ffEHgC2gVVqAIojKR3Iw9zLRcjVmtTnA0NydxQDg0IWvq59kYIOeZtWs9gQkagcMcgK/vLjYNXQHcEkas0AcYPdNIPr7Q/0M69B089ofavB5ZVm3OJ2cTwegzAUgxGbSe8tLS52xewjRZGabzAABZt+8mvGHBsiYNF+AAw1cXEBGNUiQqWpAlArM5MSYBXgEOl0NkLcCkxak28MRKbuDMa6KDAwAUnU8HO2Q+N0SJ3OLMCA7V1S9vt7d3tSg5LNV0ACXwOekcGfreVbVVYUqMjOvyPsH71cqkxsZ7NHFJIXBTCMONMAlEryoxAfDucyOmaOpmINyaTowrK23IyDxKbNzUIYoKU3+i37OXpCESvfGCOw11uMMcCkQke4rDlrS1coOSk2VOXftERfKtZsURmLXQUqBVqiUABgrQirc0Xp4Fv4t8kxN8dLkaJQupOVcGnTN0PuQHHlRSG1Eu9tUTLOnxZ5clclsfmK078va7/WN7axomCN2e42Xc/VEIoiiM0KePeM20DTY3M22BZtuhENW1rC/NrI3WVGTmZxSKEr7V4ABAJ+53J1I3nPjAAAAAElFTkSuQmCCCg==) 0 8 0 14;
+}
+
+/* ------------------------------------------- */
+
+body.iPhone form.loginForm {
+ min-height: 372px;
+
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ padding: 10px;
+/* background: #c8c8c8 url(../images/old/iPhone/pinstripes.png); */
+ background: #c8c8c8 url(data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAABCAIAAACdaSOZAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpiPHrmCgMC/GNjYwNSAAEGADdNA3dnzPlQAAAAAElFTkSuQmCCCg==);
+}
+
+fieldset {
+ position: relative;
+ margin: 0 0 20px 0;
+ padding: 0;
+ background: #FFFFFF;
+ -webkit-border-radius: 10px;
+ -moz-border-radius: 10px;
+ border: 1px solid #999999;
+ text-align: right;
+ font-size: 16px;
+}
+
+.row {
+ position: relative;
+ min-height: 42px;
+ border-bottom: 1px solid #999999;
+ -webkit-border-radius: 0;
+ text-align: right;
+}
+
+fieldset > .row:last-child {
+ border-bottom: none !important;
+}
+
+
+.row > input:not(input[type|=radio]):not(input[type|=checkbox]),
+.row > div.fieldValue {
+ width: 100%;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ margin: 0;
+ border: none;
+/* padding: 0px; */
+ padding: 0px 10px 0 112px;
+ height: 42px;
+ background: none;
+ font-size: 16px;
+ font-weight: normal;
+
+ color: #666a60;
+ -webkit-user-select: text;
+}
+
+/*.row > span.fieldValue {*/
+.row > div.fieldValue p {
+/*.row > input.fieldValue {*/
+ margin: 0px;
+ text-align: left;
+ height: 40px;
+ vertical-align: middle;
+ line-height: 40px;
+/* padding: 0px 10px 0 112px; */
+}
+
+/*body[orientation="landscape"] .row > span.fieldValue.password {*/
+body[orientation="landscape"] .row > div.fieldValue.password {
+/*body[orientation="landscape"] .row > input.fieldValue.password {*/
+ padding-right: 120px;
+/* background: url(../images/old/iPhone/password_background.png) no-repeat 105px; */
+ background: url(data:image/png;charset=utf-8;base64,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) no-repeat 105px;
+}
+
+/*.row > span.fieldValue.password {*/
+.row > div.fieldValue.password {
+/*.row > input.fieldValue.password {*/
+ color: rgba(255,255,255,0.5);
+/* background: url(../images/old/iPhone/password_background.png) no-repeat 106px; */
+ background: url(data:image/png;charset=utf-8;base64,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) no-repeat 106px;
+}
+
+.row > div.fieldValue.password.clear {
+ color: #666a60;
+ background: none;
+}
+
+.row > input[type|=radio], .row > input[type|=checkbox] {
+ margin: 7px 7px 0 0;
+ height: 25px;
+ width: 25px;
+}
+
+
+.row > label {
+ position: absolute;
+ margin: 0 0 0 14px;
+ line-height: 42px;
+ font-weight: bold;
+ max-width: 92px;
+ overflow: hidden;
+ white-space: nowrap;
+}
+
+body[orientation="landscape"] .row > label {
+ max-width: 150px;
+}
+
+body[orientation="landscape"] .row > input:not(input[type|=radio]):not(input[type|=checkbox]) {
+ padding-left: 140px;
+}
+
+.row > img.favicon {
+ position: absolute;
+ width: 20px;
+ height: 20px;
+ top: 12px;
+ left: 11px;
+}
+
+.row > span {
+ padding: 8px 13px;
+ text-align: left;
+ display: block;
+ color: #666a60;
+ font-size: 10pt;
+}
+
+.row.notes {
+ -webkit-user-select: text;
+}
+
+/* ------------------------------------------- */
+
+.whiteButton {
+ margin-left: auto;
+ margin-right: auto;
+ width: 150px;
+ display: block;
+ border-width: 0 12px;
+ padding: 10px;
+ text-align: center;
+ font-size: 20px;
+ font-weight: bold;
+ text-decoration: inherit;
+ color: inherit;
+
+/* -webkit-border-image: url(../images/old/iPhone/whiteButton.png) 0 12 0 12; */
+ -webkit-border-image: url(data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAuCAQAAAB+dNqHAAAACXBIWXMAAABIAAAASABGyWs+AAAACXZwQWcAAAAdAAAALgChnaVgAAAAAmJLR0QA/4ePzL8AAANhSURBVEjHnZZNaFxVFMd/5747mclMkpmxzYdJtFaJglgFpYSiBAVX7l0UUZGuSkEEu3PtSulCUXFdxYXL7kQQIWD9CsRIqdomGGOaSdJmZjKTeW/eu/e4mKRmrE3n5X83j/ve7/3POfe+d67QrTxP8QLDnMTenkv4kQ2+YZ6d/Y/Kvut+XuZVKtygzVbXC8v0cT+jXORLWneix/mAZZZwKIrSbSAIAcd5kDdZ6kaf4zzfEeLPnHrr+UeOWpMJ9rjYxe7a5ntff/YThhyneJ/Zf9Ep3uEXkhNjX50bHoiStoPE76HWiPQFfcGN+kufLKxheZJ3+aOD5vmIBaLXpz89HSVhzF2Uy2TtGxe/+JksJzjHjgCvMEHz6cnZt7dD5zlAgSlkZy7MrVDgbz43FJimhV46W2vFzutBI3aN8NJZlBbTFAKepZ/o/IszU1Gs95Tz2Uw1nFuiiTE8Rhs9fbIROt/LaISvTaO0mbIM0kTKeefoUSMDCI6SxRCT9d77XlFrCYgQi0PH72vH9CyNMSjO4tGM9do76hXB4y2KU+c8aaR41KJ4SIn6DgqgPq2rggWc+kMEjBUBVDUNKQBiOx+218Pl6tVr+jJhUZx4PYSr4XBSsAKaJH9tpirT7uIoTj3pAna43TJJWtSjYDpxp5bv5OpTb4mOq3IIX0W14ypeUq+rYBH5T9fqbRerWMClrbB4PBgUjZPUuXrUGBW51Yhc71y9LSJi1NgQxVWj3a7aw2gmONSGJtNAxC9v9+56vaoe6aubXEWy4meXe/+VXl42TvqzG4ZFCkRzv/+w3lu436/PX6NNnsUgCctjUUJwnWdGC/ZenpXw47loTRrldu3XwLkSrQmiHbkSP3FkwB4MXpjfWDE3JTfw29ZGAGHjgWJdcDW9XC/0PVS4W47fVj5cuLUmFWlOVlevei8ApVLp8bWclnWU4khpZvTRwaw5VggEINHlZuSv1mcr6zW2ZF22xqLqlWr19uYdGSkeWyn4IY5okX61GBHMrp1HJaYldW4G9Ylm7c/19a4jV6k0+fBmtjbkCwxoDovdQ0lIpEXTNIrbR6OVxWr1joNeJjM+Xhyu2+0+Z6Ocmt17Kj4bBvFgPJTUNlZX4/j/zohAJlMuF4vW5vP7Z3d2kqRW29qKuxr4P1RbNFwZtqq8AAAAAElFTkSuQmCCCg==) 0 12 0 12;
+ text-shadow: rgba(255, 255, 255, 0.7) 0 1px 0;
+}
+
+/* ------------------------------------------- */
+
+body.iPhone .loginProgressPanel {
+ min-height: 372px;
+
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ padding: 10px;
+/* background: #c8c8c8 url(../images/old/iPhone/pinstripes.png); */
+ background: #c8c8c8 url(data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAABCAIAAACdaSOZAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpiPHrmCgMC/GNjYwNSAAEGADdNA3dnzPlQAAAAAElFTkSuQmCCCg==);
+}
+
+body.iPhone .loadingBar {
+ margin-left: auto;
+ margin-right: auto;
+ margin-top: 60px;
+}
+
+div.loadingBar {
+ height: 22px;
+ width: 214px;
+/* background: url(../images/old/loading/loadingBar.gif) no-repeat center; */
+ background: url(data:image/gif;charset=utf-8;base64,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) no-repeat center;
+}
+
+div.loadingBar div.loadingBarProgress {
+ height: 100%;
+ width: 0%;
+}
+
+div.loadingBar div.loadingBarProgress div.loadingBarProgress_left {
+ height: 100%;
+ max-width: 8px;
+/* background: url(../images/old/loading/loadingBarProgress.png) no-repeat 0; */
+ background: url(data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAANYAAAAWCAYAAAC8C2KaAAAACXBIWXMAAAsSAAALEgHS3X78AAACIklEQVR4Ae3brU7DUBQH8HO6PQAazx4BRUKDwfChQTGFQ4wRFGEERdgQONRQoGEzGFISFI8w/DQSWHsP565r0xY2BiWY/ivW+530l52cdr0jwgEBCPy5AE9aUc7XV0kcl4jniGR20lj0QaAYAtzXWHgmNh7v3HTGXfOXgSWnKy6VqEZMCKZxcmiHgFCfAjrjva6XxfgUWNJc3tVBG9mBqEMAAmMFrrl+10r2pgJLTpYO9dZvNTkAZQhAYAoBNh3evz+KRsaBJccLevtXakYdOEMAAj8UCII6Hzx6dlY5nipBjXwTV1GAAAR+KiA1neHZWcOMJY35FS03bAMOCEAgl0CDG0/dMGP5by6xk2s1TIYABFRAjKufo8AyfoUkftyCDwQg8FsBloqdGmaswMf7qt9CYh4E0gLDWBrdCg7SXahBAAK5BEYZa9AnZmStXJSYDAEVENEtT/GtYNAjxl5AfDEgkFtAuGfXCDPW4N0jh9zci2IBCBRdwCTeY1kL2Z65RdYq+rcC159LQLjPFy9rdo0wY9nS+2uLSk5qI6FtxgEBCEwpEJg4flIvr2SrfEgOYxPulI4YBoFYwEiHL/2jqJ4KLNuowVXT4NqMBuAMAQh8I2DkSoPqLDnqU2DZTqmWF4mcXTxzJalQhkBGQJ+piEyL2/5DpifchJttjOpSLenmXMfVvboVBFmkgnOhBYbBJPqTuv41vx10C22Bi4fAfwt8AJe2flCLvH1PAAAAAElFTkSuQmCCCg==) no-repeat 0;
+}
+
+div.loadingBar div.loadingBarProgress div.loadingBarProgress_right {
+ position: relative;
+ height: 100%;
+ margin-left: 8px;
+/* background: url(../images/old/loading/loadingBarProgress.png) no-repeat right; */
+ background: url(data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAANYAAAAWCAYAAAC8C2KaAAAACXBIWXMAAAsSAAALEgHS3X78AAACIklEQVR4Ae3brU7DUBQH8HO6PQAazx4BRUKDwfChQTGFQ4wRFGEERdgQONRQoGEzGFISFI8w/DQSWHsP565r0xY2BiWY/ivW+530l52cdr0jwgEBCPy5AE9aUc7XV0kcl4jniGR20lj0QaAYAtzXWHgmNh7v3HTGXfOXgSWnKy6VqEZMCKZxcmiHgFCfAjrjva6XxfgUWNJc3tVBG9mBqEMAAmMFrrl+10r2pgJLTpYO9dZvNTkAZQhAYAoBNh3evz+KRsaBJccLevtXakYdOEMAAj8UCII6Hzx6dlY5nipBjXwTV1GAAAR+KiA1neHZWcOMJY35FS03bAMOCEAgl0CDG0/dMGP5by6xk2s1TIYABFRAjKufo8AyfoUkftyCDwQg8FsBloqdGmaswMf7qt9CYh4E0gLDWBrdCg7SXahBAAK5BEYZa9AnZmStXJSYDAEVENEtT/GtYNAjxl5AfDEgkFtAuGfXCDPW4N0jh9zci2IBCBRdwCTeY1kL2Z65RdYq+rcC159LQLjPFy9rdo0wY9nS+2uLSk5qI6FtxgEBCEwpEJg4flIvr2SrfEgOYxPulI4YBoFYwEiHL/2jqJ4KLNuowVXT4NqMBuAMAQh8I2DkSoPqLDnqU2DZTqmWF4mcXTxzJalQhkBGQJ+piEyL2/5DpifchJttjOpSLenmXMfVvboVBFmkgnOhBYbBJPqTuv41vx10C22Bi4fAfwt8AJe2flCLvH1PAAAAAElFTkSuQmCCCg==) no-repeat right;
+ top: -22px;
+}
+
+/* ------------------------------------------- */
+
+body.iPhone .loginErrorPanel {
+ position: absolute;
+ min-height: 372px;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ padding: 10px;
+/* background: #c8c8c8 url(../images/old/iPhone/pinstripes.png); */
+ background: #c8c8c8 url(data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAABCAIAAACdaSOZAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpiPHrmCgMC/GNjYwNSAAEGADdNA3dnzPlQAAAAAElFTkSuQmCCCg==);
+}
+
+body.iPhone .loginErrorPanel h2 {
+ text-align: center;
+ color: red;
+ margin-top: 40px;
+}
+
+/* ------------------------------------------- */
+
+
+
+
+
+
+
+
+form.cardListSearchForm {
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ border-bottom: 1px solid #2d3642;
+ border-top: 1px solid #6d84a2;
+ padding: 6px;
+ height: 45px;
+/* background: url(../images/old/iPhone/toolbar.png) #6d84a2 repeat-x; */
+ background: url(data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAArCAIAAAA2QHWOAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAE1JREFUCNddjDEOgEAQAgn//5qltYWFnb1GB4vdSy4WBAYStKyb9+O0FJMYyjMyMWCC35lJM71r6vF1P07/lFSfPx6ZxNLcy1HtihzpA/RWcOj0zlDhAAAAAElFTkSuQmCCCg==) #6d84a2 repeat-x;
+ margin: 0px;
+}
+
+form.cardListSearchForm input {
+ margin: 7px;
+ -webkit-appearance: searchfield;
+ width: 200px;
+}
+
+ul.cardListPanel {
+ margin: 0px;
+ padding: 0px;
+ list-style-type: none;
+ min-height: 372px;
+}
+
+li.cardListItem {
+ height: 43px;
+ border-bottom: 1px solid #cccccc;
+/* background: url(../images/old/iPhone/listArrow.png) no-repeat right center; */
+ background: url(data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAUCAYAAAB4d5a9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAKVJREFUeNpi/P//PwOtARMDHcDwsYQFRJSXl8P4dVC6CZvizs5O8i1BsqARid9Ei+BiQ2KDLKumhSU1QNyKxG+hlkXoEQ+yqAPNogpapK5KNIvaKbUIVxKeAsTvkPg5QCxETUukgfgAkqFPgdgBzVKKLIFZoIJmwR1qBRdNLEC2BJQpV9LCAmRL/gBxAtRwqlqAXqzcgRrOQE0LQIBxtNIiBQAEGAA7xCa2yF9zEgAAAABJRU5ErkJgggo=) no-repeat right center;
+
+}
+
+li.cardListItem a {
+ position: relative;
+ top: -22px;
+ left: 40px;
+ display: block;
+ white-space: nowrap;
+ overflow: hidden;
+}
+
+body[orientation="portrait"] li.cardListItem a {
+ max-width: 250px;
+}
+
+body[orientation="landscape"] li.cardListItem a {
+ max-width: 400px;
+}
+
+li.cardListItem img {
+ height: 20px;
+ width: 20px;
+ padding: 12px 10px 0px 10px;
+}
+
+li.cardListItem a {
+ text-decoration: none;
+ color: black;
+ font-weight: bold;
+ font-size: 14pt;
+ vertical-align: 3px;
+}
+
+
+div.cardDetailPanel {
+ position: absolute;
+ top: 45px;
+ min-height: 372px;
+
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ padding: 10px;
+/* background: #c8c8c8 url(../images/old/iPhone/pinstripes.png); */
+ background: #c8c8c8 url(data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAABCAIAAACdaSOZAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABdJREFUeNpiPHrmCgMC/GNjYwNSAAEGADdNA3dnzPlQAAAAAElFTkSuQmCCCg==);
+}
+
+/*div.cardDetailPanel > fieldset > div.row > input.directLogin {*/
+div.cardDetailPanel > fieldset > div.row > span.directLogin {
+ width: 100%;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ margin: 0;
+ border: none;
+ padding: 12px 10px 0 110px;
+ height: 42px;
+ background: none;
+ font-size: 16px;
+ font-weight: normal;
+
+ padding-left: 40px;
+ color: black;
+/* background: url(../images/old/iPhone/listArrow.png) no-repeat right center; */
+ background: url(data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAUCAYAAAB4d5a9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAKVJREFUeNpi/P//PwOtARMDHcDwsYQFRJSXl8P4dVC6CZvizs5O8i1BsqARid9Ei+BiQ2KDLKumhSU1QNyKxG+hlkXoEQ+yqAPNogpapK5KNIvaKbUIVxKeAsTvkPg5QCxETUukgfgAkqFPgdgBzVKKLIFZoIJmwR1qBRdNLEC2BJQpV9LCAmRL/gBxAtRwqlqAXqzcgRrOQE0LQIBxtNIiBQAEGAA7xCa2yF9zEgAAAABJRU5ErkJgggo=) no-repeat right center;
+}
+
+/*body[orientation="landscape"] div.cardDetailPanel > fieldset > div.row > input.directLogin { */
+body[orientation="landscape"] div.cardDetailPanel > fieldset > div.row > span.directLogin {
+ padding-left: 50px;
+}
+
+div.cardDetailPanel h2 {
+ margin: 0 0 8px 14px;
+ font-size: inherit;
+ font-weight: bold;
+ color: #4d4d70;
+ text-shadow: rgba(255, 255, 255, 0.75) 1px 1px 0;
+}
+
+
+
+
+/* body[orientation="portrait"] div.cardList { */
+body[orientation="portrait"] > * {
+ width: 320px;
+}
+
+/* body[orientation="landscape"] div.cardList { */
+body[orientation="landscape"] > * {
+ width: 480px;
+}
diff --git a/frontend/gamma/css/clipperz/ie.css b/frontend/gamma/css/clipperz/ie.css
new file mode 100644
index 0000000..5148ada
--- a/dev/null
+++ b/frontend/gamma/css/clipperz/ie.css
@@ -0,0 +1,356 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+<!--[if IE]>
+
+<style>
+
+{
+ background-color: white;
+}
+
+div#logoFrame {
+ height: 44px;
+}
+
+div#logo {
+/* padding-left: 15px; */
+ background: url(../images/old/logo_blue.png);
+}
+
+div.clipperzLoginForm div.loginForm form {
+ padding-left: 20px;
+}
+
+div.clipperzLoginForm div.registrationForm form {
+ padding-left: 20px;
+}
+
+div#newRecordInnerPanel {
+ width: 350px;
+ height: 160px;
+ background: url(../images/old/newRecordPanelBackground.png) no-repeat 0 -165px;
+/* background: url(data:image/png;charset=utf-8;base64,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) no-repeat 0 -165px; */
+}
+
+img#donateHeaderIcon {
+ padding-top: 0px;
+ margin-bottom: 0px;
+}
+
+/* ========================================================== */
+
+div#applicationVersionType {
+ position: absolute;
+}
+
+div#applicationVersionType.readOnly {
+ background: url(../images/old/read-only.png) no-repeat fixed -5px -8px;
+}
+
+div#applicationVersionType.TEST {
+ background: url(../images/old/test-database.png) no-repeat fixed -5px -8px;
+}
+
+div#mainTabs {
+ background: #ff9400 url(../images/old/menubarSprite.gif) repeat-x;
+}
+
+div#menus {
+ background: url(../images/old/menubarSprite.gif) no-repeat right -26px;
+}
+
+div#menus table {
+ background: url(../images/old/menubarSprite.gif) no-repeat 0 -52px;
+}
+
+div#menus table tbody tr td div {
+ background: url(../images/old/menubarSprite.gif) no-repeat right -52px;
+}
+
+div#menus table tbody tr td div a {
+ background: url(../images/old/menubarSprite.gif) no-repeat left -26px;
+}
+
+div#menus table tbody tr td.selectedTab {
+ background: url(../images/old/menubarSprite.gif) repeat-x right -78px;
+}
+
+div#menus table tbody tr td.selectedTab div {
+ background: url(../images/old/menubarSprite.gif) no-repeat right -130px;
+}
+
+div#menus table tbody tr td.selectedTab div a {
+ background: url(../images/old/menubarSprite.gif) no-repeat left -104px;
+}
+
+div.clipperzLoginForm div.loginFormHeaderBox {
+ background: url(../images/old/loginFormBox.png) no-repeat -3px top;
+}
+
+div.clipperzLoginForm div.loginForm {
+ background: url(../images/old/loginFormBox.png) repeat-y -408px;
+}
+
+div.loginForm div.loginFormFooterBox {
+ background: url(../images/old/loginFormBox.png) no-repeat -813px bottom;
+}
+
+div.clipperzLoginForm div.registrationForm {
+ background: url(../images/old/loginFormBox.png) repeat-y -408px;
+}
+
+div.clipperzLoginForm form.read-only table.formLayout, div.panelform.read-only table.panelBody, div.clipperzSubPanel span.read-only, div.read-only {
+ background-image: url(../images/old/read-only_background.png);
+}
+
+div.registrationForm div.loginFormFooterBox {
+ background: url(../images/old/loginFormBox.png) no-repeat -813px bottom;
+}
+
+div.loginPanelSwitchLanguageBox {
+ background: url(../images/old/languageBox.png) no-repeat 19px -15px;
+}
+
+div#directLoginsBlock {
+ background: url(../images/old/directLoginBox.png) repeat-y -262px bottom;
+}
+
+div#directLoginsBlock div.directLoginsBlockHeaderBox {
+ background: url(../images/old/directLoginBox.png) no-repeat -11px -13px;
+}
+
+ul#directLogins {
+ background: url(../images/old/directLoginBox.png) no-repeat -513px bottom;
+}
+
+div#directLoginsDescription {
+ background: url(../images/old/directLoginBox.png) no-repeat -513px bottom;
+}
+
+/*
+div#recordListFilterHeader {
+ background: url(../images/old/cardFiltersSprite.gif) repeat-x 0 -114px;
+}
+
+div#recordFiltersTableWrapper {
+ background: url(../images/old/cardFiltersSprite.gif) no-repeat left -38px;
+}
+
+div#recordFiltersDIV table {
+ background: url(../images/old/cardFiltersSprite.gif) no-repeat right -19px;
+}
+
+div#recordFiltersDIV table tbody tr td div {
+ background: url(../images/old/cardFiltersSprite.gif) no-repeat right -38px;
+}
+
+div#recordFiltersDIV table tbody tr td div a {
+ background: url(../images/old/cardFiltersSprite.gif) no-repeat left -19px;
+}
+
+div#recordFiltersDIV table tbody tr td.selectedTab {
+ background: url(../images/old/cardFiltersSprite.gif) repeat-x -57px;
+}
+
+div#recordFiltersDIV table tbody tr td.selectedTab div {
+ background: url(../images/old/cardFiltersSprite.gif) no-repeat right -95px;
+}
+
+div#recordFiltersDIV table tbody tr td.selectedTab div a {
+ background: url(../images/old/cardFiltersSprite.gif) no-repeat left -76px;
+}
+*/
+
+div#recordFiltersSearchInnerPanel {
+ background: url(../images/old/recordFilterBackground.png) no-repeat -10px -138px;
+}
+
+table#recordListAndDetailBlockTABLE {
+ background: url(../images/old/cardBlockLowerBorder.gif) repeat-x 0 bottom;
+}
+
+div#recordListBlockHeader table.recordListBlockHeaderTABLE {
+ background: url(../images/old/cardsBlockRoundCorners.gif) no-repeat right -51px;
+}
+
+div#recordListBlockHeader table.recordListBlockHeaderTABLE tbody tr td.recordBlockTitleTD {
+ background: url(../images/old/cardsBlockRoundCorners.gif) no-repeat left 0px;
+}
+
+td#cardBoxLowerLeftTD {
+ background: url(../images/old/cardBlockLowerRoundedCorner.gif) no-repeat left -32px;
+}
+
+td#cardBoxLowerRightTD {
+ background: url(../images/old/cardBlockLowerRoundedCorner.gif) no-repeat right -82px;
+}
+
+div#newRecordInnerPanel {
+ background: url(../images/old/newRecordPanelBackground.png) no-repeat 0 -165px;
+}
+
+.resizable-textarea .grippie {
+ background: #eee url(../images/old/grippie.png) no-repeat center 1px;
+}
+
+div.Clipperz_recordFieldData div.passwordBackground, div.passwordEntropy {
+ background: url(../images/old/entropyBackground.gif) repeat-x 0 0;
+}
+
+div.Clipperz_recordFieldData input.scrambledField {
+ background: transparent url(../images/old/scrambledValue.png) no-repeat 0 0px;
+}
+
+div.Clipperz_recordFieldData input.scrambledField:focus {
+ background: transparent url(../images/old/scrambledValue.png) no-repeat 0 -16px;
+}
+
+div.directLoginCollapseLink {
+ background: url(../images/old/directLogin/toggle.png) no-repeat;
+}
+
+#mb-dlg .ext-mb-progress {
+ background:transparent url(../images/old/default/basic-dialog/progress2.gif) repeat-x 1px 1px;
+}
+
+.ydlg .ydlg-hd {
+ background: url(../images/old/clipperz/basic-dialog/hd-sprite.gif) repeat-x 0 -82px;
+}
+.ydlg .ydlg-hd-left {
+ background: url(../images/old/clipperz/basic-dialog/hd-sprite.gif) no-repeat 0 -41px;
+}
+.ydlg .ydlg-hd-right {
+ background: url(../images/old/clipperz/basic-dialog/hd-sprite.gif) no-repeat right 0;
+}
+
+.ydlg .ydlg-close {
+ background-image:url(../images/old/clipperz/basic-dialog/close.gif);
+}
+
+body .ybtn-left{
+ background:url(../images/old/default/basic-dialog/btn-sprite.gif) no-repeat 0 0;
+}
+body .ybtn-right{
+ background:url(../images/old/default/basic-dialog/btn-sprite.gif) no-repeat 0 -21px;
+}
+body .ybtn-center{
+ background:url(../images/old/default/basic-dialog/btn-sprite.gif) repeat-x 0 -42px;
+}
+
+
+
+
+div.Clipperz_PasswordGenerator_button {
+ background: url(../images/old/passwordAssistant.png) 0 22px;
+}
+
+div.Clipperz_PasswordGenerator_button.hover {
+ background: url(../images/old/passwordAssistant.png) 0 -1px;
+}
+
+body ul.radioList li h4 {
+ cursor: auto;
+}
+
+/* ========================================================== */
+
+</style>
+
+<![endif]-->
+
+
+
+<!--[if lt IE 7]>
+
+<style>
+
+div#newRecordPanel {
+ position: absolute;
+ margin-left: 0px;
+ width: 350px;
+ height: 160px;
+}
+
+div#newRecordInnerPanel {
+ width: 350px;
+ height: 160px;
+ background: url(../images/old/newRecordPanelBackground.gif) no-repeat 0 -165px;
+/* background: url(data:image/gif;charset=utf-8;base64,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) no-repeat 0 -165px; */
+}
+
+div.newRecordInnerInnerPanel {
+ background-color: white;
+ padding: 0px;
+ margin-left: 15px;
+ margin-right: 15px;
+}
+
+div#newRecordPanel table td.newRecordPanelLabelTD {
+ padding-left: 0px;
+ padding-top: 3px;
+ font-size: 9pt;
+ width: 100px;
+}
+
+div#readOnlyBanner {
+ background: url(../images/old/read-only.gif) no-repeat fixed -5px -8px;
+/* background: url(data:image/gif;charset=utf-8;base64,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) no-repeat fixed -5px -8px; */
+}
+
+
+
+ul#directLogins {
+ height: 200px;
+}
+
+div#recordListBlock {
+ height: 200px;
+}
+
+div.clipperzSubPanel {
+ height: 200px;
+}
+
+
+
+div.Clipperz_recordFieldData input.scrambledField {
+ background: transparent url(../images/old/scrambledValue.gif) no-repeat 0 0px;
+/* background: transparent url(data:image/gif;charset=utf-8;base64,R0lGODlhRwAgANUmAP///7XV/2ZmZqW/4ODg4HBwcGttcJChuLi4uHZ8hYWFhfX19bDO9YCLmZmZmaOjo4aSo6C31tbW1q2trXuEj4uarY+Pj+vr66rG68LCwpWpwnp6eszMzHF1epuwzMTd/7rY/9Pm/8ng/7/b/87j/9jp/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACYALAAAAABHACAAAAb/QIBwSCwaj8ikcslsOp/QqHRKRV4QkmQGkbxmkVtlGGkyLSUCLtIiSKLVR7ZSTjYfLwvAW0gY9gF0eEKCewB/hkKBeXyJbQCCRGVIDgIOE5UPBQV8AhsTCmmgapSWmJqcnqKiqJ+haUJlsbFFCKACt50TeQSZuLcOHEK1vrm7vb7AfMe4yQCyskcEBbcZRw+3CotE0tTW2NpE1wLZRtBI19fk25qU1UXo4+CG7ALu6wXt5bNHHAIWAAgEPCgCSsICTYcA9PsXcCCRggcLJAQAEWEkO5KMcNhwIREcAAssCZGgIOHGjoA+hpwwsiSRlS0TZsxYpabNmzhz6tzJs6fP/wBAgwodSrSo0aNIkypdyrSp06dQo0o1iuFAhKMaDhytetVoVqRfjZZJGkGAVqMUBBwte7ZoWqRvxZqgyiAAW6ADguYNEBdD3QB+7ZrFqxdo378B9h4G+gHo2AAjQAhtIKBBhcoQDBjAK6BDhQRmQZ+lbBmzZs6eRYtG/Tn04A/PYpUQegC0L891B2Qm1sAD0NrEcCfe7as3XuK4jMOObYIE0QEGbmkoCuFWAsR6owuYTrS6gOvUrWN3HEty+OrghUI3QJm70Orox69v/1wzfaHLy4Qo6kEAhQAHCADBUKBFwIBmewHV338BDihUgQcakCBQECIoVBkigFBGY0N50DIBBoa1FQADlgEVQQITeggiXyKSWIGJKArlIowJajhXABtOpeOOPPbo449ABinkkAEEAQA7Cg==) no-repeat 0 0px; */
+}
+
+div.Clipperz_recordFieldData input.scrambledField:focus {
+ background: transparent url(../images/old/scrambledValue.gif) no-repeat 0 -14px;
+/* background: transparent url(data:image/gif;charset=utf-8;base64,R0lGODlhRwAgANUmAP///7XV/2ZmZqW/4ODg4HBwcGttcJChuLi4uHZ8hYWFhfX19bDO9YCLmZmZmaOjo4aSo6C31tbW1q2trXuEj4uarY+Pj+vr66rG68LCwpWpwnp6eszMzHF1epuwzMTd/7rY/9Pm/8ng/7/b/87j/9jp/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAACYALAAAAABHACAAAAb/QIBwSCwaj8ikcslsOp/QqHRKRV4QkmQGkbxmkVtlGGkyLSUCLtIiSKLVR7ZSTjYfLwvAW0gY9gF0eEKCewB/hkKBeXyJbQCCRGVIDgIOE5UPBQV8AhsTCmmgapSWmJqcnqKiqJ+haUJlsbFFCKACt50TeQSZuLcOHEK1vrm7vb7AfMe4yQCyskcEBbcZRw+3CotE0tTW2NpE1wLZRtBI19fk25qU1UXo4+CG7ALu6wXt5bNHHAIWAAgEPCgCSsICTYcA9PsXcCCRggcLJAQAEWEkO5KMcNhwIREcAAssCZGgIOHGjoA+hpwwsiSRlS0TZsxYpabNmzhz6tzJs6fP/wBAgwodSrSo0aNIkypdyrSp06dQo0o1iuFAhKMaDhytetVoVqRfjZZJGkGAVqMUBBwte7ZoWqRvxZqgyiAAW6ADguYNEBdD3QB+7ZrFqxdo378B9h4G+gHo2AAjQAhtIKBBhcoQDBjAK6BDhQRmQZ+lbBmzZs6eRYtG/Tn04A/PYpUQegC0L891B2Qm1sAD0NrEcCfe7as3XuK4jMOObYIE0QEGbmkoCuFWAsR6owuYTrS6gOvUrWN3HEty+OrghUI3QJm70Orox69v/1wzfaHLy4Qo6kEAhQAHCADBUKBFwIBmewHV338BDihUgQcakCBQECIoVBkigFBGY0N50DIBBoa1FQADlgEVQQITeggiXyKSWIGJKArlIowJajhXABtOpeOOPPbo449ABinkkAEEAQA7Cg==) no-repeat 0 -14px; */
+}
+
+
+
+</style>
+
+<![endif]-->
diff --git a/frontend/gamma/graphics/CoverActions.opacity b/frontend/gamma/graphics/CoverActions.opacity
new file mode 100644
index 0000000..58028fd
--- a/dev/null
+++ b/frontend/gamma/graphics/CoverActions.opacity
Binary files differ
diff --git a/frontend/gamma/graphics/Features.opacity b/frontend/gamma/graphics/Features.opacity
new file mode 100644
index 0000000..8824506
--- a/dev/null
+++ b/frontend/gamma/graphics/Features.opacity
Binary files differ
diff --git a/frontend/gamma/graphics/GridSorting.opacity b/frontend/gamma/graphics/GridSorting.opacity
new file mode 100644
index 0000000..0d6c784
--- a/dev/null
+++ b/frontend/gamma/graphics/GridSorting.opacity
Binary files differ
diff --git a/frontend/gamma/graphics/Logo.opacity b/frontend/gamma/graphics/Logo.opacity
new file mode 100644
index 0000000..a4dbfc8
--- a/dev/null
+++ b/frontend/gamma/graphics/Logo.opacity
Binary files differ
diff --git a/frontend/gamma/graphics/Marks.opacity b/frontend/gamma/graphics/Marks.opacity
new file mode 100644
index 0000000..4aef025
--- a/dev/null
+++ b/frontend/gamma/graphics/Marks.opacity
Binary files differ
diff --git a/frontend/gamma/graphics/RegisterButton.opacity b/frontend/gamma/graphics/RegisterButton.opacity
new file mode 100644
index 0000000..d57920b
--- a/dev/null
+++ b/frontend/gamma/graphics/RegisterButton.opacity
Binary files differ
diff --git a/frontend/gamma/graphics/Star.opacity b/frontend/gamma/graphics/Star.opacity
new file mode 100644
index 0000000..84335a7
--- a/dev/null
+++ b/frontend/gamma/graphics/Star.opacity
Binary files differ
diff --git a/frontend/gamma/graphics/Tips.opacity b/frontend/gamma/graphics/Tips.opacity
new file mode 100644
index 0000000..56492c6
--- a/dev/null
+++ b/frontend/gamma/graphics/Tips.opacity
Binary files differ
diff --git a/frontend/gamma/html/exitPage_template.html b/frontend/gamma/html/exitPage_template.html
new file mode 100644
index 0000000..7056320
--- a/dev/null
+++ b/frontend/gamma/html/exitPage_template.html
@@ -0,0 +1,140 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>clipperz</title>
+ <link rel="stylesheet" type="text/css" href="./static.css" />
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+</head>
+<body>
+
+<!-- h1>clipper<span class="logo_z">z</span></h1 -->
+<div class="header">
+ <div id="logo"></div>
+ <h5 class="clipperzPayoff">keep it to yourself!</h5>
+</div>
+
+
+<div class="contentWrapper">
+ <div class="block1">
+ <div class="languageBlock en-us">
+ <div class="flags"></div>
+ <div class="content">
+ <h3>Goodbye! Thanks for using Clipperz.</h3>
+
+ <p>You just logged out from your Clipperz account. We hope to see you again soon!</p>
+ </div>
+ </div>
+
+
+ <div class="languageBlock zh-cn">
+ <div class="flags"></div>
+ <div class="content">
+ <h3>下次再见!感谢您使用 Clipperz。</h3>
+
+ <p>您仅仅是从您的 Clipperz 账户登出,我们希望很快再次见到您!</p>
+ </div>
+ </div>
+
+
+ <!--
+ <div class="languageBlock fr-fr">
+ <div class="flags"></div>
+ <div class="content">
+ <h3></h3>
+
+ <p></p>
+ </div>
+ </div>
+ -->
+
+
+ <div class="languageBlock it-it">
+ <div class="flags"></div>
+ <div class="content">
+ <h3>Arrivederci! Grazie per aver scelto Clipperz.</h3>
+
+ <p>Sei uscito da Clipperz. Speriamo di rivederti presto.</p>
+ </div>
+ </div>
+
+
+ <div class="languageBlock ja-jp">
+ <div class="flags"></div>
+ <div class="content">
+ <h3>Clipperz をご利用いただきありがとうございました。</h3>
+
+ <p>Clipperz から正常にログアウトしました。またのご利用をお待ちしています。</p>
+ </div>
+ </div>
+ </div>
+
+ <div class="block2">
+ <div class="languageBlock pt-br">
+ <div class="flags"></div>
+ <div class="content">
+ <h3>Até logo! Obrigado por utilizar Clipperz.</h3>
+
+ <p>Você acaba de sair de sua conta Clipperz. Esperamos ve-lo de volta em breve!</p>
+ </div>
+ </div>
+
+
+ <div class="languageBlock es-es">
+ <div class="flags"></div>
+ <div class="content">
+ <h3>¡Hasta luego! Gracias por usar Clipperz</h3>
+
+ <p>Se acaba cerrar su sesión Clipperz. ¡Esperamos verlo nuevamente pronto!</p>
+ </div>
+ </div>
+
+ <div class="languageBlock ru-ru">
+ <div class="flags"></div>
+ <div class="content">
+ <h3>До свидания! Спасибо за использование Clipperz.</h3>
+
+ <p>Вы только что вышли из своего аккаунта Clipperz. Мы надеемся увидеть Вас снова!</p>
+ </div>
+ </div>
+
+ <div class="languageBlock de-de">
+ <div class="flags"></div>
+ <div class="content">
+ <h3>Auf Wiedersehen! Danke, dass Sie Clipperz verwendet haben.</h3>
+
+ <p>Sie haben sich gerade von Ihrem Clipperz-Account abgemeldet. Wir hoffen, Sie bald wieder zu sehen.</p>
+ </div>
+ </div>
+
+ </div>
+</div>
+
+</body>
+</html>
diff --git a/frontend/gamma/html/index_template.html b/frontend/gamma/html/index_template.html
new file mode 100644
index 0000000..8cf838c
--- a/dev/null
+++ b/frontend/gamma/html/index_template.html
@@ -0,0 +1,62 @@
+<html>
+<head>
+ <title>@page.title@</title>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<!--
+@copyright@
+-->
+
+@css@
+
+ <link rel="shortcut icon" href="./clipperz.ico" />
+
+ <meta name="description" content="Login to your web accounts with just one click. Never type a password again! Use multiple complex passwords and forget them. A password manager that enhances your online security." />
+ <meta name="keywords" content="password manager,gestor de contraseñas,gerenciador de senhas,Kennwortmanager,passwords,security,privacy,cryptography" />
+<script>
+ Clipperz_IEisBroken = false;
+ Clipperz_normalizedNewLine = '\n';
+ Clipperz_dumpUrl = "/dump/";
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+Clipperz_normalizedNewLine = '\x0d\x0a';
+</script><![endif]-->
+
+@js_DEBUG@
+
+</head>
+<body>
+<div id="mainDiv">
+ <div id="loading">
+ <a href="http://www.clipperz.com" target="_blank"><div id="logo"></div></a>
+ <h5 class="clipperzPayoff">keep it to yourself!</h5>
+ <h2>loading ...</h2>
+ </div>
+
+@js_INSTALL@
+
+</div>
+<div id="applicationVersionType" class="@application.version.type@"></div>
+
+<!-- -->
+<div id="javaScriptAlert">
+ <div class="mask"></div>
+ <div class="message">
+ <div class="header"></div>
+ <div class="body">
+ <div class="alertLogo"></div>
+ <div class="alert">
+ <h1>Attention!</h1>
+ <p>If you can read this message, the chances are that your browser does not properly support JavaScript? or you have disabled this functionality yourself.</p>
+ <h3>Javascript is required to access Clipperz.</h3>
+ <h5>Please enable scripting or upgrade your browser.</h5>
+ </div>
+ </div>
+ <div class="footer"></div>
+ </div>
+</div>
+<!-- -->
+
+</body>
+</html>
diff --git a/frontend/gamma/html/mobile_template.html b/frontend/gamma/html/mobile_template.html
new file mode 100644
index 0000000..adc36e9
--- a/dev/null
+++ b/frontend/gamma/html/mobile_template.html
@@ -0,0 +1,87 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>@page.title@</title>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+@copyright@
+@css@
+
+ <link rel="shortcut icon" href="./clipperz.ico" />
+
+ <meta name="description" content="Login to your web accounts with just one click. Never type a password again! Use multiple complex passwords and forget them. A password manager that enhances your online security." />
+ <meta name="keywords" content="password manager,gestor de contraseñas,gerenciador de senhas,Kennwortmanager,passwords,security,privacy,cryptography" />
+<script>
+ Clipperz_IEisBroken = false;
+ Clipperz_normalizedNewLine = '\n';
+ Clipperz_dumpUrl = "/dump/";
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+Clipperz_normalizedNewLine = '\x0d\x0a';
+</script><![endif]-->
+
+@CLIPPERZ_DEBUG_VERSION@
+
+</head>
+<body>
+<div id="mainDiv">
+ <div id="loading">
+ <a href="http://www.clipperz.com" target="_blank"><div id="logo"></div></a>
+ <h5 class="clipperzPayoff">keep it to yourself!</h5>
+ <h2>loading ...</h2>
+ </div>
+
+@CLIPPERZ_INSTALLED_VERSION@
+
+</div>
+<div id="applicationVersionType" class="@application.version.type@"></div>
+
+<!-- -->
+<div id="javaScriptAlert">
+ <div class="mask"></div>
+ <div class="message">
+ <div class="header"></div>
+ <div class="body">
+ <div class="alertLogo"></div>
+ <div class="alert">
+ <h1>Attention!</h1>
+ <p>If you can read this message, the chances are that your browser does not properly support JavaScript? or you have disabled this functionality yourself.</p>
+ <h3>Javascript is required to access Clipperz.</h3>
+ <h5>Please enable scripting or upgrade your browser.</h5>
+ </div>
+ </div>
+ <div class="footer"></div>
+ </div>
+</div>
+<!-- -->
+
+</body>
+</html>
diff --git a/frontend/gamma/js/Bookmarklet.js b/frontend/gamma/js/Bookmarklet.js
new file mode 100644
index 0000000..a8e3e69
--- a/dev/null
+++ b/frontend/gamma/js/Bookmarklet.js
@@ -0,0 +1,801 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+clipperz_copiedContentToClipboard = false;
+
+//#############################################################################
+
+// Simple Set Clipboard System
+// Author: Joseph Huckaby
+
+var ZeroClipboard = {
+
+ version: "1.0.4",
+ clients: {}, // registered upload clients on page, indexed by id
+// moviePath: 'ZeroClipboard.swf', // URL to movie
+// moviePath: 'data:application/octet-stream;charset=utf-8;base64,Q1dTCYgGAAB4nH1V61LbRhTeXV2OJNsYczFgIEC4JCGABSRpSy+B2JDQQtWJocl0BqK1tUZqhOSRZAj/8ih9hz5AXsGZTl+ndHUhxU2nO56z3/l05uye7+wc6xr6DeUxqpcUhFCNXF9ffxjNcYhRo8U8NruO0IeRLTkm+BpEa4i8/+t3GRGUrRf5tktDe41dMC8Kpd14Q/DM911GPfHCd6zCLyzwa67Tafo0sAppuOWEHZdeyY1O4ERMbnajyPcKIYteUM+qdYPQD/It12m9jX2XBcSx5EYUON6ZwunOEXsXAY+O94HsAu8iFnjULe1mYN/je5u2WLnvAsnRNGrZ6rnfDZlxwQKxRV1XSd1ulPJ1/9KDBB13pDCiZ2ygEdsGj2WHvsXU3dc7taM3e/tHanjDZVqEV2HEzpUGa3V5dVd4Ocfz+5d1/5w6nnbgU4sF+17bFwPfjzT3k691aEDPGb92KBvNX1krmrOjqLNVrVLLb7K1ln9e3WlsVjd0/Um12XXcyPFy6ZHdyHHDkT5tt1JtF/rJerqn6Wu+F/ErsWCmPyiRjrYi54KlgZP/k2Tq9gPYSh5APZOYBVra2VicAtfyn+4qZwHt2E4rVJvszPH2HNcVD2lkS5eOxW3b9f1AtplzZkeKFdDLl/wkibodmyrUsmq241raYdye5ECpdrBf+2GQf0ncA4c3gJelHRrHjd03xs+7L9UMHh9lZN149aOSwuOfcnFO3qQmbb0V44aoSVEXlHeikXQzz1/bpzek8E50XN6o4r/KLfQpU/pMx/J/yz9cxmWhDOOyhMqD5SkJjQnKYnmpIlfuVe5XHlSWKw8rC6QoEayoWk7MFwaKg6Whx4AJEBGIBEQGQQFJBaKBlAMpD6QA0gCQIsglICNAxkGYAFIBMgkwDWQGhFkgc0DuApkHsqDmMZAVIKtA1oBUgejqOmc21E1uHwF5DOQJ4C+AfAnkKyBbQL4G8g2Qb4F8B+o2wA6QZ4DrIOyCsAfCcw0lUwR/ZvgiOP3IhwgWcDZIsCipIpJkPmskBBiBgpGiIqQJOJdYPqbiOaRiUcRIQ5hrIfT055ySiKYVzMLKkKmuDM8aAyInyW1yNCOF22Q5I8Xb5FhGSjLR8n/gnv5q+U+9t4/MojnYLtEhc3jljjGCGT4Z7bXL7bG9Udwefz9xjk9Vhl3crtjqqXwifS8hWzblJToZmylTbk+vYuMOjsECWjZnkuDZvTmcwbscGvOiKVcxXThZNGVjkQebS+17pmLcJwl8sI1v4PI2uYEPt4UbuLItxrCwoplgrMagaOZTENf2NK0NryE8gWRCVE3p6ae5j3aOFwyZb8of6RT3FYn7Y9yvmjlDx1mKGncSfVTC9Z/v6QyZE7q5rpsburmpm490U+K/12g6WXYc+nR4CKX/H31zGG1z5m9Pt5okCg==',
+// moviePath: 'http://localhost:8000/tests/js/tests/Bookmarklet/ZeroClipboard.swf',
+ moviePath: 'http://www.clipperz.com/files/clipperz.com/bookmarklet/0.3.0/ZeroClipboard_1.0.4.swf',
+// moviePath: './ZeroClipboard.swf',
+ nextId: 1, // ID of next movie
+
+ $: function(thingy) {
+ // simple DOM lookup utility function
+ if (typeof(thingy) == 'string') thingy = document.getElementById(thingy);
+ if (!thingy.addClass) {
+ // extend element with a few useful methods
+ thingy.hide = function() { this.style.display = 'none'; };
+ thingy.show = function() { this.style.display = ''; };
+ thingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; };
+ thingy.removeClass = function(name) {
+ this.className = this.className.replace( new RegExp("\\s*" + name + "\\s*"), " ").replace(/^\s+/, '').replace(/\s+$/, '');
+ };
+ thingy.hasClass = function(name) {
+ return !!this.className.match( new RegExp("\\s*" + name + "\\s*") );
+ }
+ }
+ return thingy;
+ },
+
+ setMoviePath: function(path) {
+ // set path to ZeroClipboard.swf
+ this.moviePath = path;
+ },
+
+ dispatch: function(id, eventName, args) {
+ // receive event from flash movie, send to client
+ var client = this.clients[id];
+ if (client) {
+ client.receiveEvent(eventName, args);
+ }
+ },
+
+ register: function(id, client) {
+ // register new client to receive events
+ this.clients[id] = client;
+ },
+
+ getDOMObjectPosition: function(obj) {
+ // get absolute coordinates for dom element
+ var info = {
+ left: 0,
+ top: 0,
+ width: obj.width ? obj.width : obj.offsetWidth,
+ height: obj.height ? obj.height : obj.offsetHeight
+ };
+
+ while (obj) {
+ info.left += obj.offsetLeft;
+ info.top += obj.offsetTop;
+ obj = obj.offsetParent;
+ }
+
+ return info;
+ },
+
+ Client: function(elem) {
+ // constructor for new simple upload client
+ this.handlers = {};
+
+ // unique ID
+ this.id = ZeroClipboard.nextId++;
+ this.movieId = 'ZeroClipboardMovie_' + this.id;
+
+ // register client with singleton to receive flash events
+ ZeroClipboard.register(this.id, this);
+
+ // create movie
+ if (elem) this.glue(elem);
+ }
+};
+
+ZeroClipboard.Client.prototype = {
+
+ id: 0, // unique ID for us
+ ready: false, // whether movie is ready to receive events or not
+ movie: null, // reference to movie object
+ clipText: '', // text to copy to clipboard
+ handCursorEnabled: true, // whether to show hand cursor, or default pointer cursor
+ cssEffects: true, // enable CSS mouse effects on dom container
+ handlers: null, // user event handlers
+
+ glue: function(elem) {
+ // glue to DOM element
+ // elem can be ID or actual DOM element object
+//console.log(">>> glue");
+ this.domElement = ZeroClipboard.$(elem);
+
+ // float just above object, or zIndex 99 if dom element isn't set
+ var zIndex = 99;
+ if (this.domElement.style.zIndex) {
+ zIndex = parseInt(this.domElement.style.zIndex) + 1;
+ }
+
+ // find X/Y position of domElement
+ var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
+
+ // create floating DIV above element
+ this.div = document.createElement('div');
+ var style = this.div.style;
+ style.position = 'absolute';
+ style.left = '' + box.left + 'px';
+ style.top = '' + box.top + 'px';
+ style.width = '' + box.width + 'px';
+ style.height = '' + box.height + 'px';
+ style.zIndex = zIndex;
+
+ // style.backgroundColor = '#f00'; // debug
+
+ var body = document.getElementsByTagName('body')[0];
+ body.appendChild(this.div);
+
+ this.div.innerHTML = this.getHTML( box.width, box.height );
+//console.log("<<< glue");
+ },
+
+ getHTML: function(width, height) {
+ // return HTML for movie
+ var html = '';
+ var flashvars = 'id=' + this.id +
+ '&width=' + width +
+ '&height=' + height;
+
+ if (navigator.userAgent.match(/MSIE/)) {
+ // IE gets an OBJECT tag
+ var protocol = location.href.match(/^https/i) ? 'https://' : 'http://';
+ html += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="'+protocol+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'+width+'" height="'+height+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><param name="wmode" value="transparent"/></object>';
+ }
+ else {
+ // all other browsers get an EMBED tag
+ html += '<embed id="'+this.movieId+'" src="'+ZeroClipboard.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+width+'" height="'+height+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'" wmode="transparent" />';
+ }
+ return html;
+ },
+
+ hide: function() {
+ // temporarily hide floater offscreen
+ if (this.div) {
+ this.div.style.left = '-2000px';
+ }
+ },
+
+ show: function() {
+ // show ourselves after a call to hide()
+ this.reposition();
+ },
+
+ destroy: function() {
+ // destroy control and floater
+ if (this.domElement && this.div) {
+ this.hide();
+ this.div.innerHTML = '';
+
+ var body = document.getElementsByTagName('body')[0];
+ try { body.removeChild( this.div ); } catch(e) {;}
+
+ this.domElement = null;
+ this.div = null;
+ }
+ },
+
+ reposition: function(elem) {
+ // reposition our floating div, optionally to new container
+ // warning: container CANNOT change size, only position
+ if (elem) {
+ this.domElement = ZeroClipboard.$(elem);
+ if (!this.domElement) this.hide();
+ }
+
+ if (this.domElement && this.div) {
+ var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
+ var style = this.div.style;
+ style.left = '' + box.left + 'px';
+ style.top = '' + box.top + 'px';
+ }
+ },
+
+ setText: function(newText) {
+ // set text to be copied to clipboard
+ this.clipText = newText;
+ if (this.ready) this.movie.setText(newText);
+ },
+
+ addEventListener: function(eventName, func) {
+ // add user event listener for event
+ // event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel
+ eventName = eventName.toString().toLowerCase().replace(/^on/, '');
+ if (!this.handlers[eventName]) this.handlers[eventName] = [];
+ this.handlers[eventName].push(func);
+ },
+
+ setHandCursor: function(enabled) {
+ // enable hand cursor (true), or default arrow cursor (false)
+ this.handCursorEnabled = enabled;
+ if (this.ready) this.movie.setHandCursor(enabled);
+ },
+
+ setCSSEffects: function(enabled) {
+ // enable or disable CSS effects on DOM container
+ this.cssEffects = !!enabled;
+ },
+
+ receiveEvent: function(eventName, args) {
+ // receive event from flash
+ eventName = eventName.toString().toLowerCase().replace(/^on/, '');
+
+ // special behavior for certain events
+ switch (eventName) {
+ case 'load':
+ // movie claims it is ready, but in IE this isn't always the case...
+ // bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function
+ this.movie = document.getElementById(this.movieId);
+ if (!this.movie) {
+ var self = this;
+ setTimeout( function() { self.receiveEvent('load', null); }, 1 );
+ return;
+ }
+
+ // firefox on pc needs a "kick" in order to set these in certain cases
+ if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {
+ var self = this;
+ setTimeout( function() { self.receiveEvent('load', null); }, 100 );
+ this.ready = true;
+ return;
+ }
+
+ this.ready = true;
+ this.movie.setText( this.clipText );
+ this.movie.setHandCursor( this.handCursorEnabled );
+ break;
+
+ case 'mouseover':
+ if (this.domElement && this.cssEffects) {
+ this.domElement.addClass('hover');
+ if (this.recoverActive) this.domElement.addClass('active');
+ }
+ break;
+
+ case 'mouseout':
+ if (this.domElement && this.cssEffects) {
+ this.recoverActive = false;
+ if (this.domElement.hasClass('active')) {
+ this.domElement.removeClass('active');
+ this.recoverActive = true;
+ }
+ this.domElement.removeClass('hover');
+ }
+ break;
+
+ case 'mousedown':
+ if (this.domElement && this.cssEffects) {
+ this.domElement.addClass('active');
+ }
+ break;
+
+ case 'mouseup':
+ if (this.domElement && this.cssEffects) {
+ this.domElement.removeClass('active');
+ this.recoverActive = false;
+ }
+ break;
+ } // switch eventName
+
+ if (this.handlers[eventName]) {
+ for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) {
+ var func = this.handlers[eventName][idx];
+
+ if (typeof(func) == 'function') {
+ // actual function reference
+ func(this, args);
+ }
+ else if ((typeof(func) == 'object') && (func.length == 2)) {
+ // PHP style object + method, i.e. [myObject, 'myMethod']
+ func[0][ func[1] ](this, args);
+ }
+ else if (typeof(func) == 'string') {
+ // name of function
+ window[func](this, args);
+ }
+ } // foreach event handler defined
+ } // user defined handler for event
+ }
+
+};
+
+//#############################################################################
+
+var clip = null;
+
+function $(id) { return document.getElementById(id); }
+
+function initClip() {
+//console.log(">>> initClip");
+ clip = new ZeroClipboard.Client();
+ clip.setHandCursor( true );
+
+// clip.addEventListener('load', my_load);
+// clip.addEventListener('mouseOver', my_mouse_over);
+ clip.addEventListener('complete', my_complete);
+
+// clip.glue( 'd_clip_button' );
+//console.log("<<< initClip");
+}
+
+//function my_load(client) {
+// console.log("Flash movie loaded and ready.");
+//}
+
+//function my_mouse_over(client) {
+// // we can cheat a little here -- update the text on mouse over
+// clip.setText( $('fe_text').value );
+//}
+
+function my_complete(client, text) {
+// console.log("Copied text to clipboard: ... ");
+// console.log("Copied text to clipboard: " + text );
+ clipperz_copiedContentToClipboard = true;
+ showTooltip();
+}
+
+//function debugstr(msg) {
+// var p = document.createElement('p');
+// p.innerHTML = msg;
+// $('d_debug').appendChild(p);
+//}
+
+//#############################################################################
+
+_cble = null;
+
+//-----------------------------------------------------------------------------
+
+isLoginForm = function(aForm) {
+ var inputFields;
+ var passwordFieldsFound;
+ var i,c;
+
+//console.log("is login form: " + aForm.name + " (" + aForm.id + ")");
+ passwordFieldsFound = 0;
+ inputFields = aForm.elements;
+ c = inputFields.length;
+ for (i=0; i<c; i++) {
+ if (inputFields[i].type == "password") {
+ passwordFieldsFound ++;
+ }
+ }
+//console.log("number of password fields found: " + passwordFieldsFound);
+ return (passwordFieldsFound == 1);
+};
+
+//-----------------------------------------------------------------------------
+
+findLoginForm = function(aDocument, aLevel) {
+ var result;
+ var documentForms;
+ var i,c;
+
+ result = null;
+
+ try {
+ documentForms = aDocument.getElementsByTagName('form');
+
+ c = documentForms.length;
+ for (i=0; (i<c) && (result == null); i++) {
+ if (isLoginForm(documentForms[i])) {
+ result = documentForms[i];
+ }
+ }
+
+ if ((result == null) && (aLevel == 0)) {
+ var iFrames;
+
+ iFrames = aDocument.getElementsByTagName('iframe');
+ c = iFrames.length;
+ for (i=0; (i<c) && (result == null); i++) {
+ result = findLoginForm(iFrames[i].contentDocument, (aLevel + 1));
+ }
+ }
+ } catch (e) {
+ _cble = e;
+ }
+
+ return result;
+};
+
+//-----------------------------------------------------------------------------
+
+inputElementValues = function(anInputElement) {
+ var result;
+
+// if ((anInputElement instanceof HTMLInputElement) && (anInputElement.getAttribute('name') != null)) {
+ if ((anInputElement.tagName.toLowerCase() == "input") && (anInputElement.getAttribute('name') != null)) {
+ result = {};
+ result.type = anInputElement.getAttribute('type') || "text";
+ result.name = anInputElement.getAttribute('name');
+// result.value = anInputElement.getAttribute('value');
+ result.value = anInputElement.value;
+ if (anInputElement.type.toLowerCase() == 'radio') {
+ result.checked = anInputElement.checked;
+ }
+// } else if ((anInputElement instanceof HTMLSelectElement) && (anInputElement.getAttribute('name') != null)) {
+ } else if ((anInputElement.tagName.toLowerCase() == 'select') && (anInputElement.getAttribute('name') != null)) {
+ var options;
+ var c,i;
+
+//console.log("input element values: %o", anInputElement);
+ result = {};
+ result.type = "select";
+ result.name = anInputElement.getAttribute('name');
+
+ result.options = [];
+ options = anInputElement.options;
+ c = options.length;
+ for (i=0; i<c; i++) {
+ var option;
+
+ option = {};
+ option.selected = options[i].selected;
+ option.label = options[i].label || options[i].innerHTML;
+ option.value = options[i].value;
+ result.options.push(option);
+ }
+ } else {
+ result = null;
+ }
+
+ return result;
+};
+
+//-----------------------------------------------------------------------------
+
+formParameters = function(aLoginForm) {
+ var result;
+ var i, c;
+ var action;
+
+ if (aLoginForm == null) {
+ result = null;
+ } else {
+ var radioValues;
+ var radioValueName;
+
+ result = {};
+ radioValues = {};
+
+ action = aLoginForm.action;
+ if (action.constructor != String) {
+ action = aLoginForm.getAttribute('action');
+ }
+
+ if (/^https?\:\/\/.*/.test(action)) {
+ action = action;
+ } else if (/^\/.*/.test(action)) {
+ action = window.location.protocol + '/' + '/' + window.location.hostname + action;
+ } else {
+ action = window.location.href.replace(/\/[^\/]*$/, '/' + action);
+ }
+
+ result.attributes = {};
+ result.attributes.action = action;
+ result.attributes.method = aLoginForm.getAttribute('method');
+
+ result.inputs = [];
+ c = aLoginForm.elements.length;
+ for (i=0; i<c; i++) {
+ var inputElement;
+ var elementValues;
+
+ inputElement = aLoginForm.elements[i];
+ elementValues = inputElementValues(inputElement);
+ if (elementValues != null) {
+ if (elementValues.type != "radio") {
+ result.inputs.push(elementValues);
+ } else {
+ var radioValue;
+ var values;
+
+ radioValue = radioValues[elementValues.name];
+ if (radioValue == null) {
+ radioValue = {};
+ radioValue.name = elementValues.name;
+ radioValue.type = "radio";
+ radioValue.options = [];
+
+ radioValues[elementValues.name] = radioValue;
+ }
+
+ values = {};
+ values.value = elementValues.value;
+ values.checked = elementValues.checked;
+
+ radioValue.options.push(values);
+ }
+ }
+ }
+
+ for (radioValueName in radioValues) {
+ if (typeof(radioValues[radioValueName]) != "function") {
+ result.inputs.push(radioValues[radioValueName]);
+ }
+ }
+ }
+
+ return result;
+};
+
+//-----------------------------------------------------------------------------
+
+selectFaviconURL = function () {
+ var result;
+ var links;
+ var link;
+ var i;
+
+// <link rel="icon" type="image/x-icon" href="http://example.com/favicon.ico" />
+// <link rel="icon" type="image/vnd.microsoft.icon" href="http://example.com/image.ico" />
+// <link rel="SHORTCUT ICON" type="image/x-icon" href="/horde/imp/graphics/favicon.ico" />
+ links = document.getElementsByTagName("head")[0].getElementsByTagName('link');
+
+ i = 0;
+ link = null;
+ while ((link == null) && (i < links.length)) {
+ if ((links[i].rel.toLowerCase() == 'icon') || (links[i].rel.toLowerCase() == 'shortcut icon')) {
+ link = links[i];
+ }
+
+ i++;
+ }
+
+ if (link != null) {
+ result = link.href;
+ } else {
+ result = "http://" + window.location.hostname + "/favicon.ico";
+ }
+
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+
+pageParameters = function() {
+ var result;
+
+ result = {};
+ result['title'] = document.title;
+ result['favicon'] = selectFaviconURL();
+ result['url'] = window.location.href;
+
+ return result;
+};
+
+//-----------------------------------------------------------------------------
+
+reprString = function (o) {
+ return ('"' + o.replace(/(["\\])/g, '\\$1') + '"'
+ ).replace(/[\f]/g, "\\f"
+ ).replace(/[\b]/g, "\\b"
+ ).replace(/[\n]/g, "\\n"
+ ).replace(/[\t]/g, "\\t"
+ ).replace(/[\r]/g, "\\r");
+};
+
+//-----------------------------------------------------------------------------
+
+serializeJSON = function (o) {
+ var objtype = typeof(o);
+ if (objtype == "number" || objtype == "boolean") {
+ return o + "";
+ } else if (o === null) {
+ return "null";
+ }
+
+// var m = MochiKit.Base;
+// var reprString = m.reprString;
+ if (objtype == "string") {
+ return reprString(o);
+ }
+
+ // recurse
+ var me = arguments.callee;
+ // array
+ if (objtype != "function" && typeof(o.length) == "number") {
+ var res = [];
+ for (var i = 0; i < o.length; i++) {
+ var val = me(o[i]);
+ if (typeof(val) != "string") {
+ val = "undefined";
+ }
+ res.push(val);
+ }
+ return "[" + res.join(",\n") + "]";
+ }
+
+ // undefined is outside of the spec
+ if (objtype == "undefined") {
+// throw new TypeError("undefined can not be serialized as JSON");
+ throw new TypeError("error");
+ }
+
+ // generic object code path
+ res = [];
+ for (var k in o) {
+ if (typeof(o[k]) != "function") {
+ var useKey;
+ if (typeof(k) == "number") {
+ useKey = '"' + k + '"';
+ } else if (typeof(k) == "string") {
+ useKey = reprString(k);
+ } else {
+ // skip non-string or number keys
+ continue;
+ }
+
+ val = me(o[k]);
+ if (typeof(val) != "string") {
+ // skip non-serializable values
+ continue;
+ }
+ res.push(useKey + ":" + " " + val);
+ }
+ }
+
+ return "{" + res.join(",\n") + "}";
+};
+
+//-----------------------------------------------------------------------------
+
+getLoginFormConfiguration = function() {
+ var parameters;
+
+ parameters = {};
+ parameters.page = pageParameters();
+ parameters.form = formParameters(findLoginForm(document, 0));
+ parameters.version = "0.3.0";
+
+ return parameters;
+}
+
+//#############################################################################
+
+//-----------------------------------------------------------------------------
+
+closeClick = function () {
+ var bookmarkletDiv;
+
+ bookmarkletDiv = document.getElementById("clipperzBookmarkletWrapper");
+ bookmarkletDiv.parentNode.removeChild(bookmarkletDiv);
+};
+
+//-----------------------------------------------------------------------------
+
+logFormParameters = function(someParameters, anException) {
+ var showException;
+ var message;
+
+ if ((someParameters != null) && (someParameters.form != null) && (anException == null)) {
+ showException = false;
+ message = traslatableTexts['noExceptionMessage'];
+ } else {
+ showException = true
+ message = traslatableTexts['exceptionMessage'];
+ }
+
+ var newCSS = document.createElement('link');
+ newCSS.setAttribute("type", "text/css");
+ newCSS.setAttribute("rel", "stylesheet");
+ newCSS.setAttribute("media", "screen");
+ newCSS.setAttribute("href", "http://www.clipperz.com/files/clipperz.com/bookmarklet/0.3.0/Bookmarklet.css");
+ document.getElementsByTagName("head")[0].appendChild(newCSS);
+
+ var innerHTML;
+
+ innerHTML = "";
+ innerHTML += "<div id='clipperzBookmarklet'>" +
+ "<div id='clipperzBookmarkletClose'></div>" +
+ "<div id='clipperzBookmarkletResult'>" +
+ "<div id='clipperzBookmarkletResultIcon' class=" + ((showException == false) ? 'ok' : 'fail') + "></div>" +
+ "<p id='clipperzBookmarkletResultText'>" + message + "</p>" +
+ "</div>";
+
+ if (showException == false) {
+ innerHTML += "<div id='clipperzBookmarletButton'><span>" + traslatableTexts['copy'] + "</span></div>" +
+ "<div id='clipperzBookmarletAfterCopyHint' class='hidden'>" +
+ "<p id='clipperzBookmarkletHintText'>Lorem ipsum</p>" +
+ "</div>";
+ }
+
+ innerHTML += "</div>";
+
+ var newDiv = document.createElement('div');
+ newDiv.setAttribute("id", "clipperzBookmarkletWrapper");
+ newDiv.innerHTML = innerHTML;
+ document.body.appendChild(newDiv);
+
+ $('clipperzBookmarkletClose').onclick = closeClick;
+
+ if (showException == false) {
+ $('clipperzBookmarletButton').onclick = showTooltip;
+ setTimeout("clip.glue('clipperzBookmarletButton');", 1000);
+ }
+}
+
+showTooltip = function () {
+ if (clipperz_copiedContentToClipboard == true) {
+//console.log("SUCCEED");
+ $('clipperzBookmarkletHintText').innerHTML = traslatableTexts['successfulMessage'];
+ $('clipperzBookmarletAfterCopyHint').className = 'visible';
+ } else {
+//console.log("FAIL");
+ $('clipperzBookmarkletHintText').innerHTML = traslatableTexts['failMessage'];
+ }
+}
+
+//#############################################################################
+
+traslatableTexts = {
+ 'noExceptionMessage': "@BOOKMARKLET_NO_EXCEPTION_MESSAGE@",
+ 'exceptionMessage': "@BOOKMARKLET_EXCEPTION_MESSAGE@",
+ 'copy': "@BOOKMARKLET_COPY@",
+ 'successfulMessage': "@BOOKMARKLET_SUCCESSFUL_MESSAGE@",
+ 'failMessage': "@BOOKMARKLET_FAIL_MESSAGE@"
+
+// 'noExceptionMessage': "The direct login configuration has been collected.",
+// 'exceptionMessage': "Sorry! There was an error while processing the page.",
+// 'copy': "copy",
+// 'successfulMessage': "DONE!",
+// 'failMessage': "Failed! :("
+}
+
+//#############################################################################
+
+runBookmarklet = function () {
+ var parameters;
+
+ try {
+ initClip();
+
+ parameters = getLoginFormConfiguration();
+//console.log("configuration", serializeJSON(parameters))
+ clip.setText(serializeJSON(parameters));
+ clip.setHandCursor( true );
+// clip.glue('clipperzBookmarletButton');
+
+ logFormParameters(parameters, _cble);
+ } catch (e) {
+ logFormParameters(parameters, e);
+ }
+
+};
+
+//#############################################################################
+
+if (document.body != null) {
+ runBookmarklet();
+};
+
+//#############################################################################
diff --git a/frontend/gamma/js/BookmarkletHash.js b/frontend/gamma/js/BookmarkletHash.js
new file mode 100644
index 0000000..2e0714c
--- a/dev/null
+++ b/frontend/gamma/js/BookmarkletHash.js
@@ -0,0 +1,47 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+// 18f820faffcdb5e847d4c5d5c4a1de6743baa1a0
+// 9b30434c73fb009b15fecaa904b44f9ced807577
+// 9b30434c73fb009b15fecaa904b44f9ced807577
+var xh;
+var documentText;
+
+try {
+ xh=new XMLHttpRequest();
+} catch(e) {
+ xh=new ActiveXObject("Msxml2.XMLHTTP");
+}
+
+xh.open("GET", window.location, false);
+xh.send(null);
+
+documentText = "#####" + xh.responseText + "####";
+//documentText = document.body.innerHTML;
+
+//console.log(documentText); \ No newline at end of file
diff --git a/frontend/gamma/js/Bookmarklet_1.js b/frontend/gamma/js/Bookmarklet_1.js
new file mode 100644
index 0000000..d117479
--- a/dev/null
+++ b/frontend/gamma/js/Bookmarklet_1.js
@@ -0,0 +1,400 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+_cble = null;
+
+//-----------------------------------------------------------------------------
+
+isLoginForm = function(aForm) {
+ var inputFields;
+ var passwordFieldsFound;
+ var i,c;
+
+//console.log("is login form: " + aForm.name + " (" + aForm.id + ")");
+ passwordFieldsFound = 0;
+ inputFields = aForm.elements;
+ c = inputFields.length;
+ for (i=0; i<c; i++) {
+ if (inputFields[i].type == "password") {
+ passwordFieldsFound ++;
+ }
+ }
+//console.log("number of password fields found: " + passwordFieldsFound);
+ return (passwordFieldsFound == 1);
+};
+
+//-----------------------------------------------------------------------------
+
+findLoginForm = function(aDocument, aLevel) {
+ var result;
+ var documentForms;
+ var i,c;
+
+ result = null;
+
+ try {
+ documentForms = aDocument.getElementsByTagName('form');
+
+ c = documentForms.length;
+ for (i=0; (i<c) && (result == null); i++) {
+ if (isLoginForm(documentForms[i])) {
+ result = documentForms[i];
+ }
+ }
+
+ if ((result == null) && (aLevel == 0)) {
+ var iFrames;
+
+ iFrames = aDocument.getElementsByTagName('iframe');
+ c = iFrames.length;
+ for (i=0; (i<c) && (result == null); i++) {
+ result = findLoginForm(iFrames[i].contentDocument, (aLevel + 1));
+ }
+ }
+ } catch (e) {
+ _cble = e;
+ }
+
+ return result;
+};
+
+//-----------------------------------------------------------------------------
+
+inputElementValues = function(anInputElement) {
+ var result;
+
+// if ((anInputElement instanceof HTMLInputElement) && (anInputElement.getAttribute('name') != null)) {
+ if ((anInputElement.tagName.toLowerCase() == "input") && (anInputElement.getAttribute('name') != null)) {
+ result = {};
+ result.type = anInputElement.getAttribute('type') || "text";
+ result.name = anInputElement.getAttribute('name');
+// result.value = anInputElement.getAttribute('value');
+ result.value = anInputElement.value;
+ if (anInputElement.type.toLowerCase() == 'radio') {
+ result.checked = anInputElement.checked;
+ }
+// } else if ((anInputElement instanceof HTMLSelectElement) && (anInputElement.getAttribute('name') != null)) {
+ } else if ((anInputElement.tagName.toLowerCase() == 'select') && (anInputElement.getAttribute('name') != null)) {
+ var options;
+ var c,i;
+
+//console.log("input element values: %o", anInputElement);
+ result = {};
+ result.type = "select";
+ result.name = anInputElement.getAttribute('name');
+
+ result.options = [];
+ options = anInputElement.options;
+ c = options.length;
+ for (i=0; i<c; i++) {
+ var option;
+
+ option = {};
+ option.selected = options[i].selected;
+ option.label = options[i].label || options[i].innerHTML;
+ option.value = options[i].value;
+ result.options.push(option);
+ }
+ } else {
+ result = null;
+ }
+
+ return result;
+};
+
+//-----------------------------------------------------------------------------
+
+formParameters = function(aLoginForm) {
+ var result;
+ var i, c;
+ var action;
+
+ if (aLoginForm == null) {
+ result = null;
+ } else {
+ var radioValues;
+ var radioValueName;
+
+ result = {};
+ radioValues = {};
+
+ action = aLoginForm.action;
+ if (action.constructor != String) {
+ action = aLoginForm.getAttribute('action');
+ }
+
+ if (/^https?\:\/\/.*/.test(action)) {
+ action = action;
+ } else if (/^\/.*/.test(action)) {
+ action = window.location.protocol + '/' + '/' + window.location.hostname + action;
+ } else {
+ action = window.location.href.replace(/\/[^\/]*$/, '/' + action);
+ }
+
+ result.attributes = {};
+ result.attributes.action = action;
+ result.attributes.method = aLoginForm.getAttribute('method');
+
+ result.inputs = [];
+ c = aLoginForm.elements.length;
+ for (i=0; i<c; i++) {
+ var inputElement;
+ var elementValues;
+
+ inputElement = aLoginForm.elements[i];
+ elementValues = inputElementValues(inputElement);
+ if (elementValues != null) {
+ if (elementValues.type != "radio") {
+ result.inputs.push(elementValues);
+ } else {
+ var radioValue;
+ var values;
+
+ radioValue = radioValues[elementValues.name];
+ if (radioValue == null) {
+ radioValue = {};
+ radioValue.name = elementValues.name;
+ radioValue.type = "radio";
+ radioValue.options = [];
+
+ radioValues[elementValues.name] = radioValue;
+ }
+
+ values = {};
+ values.value = elementValues.value;
+ values.checked = elementValues.checked;
+
+ radioValue.options.push(values);
+ }
+ }
+ }
+
+ for (radioValueName in radioValues) {
+ if (typeof(radioValues[radioValueName]) != "function") {
+ result.inputs.push(radioValues[radioValueName]);
+ }
+ }
+ }
+
+ return result;
+};
+
+//-----------------------------------------------------------------------------
+
+pageParameters = function() {
+ var result;
+
+ result = {};
+ result['title'] = document.title;
+//<link rel="icon" href="http://example.com/favicon.ico" type="image/x-icon">
+
+ return result;
+};
+
+//-----------------------------------------------------------------------------
+
+reprString = function (o) {
+ return ('"' + o.replace(/(["\\])/g, '\\$1') + '"'
+ ).replace(/[\f]/g, "\\f"
+ ).replace(/[\b]/g, "\\b"
+ ).replace(/[\n]/g, "\\n"
+ ).replace(/[\t]/g, "\\t"
+ ).replace(/[\r]/g, "\\r");
+};
+
+//-----------------------------------------------------------------------------
+
+serializeJSON = function (o) {
+ var objtype = typeof(o);
+ if (objtype == "number" || objtype == "boolean") {
+ return o + "";
+ } else if (o === null) {
+ return "null";
+ }
+
+// var m = MochiKit.Base;
+// var reprString = m.reprString;
+ if (objtype == "string") {
+ return reprString(o);
+ }
+
+ // recurse
+ var me = arguments.callee;
+ // array
+ if (objtype != "function" && typeof(o.length) == "number") {
+ var res = [];
+ for (var i = 0; i < o.length; i++) {
+ var val = me(o[i]);
+ if (typeof(val) != "string") {
+ val = "undefined";
+ }
+ res.push(val);
+ }
+ return "[" + res.join(",\n") + "]";
+ }
+
+ // undefined is outside of the spec
+ if (objtype == "undefined") {
+// throw new TypeError("undefined can not be serialized as JSON");
+ throw new TypeError("error");
+ }
+
+ // generic object code path
+ res = [];
+ for (var k in o) {
+ if (typeof(o[k]) != "function") {
+ var useKey;
+ if (typeof(k) == "number") {
+ useKey = '"' + k + '"';
+ } else if (typeof(k) == "string") {
+ useKey = reprString(k);
+ } else {
+ // skip non-string or number keys
+ continue;
+ }
+
+ val = me(o[k]);
+ if (typeof(val) != "string") {
+ // skip non-serializable values
+ continue;
+ }
+ res.push(useKey + ":" + " " + val);
+ }
+ }
+
+ return "{" + res.join(",\n") + "}";
+};
+
+//-----------------------------------------------------------------------------
+
+closeBookmarklet = function() {
+ var bookmarkletDiv;
+
+ bookmarkletDiv = document.getElementById("clipperz_bookmarklet");
+ bookmarkletDiv.parentNode.removeChild(bookmarkletDiv);
+};
+
+//-----------------------------------------------------------------------------
+
+logFormParameters = function(someParameters, anException) {
+ var newDiv;
+ var base_url;
+ var help_url;
+// var base_image_url;
+ var logo_image_url;
+ var background_image_url;
+ var close_image_url;
+ var bookmarklet_textarea;
+ var innerHTML;
+
+//
+// Obsolete: image -> base64 encoding done here: http://www.motobit.com/util/base64-decoder-encoder.asp
+// conversion done using the Filemark Maker application: http://www.insanelygreattees.com/news/?p=51
+//
+
+ base_url = "http://www.clipperz.com/";
+ help_url = base_url + "help/bookmarklet";
+// base_image_url = base_url + "files/clipperz.com/bookmarklet/";
+// logo_image_url = base_image_url + "logo.png";
+ logo_image_url = "data:image/png;charset=utf-8;base64,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";
+// background_image_url = base_image_url + "background.png";
+ background_image_url = "data:image/png;charset=utf-8;base64,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Llccuo/bX7mtHavu9cv5eoDJDda5Pqy1sepe31SbHYj247Uj1V/nst/6md4GjwFsDetFqTkGrWO9729auKY364HqwumpX1VTtRqnqc71dtDWm7aAq2/Y+bq53o7Ucufr5noTs+7jjG2zgtVEph2n5uuZqpo6cOCOj+39yK2fn5nZ8dler39Tr9ff1+v1rtmk5weukOFwOD8cDo4NB4OfnFta+Pe33n3x8SNHDh2uUagWazVayzVqQzdeY9uMaaY9ITWxml45Zm644c4b9u05+Bcz03NfrOpNbcLzAVvKcHlx8czXjh7//pePHDn0eo2itdQ6lmvt0nFskwarvYxrh2q6quYO3vrFz+/c+dG/r15v54TPA2xxw+Fw/uTJo1964aWHH6+qszUKV3O0l41jLw8nmXg2itVMVW3/9ME//KPt26//cq/Xm5vgOYAQvV5vdnZ21xf2XPfx08feev75zrc3ZQ9rkgmrvQxsQjVTVdtu+/h9X9i1a/8/9nq9NY9/8y37655776zP3HFb7d+/p3bs0DJIs7Bwto4efbuee/aFeuzRZ+qVl4+u+f5wWIMTJ177k/995bFvVNWZGk1bZ2t1edhMW5ds3GB196xmaxSruX37fu2mGw/c+a/tDfXp6an60z/7/brv/ruq3++v/4hAnMFgUA8/9FQ9+MAjtbS0fP724XA4//Jr3/zd48d/8GqNonWmqs7V6r7WWPtZ4y4Jm2A1pyrM1Cha2z9x02//1fT07K82d5yenqoH/+GP6+7P3V6dgQsI1+v16pc+dWN9+lduricf/04NBsPm9tkd266/9o03v/eftbpv1d58rxpjmThJsJpTF2aqaq6q5vbu/eWb9u659e+qeufHqC/9+R/U3Z+7fcynARLccMPe2r17Rz3z9A/P3zY9PfuJhbMnvnHmzPH3au27hGOf4jDO+qx7GkOz2T67b89tv9U+deHmW/bXffffNc7rAsLcd/9ddfMt+1u39Kb2XX/w7qraXqvbRu1zNC95yTXJhlL77PWZqpqdm939G+073HPvnfas4EOi3+/XPffeuea27XPX/XqNVmCztTrcTNWFf5J3cc8x5mtb7x3CuX5/+hfad/rMHbeN+fBAou7vfH9q5kBVbatRsGZr7YR1ycYNVvtPcM4vCfv9qb3tO+3fv2fMhwcSdX/np3pT19dowmpOe2omrO4nuFyUcfewmssmXNNVNdPr9be37+g8K/hw6f7O9/pTzXTV7F+NHauqyZaE7T2sZsoC6Gomq+a4Ypvu3Y+D6XcOgK7uR0t1+3HRJt10735CA0BX+93Bsaerqsmmom4lncYOrGe9yeqKB6vqwkkLoGviUDUmnbAAfpaN3hG8ome6t1+ICQvYyHr/W9ZVWRIC/CybthoTLCDGJKc1AIzrii4Ju2tRAQPez0a9uGJ/Swhwsd6vGxfdFHtYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXE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";
+// close_image_url = base_image_url + "close.png";
+ close_image_url = "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAIAAAC0D9CtAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGiSURBVHjaYvz//z8DiYAFU+jhg5cXLtx9/+4LLy+nlpa8hpYsIyMjTj03rj/u71l74fxdZEEFRfG8wkBrG224CCPcbfv2XKivWfjr1x+s7snM8U1IcoOwmeA24NEABNOnbN698yyKHqCTIBrcPU2WrKiIjHYEsh2c9BctK0tMcYeomdC37sePXyAW0G0P7r8wM8yBoFs3n/wHgwP7L/79+xfI+Pnzl6VpHkR27+7zQBGQPcie3rr5JIRh76DHxASS3bHtzN8//yCCF87fgbrt/fsvcD3Ll+4/eOASnPvg/suO1hVwLjACoHqA8QAXBfrB1k4HOaDjEl3hXF4+LqgeYMTBRZNS3CFOAtoAEUlIdGNmgQaVlrYcVA8wpoHmQUT377v469fvTRuOR4W1zZi25cf3X6DAAPuHi4vd1l4XEadHj1wtypsB0QY0Fe5pZHZOvn9svAsifoBJAxjTEDZcETLbw8s0Js4ZPe0AATCmgRH35vUn5BQAdFJSqgdQAzylMqLlBWBMHztyDRgPoHTNxwX0NNAP/PzcyGoYycg/AAEGABYVzxqE3YcJAAAAAElFTkSuQmCCCg==";
+
+// newDiv.parentNode.removeChild(newDiv);
+ newDiv = document.createElement('div');
+ newDiv.setAttribute("id", "clipperz_bookmarklet");
+// newDiv.setAttribute("style", "width:270px; height:400px; padding:20px 0px 0px 20px; margin:0px; border:0px; background-color:transparent; background-repeat:no-repeat; position:absolute; z-index:20000; top:40px; left:40px; background-image:url(" + background_image_url + ");");
+
+ innerHTML = "";
+ innerHTML += "<style>div#ClipperzBackgroundDIV { width:290px; height:420px; padding:20px 0px 0px 20px; margin:0px; border:0px; background-color:transparent; background-repeat:no-repeat; position:absolute; z-index:20000; top:40px; left:40px; background-image:url(" + background_image_url + ") }</style>";
+ innerHTML += "<div style=\"border:0px; margin:0px; padding:0px; padding-left:10px;\">" +
+ "<img style=\"padding-top:5px;\" src=\"" + logo_image_url + "\">" +
+ "<a href=\"javascript:closeBookmarklet();\">" +
+ "<img style=\"padding-left:28px; padding-bottom:10px;\" border=0 src=\"" + close_image_url + "\">" +
+ "</a>" +
+ "</div>";
+
+ if ((someParameters != null) && (anException == null)) {
+ innerHTML += "<div style=\"width:255px; border-top:1px dotted #336;\">" +
+ "<div style=\"line-height:10pt; margin-right:10px; margin-top:5px; padding:5px 10px; color:#666; text-align:left; font-family:sans-serif;\">" +
+ "<p style=\"margin:0px; font-weight:bold; font-size:10pt; font-family:sans-serif;\">How to add a new card or a direct login to an existing card for this website:</p>" +
+ "<ol style=\"padding:0px 0px 0px 20px; font-size:9pt; font-family:sans-serif;\">" +
+ "<li>Copy the content of the text area below (Ctrl-C)</li>" +
+ "<li>Go to your Clipperz account</li>" +
+ "<li>Click \"Add new card\" or select the related card</li>" +
+ "<li>Paste the direct login configuration (Ctrl-V)</li>" +
+ "<li>Complete and review the details, then click \"Save\"</li>" +
+ "</ol>" +
+ "</div>" +
+ "</div>";
+ innerHTML += "<textarea id=\"bookmarklet_textarea\" style=\"border:2px solid #333366; font-family:sans-serif; font-size:8pt; color:#336; width:240px; height:135px; padding:4px; background-color:white; margin:0px 10px;\">" +
+ serializeJSON(someParameters) +
+ "</textarea>";
+ } else if ((someParameters == null) && (anException == null)) {
+ innerHTML += "<div>No login form has been found on the page</div><div>Get some help <a href=\"#\">here</a></div>";
+ } else {
+ innerHTML += "<div>An error happened while processing the page</div><div>Get some help <a href=\"#\">here</a></div><div>" + anException.name + " - " + anException.message + "</div>";
+ }
+
+// newDiv.innerHTML = "<div style='width:290px; height:420px; padding:20px 0px 0px 20px; margin:0px; border:0px; background-color:transparent; background-repeat:no-repeat; position:absolute; z-index:20000; top:40px; left:40px; background-image:url(" + background_image_url + ")'>" + innerHTML + "</div>";
+ newDiv.innerHTML = "<div id=\"ClipperzBackgroundDIV\">" + innerHTML + "</div>";
+
+ document.body.appendChild(newDiv);
+
+ if ((someParameters != null) && (anException == null)) {
+ bookmarklet_textarea = document.getElementById("bookmarklet_textarea");
+ bookmarklet_textarea.focus();
+ bookmarklet_textarea.select();
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+getLoginFormConfiguration = function() {
+ var parameters;
+
+ try {
+ parameters = {};
+ parameters.page = pageParameters();
+ parameters.form = formParameters(findLoginForm(document, 0));
+ parameters.version = "0.2.3";
+ logFormParameters(parameters, _cble);
+ } catch (e) {
+ // parameters = "No login form has been found"
+ logFormParameters(parameters, e);
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+getLoginFormConfiguration();
+
+
+
diff --git a/frontend/gamma/js/Bookmarklet_2.js b/frontend/gamma/js/Bookmarklet_2.js
new file mode 100644
index 0000000..f9c40a9
--- a/dev/null
+++ b/frontend/gamma/js/Bookmarklet_2.js
@@ -0,0 +1,767 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+clipperz_copiedContentToClipboard = false;
+
+//#############################################################################
+
+// Simple Set Clipboard System
+// Author: Joseph Huckaby
+
+var ZeroClipboard = {
+
+ version: "1.0.4",
+ clients: {}, // registered upload clients on page, indexed by id
+// moviePath: 'ZeroClipboard.swf', // URL to movie
+// moviePath: 'data:application/octet-stream;charset=utf-8;base64,Q1dTCYgGAAB4nH1V61LbRhTeXV2OJNsYczFgIEC4JCGABSRpSy+B2JDQQtWJocl0BqK1tUZqhOSRZAj/8ih9hz5AXsGZTl+ndHUhxU2nO56z3/l05uye7+wc6xr6DeUxqpcUhFCNXF9ffxjNcYhRo8U8NruO0IeRLTkm+BpEa4i8/+t3GRGUrRf5tktDe41dMC8Kpd14Q/DM911GPfHCd6zCLyzwa67Tafo0sAppuOWEHZdeyY1O4ERMbnajyPcKIYteUM+qdYPQD/It12m9jX2XBcSx5EYUON6ZwunOEXsXAY+O94HsAu8iFnjULe1mYN/je5u2WLnvAsnRNGrZ6rnfDZlxwQKxRV1XSd1ulPJ1/9KDBB13pDCiZ2ygEdsGj2WHvsXU3dc7taM3e/tHanjDZVqEV2HEzpUGa3V5dVd4Ocfz+5d1/5w6nnbgU4sF+17bFwPfjzT3k691aEDPGb92KBvNX1krmrOjqLNVrVLLb7K1ln9e3WlsVjd0/Um12XXcyPFy6ZHdyHHDkT5tt1JtF/rJerqn6Wu+F/ErsWCmPyiRjrYi54KlgZP/k2Tq9gPYSh5APZOYBVra2VicAtfyn+4qZwHt2E4rVJvszPH2HNcVD2lkS5eOxW3b9f1AtplzZkeKFdDLl/wkibodmyrUsmq241raYdye5ECpdrBf+2GQf0ncA4c3gJelHRrHjd03xs+7L9UMHh9lZN149aOSwuOfcnFO3qQmbb0V44aoSVEXlHeikXQzz1/bpzek8E50XN6o4r/KLfQpU/pMx/J/yz9cxmWhDOOyhMqD5SkJjQnKYnmpIlfuVe5XHlSWKw8rC6QoEayoWk7MFwaKg6Whx4AJEBGIBEQGQQFJBaKBlAMpD6QA0gCQIsglICNAxkGYAFIBMgkwDWQGhFkgc0DuApkHsqDmMZAVIKtA1oBUgejqOmc21E1uHwF5DOQJ4C+AfAnkKyBbQL4G8g2Qb4F8B+o2wA6QZ4DrIOyCsAfCcw0lUwR/ZvgiOP3IhwgWcDZIsCipIpJkPmskBBiBgpGiIqQJOJdYPqbiOaRiUcRIQ5hrIfT055ySiKYVzMLKkKmuDM8aAyInyW1yNCOF22Q5I8Xb5FhGSjLR8n/gnv5q+U+9t4/MojnYLtEhc3jljjGCGT4Z7bXL7bG9Udwefz9xjk9Vhl3crtjqqXwifS8hWzblJToZmylTbk+vYuMOjsECWjZnkuDZvTmcwbscGvOiKVcxXThZNGVjkQebS+17pmLcJwl8sI1v4PI2uYEPt4UbuLItxrCwoplgrMagaOZTENf2NK0NryE8gWRCVE3p6ae5j3aOFwyZb8of6RT3FYn7Y9yvmjlDx1mKGncSfVTC9Z/v6QyZE7q5rpsburmpm490U+K/12g6WXYc+nR4CKX/H31zGG1z5m9Pt5okCg==',
+// moviePath: 'http://localhost:8000/tests/js/tests/Bookmarklet/ZeroClipboard.swf',
+ moviePath: 'http://www.clipperz.com/files/clipperz.com/bookmarklet/0.3.0/ZeroClipboard_1.0.4.swf',
+ nextId: 1, // ID of next movie
+
+ $: function(thingy) {
+ // simple DOM lookup utility function
+ if (typeof(thingy) == 'string') thingy = document.getElementById(thingy);
+ if (!thingy.addClass) {
+ // extend element with a few useful methods
+ thingy.hide = function() { this.style.display = 'none'; };
+ thingy.show = function() { this.style.display = ''; };
+ thingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; };
+ thingy.removeClass = function(name) {
+ this.className = this.className.replace( new RegExp("\\s*" + name + "\\s*"), " ").replace(/^\s+/, '').replace(/\s+$/, '');
+ };
+ thingy.hasClass = function(name) {
+ return !!this.className.match( new RegExp("\\s*" + name + "\\s*") );
+ }
+ }
+ return thingy;
+ },
+
+ setMoviePath: function(path) {
+ // set path to ZeroClipboard.swf
+ this.moviePath = path;
+ },
+
+ dispatch: function(id, eventName, args) {
+ // receive event from flash movie, send to client
+ var client = this.clients[id];
+ if (client) {
+ client.receiveEvent(eventName, args);
+ }
+ },
+
+ register: function(id, client) {
+ // register new client to receive events
+ this.clients[id] = client;
+ },
+
+ getDOMObjectPosition: function(obj) {
+ // get absolute coordinates for dom element
+ var info = {
+ left: 0,
+ top: 0,
+ width: obj.width ? obj.width : obj.offsetWidth,
+ height: obj.height ? obj.height : obj.offsetHeight
+ };
+
+ while (obj) {
+ info.left += obj.offsetLeft;
+ info.top += obj.offsetTop;
+ obj = obj.offsetParent;
+ }
+
+ return info;
+ },
+
+ Client: function(elem) {
+ // constructor for new simple upload client
+ this.handlers = {};
+
+ // unique ID
+ this.id = ZeroClipboard.nextId++;
+ this.movieId = 'ZeroClipboardMovie_' + this.id;
+
+ // register client with singleton to receive flash events
+ ZeroClipboard.register(this.id, this);
+
+ // create movie
+ if (elem) this.glue(elem);
+ }
+};
+
+ZeroClipboard.Client.prototype = {
+
+ id: 0, // unique ID for us
+ ready: false, // whether movie is ready to receive events or not
+ movie: null, // reference to movie object
+ clipText: '', // text to copy to clipboard
+ handCursorEnabled: true, // whether to show hand cursor, or default pointer cursor
+ cssEffects: true, // enable CSS mouse effects on dom container
+ handlers: null, // user event handlers
+
+ glue: function(elem) {
+ // glue to DOM element
+ // elem can be ID or actual DOM element object
+//console.log(">>> glue");
+ this.domElement = ZeroClipboard.$(elem);
+
+ // float just above object, or zIndex 99 if dom element isn't set
+ var zIndex = 99;
+ if (this.domElement.style.zIndex) {
+ zIndex = parseInt(this.domElement.style.zIndex) + 1;
+ }
+
+ // find X/Y position of domElement
+ var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
+
+ // create floating DIV above element
+ this.div = document.createElement('div');
+ var style = this.div.style;
+ style.position = 'absolute';
+ style.left = '' + box.left + 'px';
+ style.top = '' + box.top + 'px';
+ style.width = '' + box.width + 'px';
+ style.height = '' + box.height + 'px';
+ style.zIndex = zIndex;
+
+ // style.backgroundColor = '#f00'; // debug
+
+ var body = document.getElementsByTagName('body')[0];
+ body.appendChild(this.div);
+
+ this.div.innerHTML = this.getHTML( box.width, box.height );
+//console.log("<<< glue");
+ },
+
+ getHTML: function(width, height) {
+ // return HTML for movie
+ var html = '';
+ var flashvars = 'id=' + this.id +
+ '&width=' + width +
+ '&height=' + height;
+
+ if (navigator.userAgent.match(/MSIE/)) {
+ // IE gets an OBJECT tag
+ var protocol = location.href.match(/^https/i) ? 'https://' : 'http://';
+ html += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="'+protocol+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'+width+'" height="'+height+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><param name="wmode" value="transparent"/></object>';
+ }
+ else {
+ // all other browsers get an EMBED tag
+ html += '<embed id="'+this.movieId+'" src="'+ZeroClipboard.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+width+'" height="'+height+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'" wmode="transparent" />';
+ }
+ return html;
+ },
+
+ hide: function() {
+ // temporarily hide floater offscreen
+ if (this.div) {
+ this.div.style.left = '-2000px';
+ }
+ },
+
+ show: function() {
+ // show ourselves after a call to hide()
+ this.reposition();
+ },
+
+ destroy: function() {
+ // destroy control and floater
+ if (this.domElement && this.div) {
+ this.hide();
+ this.div.innerHTML = '';
+
+ var body = document.getElementsByTagName('body')[0];
+ try { body.removeChild( this.div ); } catch(e) {;}
+
+ this.domElement = null;
+ this.div = null;
+ }
+ },
+
+ reposition: function(elem) {
+ // reposition our floating div, optionally to new container
+ // warning: container CANNOT change size, only position
+ if (elem) {
+ this.domElement = ZeroClipboard.$(elem);
+ if (!this.domElement) this.hide();
+ }
+
+ if (this.domElement && this.div) {
+ var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
+ var style = this.div.style;
+ style.left = '' + box.left + 'px';
+ style.top = '' + box.top + 'px';
+ }
+ },
+
+ setText: function(newText) {
+ // set text to be copied to clipboard
+ this.clipText = newText;
+ if (this.ready) this.movie.setText(newText);
+ },
+
+ addEventListener: function(eventName, func) {
+ // add user event listener for event
+ // event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel
+ eventName = eventName.toString().toLowerCase().replace(/^on/, '');
+ if (!this.handlers[eventName]) this.handlers[eventName] = [];
+ this.handlers[eventName].push(func);
+ },
+
+ setHandCursor: function(enabled) {
+ // enable hand cursor (true), or default arrow cursor (false)
+ this.handCursorEnabled = enabled;
+ if (this.ready) this.movie.setHandCursor(enabled);
+ },
+
+ setCSSEffects: function(enabled) {
+ // enable or disable CSS effects on DOM container
+ this.cssEffects = !!enabled;
+ },
+
+ receiveEvent: function(eventName, args) {
+ // receive event from flash
+ eventName = eventName.toString().toLowerCase().replace(/^on/, '');
+
+ // special behavior for certain events
+ switch (eventName) {
+ case 'load':
+ // movie claims it is ready, but in IE this isn't always the case...
+ // bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function
+ this.movie = document.getElementById(this.movieId);
+ if (!this.movie) {
+ var self = this;
+ setTimeout( function() { self.receiveEvent('load', null); }, 1 );
+ return;
+ }
+
+ // firefox on pc needs a "kick" in order to set these in certain cases
+ if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {
+ var self = this;
+ setTimeout( function() { self.receiveEvent('load', null); }, 100 );
+ this.ready = true;
+ return;
+ }
+
+ this.ready = true;
+ this.movie.setText( this.clipText );
+ this.movie.setHandCursor( this.handCursorEnabled );
+ break;
+
+ case 'mouseover':
+ if (this.domElement && this.cssEffects) {
+ this.domElement.addClass('hover');
+ if (this.recoverActive) this.domElement.addClass('active');
+ }
+ break;
+
+ case 'mouseout':
+ if (this.domElement && this.cssEffects) {
+ this.recoverActive = false;
+ if (this.domElement.hasClass('active')) {
+ this.domElement.removeClass('active');
+ this.recoverActive = true;
+ }
+ this.domElement.removeClass('hover');
+ }
+ break;
+
+ case 'mousedown':
+ if (this.domElement && this.cssEffects) {
+ this.domElement.addClass('active');
+ }
+ break;
+
+ case 'mouseup':
+ if (this.domElement && this.cssEffects) {
+ this.domElement.removeClass('active');
+ this.recoverActive = false;
+ }
+ break;
+ } // switch eventName
+
+ if (this.handlers[eventName]) {
+ for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) {
+ var func = this.handlers[eventName][idx];
+
+ if (typeof(func) == 'function') {
+ // actual function reference
+ func(this, args);
+ }
+ else if ((typeof(func) == 'object') && (func.length == 2)) {
+ // PHP style object + method, i.e. [myObject, 'myMethod']
+ func[0][ func[1] ](this, args);
+ }
+ else if (typeof(func) == 'string') {
+ // name of function
+ window[func](this, args);
+ }
+ } // foreach event handler defined
+ } // user defined handler for event
+ }
+
+};
+
+//#############################################################################
+
+var clip = null;
+
+function $(id) { return document.getElementById(id); }
+
+function initClip() {
+//console.log(">>> initClip");
+ clip = new ZeroClipboard.Client();
+ clip.setHandCursor( true );
+
+// clip.addEventListener('load', my_load);
+// clip.addEventListener('mouseOver', my_mouse_over);
+ clip.addEventListener('complete', my_complete);
+
+// clip.glue( 'd_clip_button' );
+//console.log("<<< initClip");
+}
+
+//function my_load(client) {
+// console.log("Flash movie loaded and ready.");
+//}
+
+//function my_mouse_over(client) {
+// // we can cheat a little here -- update the text on mouse over
+// clip.setText( $('fe_text').value );
+//}
+
+function my_complete(client, text) {
+// console.log("Copied text to clipboard: ... ");
+// console.log("Copied text to clipboard: " + text );
+ clipperz_copiedContentToClipboard = true;
+ showTooltip();
+}
+
+//function debugstr(msg) {
+// var p = document.createElement('p');
+// p.innerHTML = msg;
+// $('d_debug').appendChild(p);
+//}
+
+//#############################################################################
+
+_cble = null;
+
+//-----------------------------------------------------------------------------
+
+isLoginForm = function(aForm) {
+ var inputFields;
+ var passwordFieldsFound;
+ var i,c;
+
+//console.log("is login form: " + aForm.name + " (" + aForm.id + ")");
+ passwordFieldsFound = 0;
+ inputFields = aForm.elements;
+ c = inputFields.length;
+ for (i=0; i<c; i++) {
+ if (inputFields[i].type == "password") {
+ passwordFieldsFound ++;
+ }
+ }
+//console.log("number of password fields found: " + passwordFieldsFound);
+ return (passwordFieldsFound == 1);
+};
+
+//-----------------------------------------------------------------------------
+
+findLoginForm = function(aDocument, aLevel) {
+ var result;
+ var documentForms;
+ var i,c;
+
+ result = null;
+
+ try {
+ documentForms = aDocument.getElementsByTagName('form');
+
+ c = documentForms.length;
+ for (i=0; (i<c) && (result == null); i++) {
+ if (isLoginForm(documentForms[i])) {
+ result = documentForms[i];
+ }
+ }
+
+ if ((result == null) && (aLevel == 0)) {
+ var iFrames;
+
+ iFrames = aDocument.getElementsByTagName('iframe');
+ c = iFrames.length;
+ for (i=0; (i<c) && (result == null); i++) {
+ result = findLoginForm(iFrames[i].contentDocument, (aLevel + 1));
+ }
+ }
+ } catch (e) {
+ _cble = e;
+ }
+
+ return result;
+};
+
+//-----------------------------------------------------------------------------
+
+inputElementValues = function(anInputElement) {
+ var result;
+
+// if ((anInputElement instanceof HTMLInputElement) && (anInputElement.getAttribute('name') != null)) {
+ if ((anInputElement.tagName.toLowerCase() == "input") && (anInputElement.getAttribute('name') != null)) {
+ result = {};
+ result.type = anInputElement.getAttribute('type') || "text";
+ result.name = anInputElement.getAttribute('name');
+// result.value = anInputElement.getAttribute('value');
+ result.value = anInputElement.value;
+ if (anInputElement.type.toLowerCase() == 'radio') {
+ result.checked = anInputElement.checked;
+ }
+// } else if ((anInputElement instanceof HTMLSelectElement) && (anInputElement.getAttribute('name') != null)) {
+ } else if ((anInputElement.tagName.toLowerCase() == 'select') && (anInputElement.getAttribute('name') != null)) {
+ var options;
+ var c,i;
+
+//console.log("input element values: %o", anInputElement);
+ result = {};
+ result.type = "select";
+ result.name = anInputElement.getAttribute('name');
+
+ result.options = [];
+ options = anInputElement.options;
+ c = options.length;
+ for (i=0; i<c; i++) {
+ var option;
+
+ option = {};
+ option.selected = options[i].selected;
+ option.label = options[i].label || options[i].innerHTML;
+ option.value = options[i].value;
+ result.options.push(option);
+ }
+ } else {
+ result = null;
+ }
+
+ return result;
+};
+
+//-----------------------------------------------------------------------------
+
+formParameters = function(aLoginForm) {
+ var result;
+ var i, c;
+ var action;
+
+ if (aLoginForm == null) {
+ result = null;
+ } else {
+ var radioValues;
+ var radioValueName;
+
+ result = {};
+ radioValues = {};
+
+ action = aLoginForm.action;
+ if (action.constructor != String) {
+ action = aLoginForm.getAttribute('action');
+ }
+
+ if (/^https?\:\/\/.*/.test(action)) {
+ action = action;
+ } else if (/^\/.*/.test(action)) {
+ action = window.location.protocol + '/' + '/' + window.location.hostname + action;
+ } else {
+ action = window.location.href.replace(/\/[^\/]*$/, '/' + action);
+ }
+
+ result.attributes = {};
+ result.attributes.action = action;
+ result.attributes.method = aLoginForm.getAttribute('method');
+
+ result.inputs = [];
+ c = aLoginForm.elements.length;
+ for (i=0; i<c; i++) {
+ var inputElement;
+ var elementValues;
+
+ inputElement = aLoginForm.elements[i];
+ elementValues = inputElementValues(inputElement);
+ if (elementValues != null) {
+ if (elementValues.type != "radio") {
+ result.inputs.push(elementValues);
+ } else {
+ var radioValue;
+ var values;
+
+ radioValue = radioValues[elementValues.name];
+ if (radioValue == null) {
+ radioValue = {};
+ radioValue.name = elementValues.name;
+ radioValue.type = "radio";
+ radioValue.options = [];
+
+ radioValues[elementValues.name] = radioValue;
+ }
+
+ values = {};
+ values.value = elementValues.value;
+ values.checked = elementValues.checked;
+
+ radioValue.options.push(values);
+ }
+ }
+ }
+
+ for (radioValueName in radioValues) {
+ if (typeof(radioValues[radioValueName]) != "function") {
+ result.inputs.push(radioValues[radioValueName]);
+ }
+ }
+ }
+
+ return result;
+};
+
+//-----------------------------------------------------------------------------
+
+pageParameters = function() {
+ var result;
+
+ result = {};
+ result['title'] = document.title;
+//<link rel="icon" href="http://example.com/favicon.ico" type="image/x-icon">
+
+ return result;
+};
+
+//-----------------------------------------------------------------------------
+
+reprString = function (o) {
+ return ('"' + o.replace(/(["\\])/g, '\\$1') + '"'
+ ).replace(/[\f]/g, "\\f"
+ ).replace(/[\b]/g, "\\b"
+ ).replace(/[\n]/g, "\\n"
+ ).replace(/[\t]/g, "\\t"
+ ).replace(/[\r]/g, "\\r");
+};
+
+//-----------------------------------------------------------------------------
+
+serializeJSON = function (o) {
+ var objtype = typeof(o);
+ if (objtype == "number" || objtype == "boolean") {
+ return o + "";
+ } else if (o === null) {
+ return "null";
+ }
+
+// var m = MochiKit.Base;
+// var reprString = m.reprString;
+ if (objtype == "string") {
+ return reprString(o);
+ }
+
+ // recurse
+ var me = arguments.callee;
+ // array
+ if (objtype != "function" && typeof(o.length) == "number") {
+ var res = [];
+ for (var i = 0; i < o.length; i++) {
+ var val = me(o[i]);
+ if (typeof(val) != "string") {
+ val = "undefined";
+ }
+ res.push(val);
+ }
+ return "[" + res.join(",\n") + "]";
+ }
+
+ // undefined is outside of the spec
+ if (objtype == "undefined") {
+// throw new TypeError("undefined can not be serialized as JSON");
+ throw new TypeError("error");
+ }
+
+ // generic object code path
+ res = [];
+ for (var k in o) {
+ if (typeof(o[k]) != "function") {
+ var useKey;
+ if (typeof(k) == "number") {
+ useKey = '"' + k + '"';
+ } else if (typeof(k) == "string") {
+ useKey = reprString(k);
+ } else {
+ // skip non-string or number keys
+ continue;
+ }
+
+ val = me(o[k]);
+ if (typeof(val) != "string") {
+ // skip non-serializable values
+ continue;
+ }
+ res.push(useKey + ":" + " " + val);
+ }
+ }
+
+ return "{" + res.join(",\n") + "}";
+};
+
+//-----------------------------------------------------------------------------
+
+getLoginFormConfiguration = function() {
+ var parameters;
+
+ parameters = {};
+ parameters.page = pageParameters();
+ parameters.form = formParameters(findLoginForm(document, 0));
+ parameters.version = "0.3.0";
+
+ return parameters;
+}
+
+//#############################################################################
+
+//-----------------------------------------------------------------------------
+
+closeClick = function () {
+ var bookmarkletDiv;
+
+ bookmarkletDiv = document.getElementById("clipperzBookmarkletWrapper");
+ bookmarkletDiv.parentNode.removeChild(bookmarkletDiv);
+};
+
+//-----------------------------------------------------------------------------
+
+logFormParameters = function(someParameters, anException) {
+ var showException;
+ var message;
+
+ if ((someParameters != null) && (someParameters.form != null) && (anException == null)) {
+ showException = false;
+ message = "The direct login configuration has been collected.";
+ } else {
+ showException = true
+ message = "Sorry! There was an error while processing the page.";
+ }
+
+ var newCSS = document.createElement('link');
+ newCSS.setAttribute("type", "text/css");
+ newCSS.setAttribute("rel", "stylesheet");
+ newCSS.setAttribute("media", "screen");
+ newCSS.setAttribute("href", "http://www.clipperz.com/files/clipperz.com/bookmarklet/0.3.0/Bookmarklet.css");
+// newCSS.innerHTML = cssHTML;
+ document.getElementsByTagName("head")[0].appendChild(newCSS);
+
+ var innerHTML;
+
+ innerHTML = "";
+// innerHTML += "<div id='clipperzBookmarklet' style='" + reset_css + clipperzBookmarklet_style + "'>" +
+// "<div id='clipperzBookmarkletClose' style='" + reset_css + clipperzBookmarkletClose_style + "'></div>" +
+// "<div id='clipperzBookmarkletResult' style='" + reset_css + clipperzBookmarkletResult_style + "'>" +
+// "<div id='clipperzBookmarkletResultIcon' style='" + reset_css + clipperzBookmarkletResultIcon_style + "'></div>" +
+// "<p id='clipperzBookmarkletResultText' style='" + reset_css + clipperzBookmarkletResultText_style + "'>" + message + "</p>" +
+// "</div>";
+//
+// if (showException == false) {
+// innerHTML +="<div id='clipperzBookmarletButton' style='" + clipperzBookmarletButton_style + "'></div>" +
+// "<div id='clipperzBookmarletAfterCopyHint' style='" + clipperzBookmarletAfterCopyHint_style + "'>" +
+// "<p id='clipperzBookmarkletHintText' style='" + clipperzBookmarkletHintText_style + "'></p>" +
+// "</div>";
+// }
+
+ innerHTML += "<div id='clipperzBookmarklet'>" +
+ "<div id='clipperzBookmarkletClose'></div>" +
+ "<div id='clipperzBookmarkletResult'>" +
+ "<div id='clipperzBookmarkletResultIcon'></div>" +
+ "<p id='clipperzBookmarkletResultText'>" + message + "</p>" +
+ "</div>";
+
+ if (showException == false) {
+ innerHTML += "<div id='clipperzBookmarletButton'></div>" +
+ "<div id='clipperzBookmarletAfterCopyHint' class='hidden'>" +
+ "<p id='clipperzBookmarkletHintText'>Lorem ipsum</p>" +
+ "</div>";
+ }
+
+ innerHTML += "</div>";
+
+ var newDiv = document.createElement('div');
+ newDiv.setAttribute("id", "clipperzBookmarkletWrapper");
+ newDiv.innerHTML = innerHTML;
+ document.body.appendChild(newDiv);
+
+ $('clipperzBookmarkletClose').onclick = closeClick;
+
+ if (showException == false) {
+ $('clipperzBookmarletButton').onclick = showTooltip;
+ setTimeout("clip.glue('clipperzBookmarletButton');", 1000);
+ }
+}
+
+showTooltip = function () {
+ if (clipperz_copiedContentToClipboard == true) {
+//console.log("SUCCEED");
+ $('clipperzBookmarkletHintText').innerHTML = "DONE!";
+ $('clipperzBookmarletAfterCopyHint').className = 'visible';
+ } else {
+//console.log("FAIL");
+ $('clipperzBookmarkletHintText').innerHTML = "Failed! :(";
+ }
+}
+
+//#############################################################################
+
+//#############################################################################
+
+runBookmarklet = function () {
+ var parameters;
+
+ try {
+ initClip();
+
+ parameters = getLoginFormConfiguration();
+//console.log("configuration", serializeJSON(parameters))
+ clip.setText(serializeJSON(parameters));
+// clip.glue('clipperzBookmarletButton');
+
+ logFormParameters(parameters, _cble);
+ } catch (e) {
+ logFormParameters(parameters, e);
+ }
+
+}
+
+//#############################################################################
+
+if (document.body != null) {
+ runBookmarklet();
+}
+
+//#############################################################################
diff --git a/frontend/gamma/js/Bookmarklet_IE.js b/frontend/gamma/js/Bookmarklet_IE.js
new file mode 100644
index 0000000..6b3e5c0
--- a/dev/null
+++ b/frontend/gamma/js/Bookmarklet_IE.js
@@ -0,0 +1,23 @@
+//
+// IE limit: 508 characters!!!!!
+//
+
+loadClipperzBookmarklet = function() {
+ var headNode;
+ var clipperzScript;
+
+ clipperzScript = document.getElementById('clipperzScript');
+ headNode = document.getElementsByTagName("head").item(0);
+
+ if (clipperzScript) {
+ headNode.removeChild(clipperzScript);
+ }
+
+ clipperzScript = document.createElement('script');
+ clipperzScript.setAttribute('src', 'http%3a%2f%2fclipperz.com%2ffiles%2fclipperz.com%2fbookmarklet%2fBookmarklet.js');
+ clipperzScript.setAttribute('type', 'text/javascript');
+ clipperzScript.setAttribute('defer', true);
+ headNode.appendChild(clipperzScript);
+};
+
+loadClipperzBookmarklet();
diff --git a/frontend/gamma/js/Clipperz/Async.js b/frontend/gamma/js/Clipperz/Async.js
new file mode 100644
index 0000000..e80c3a2
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Async.js
@@ -0,0 +1,707 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//Clipperz.Async = MochiKit.Async;
+
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.Async) == 'undefined') { Clipperz.Async = {}; }
+
+Clipperz.Async.VERSION = "0.1";
+Clipperz.Async.NAME = "Clipperz.Async";
+
+Clipperz.Async.Deferred = function(aName, args) {
+ args = args || {};
+
+ Clipperz.Async.Deferred.superclass.constructor.call(this, args.canceller);
+
+ this._args = args;
+ this._name = aName || "Anonymous deferred";
+ this._count = 0;
+ this._shouldTrace = ((CLIPPERZ_DEFERRED_TRACING_ENABLED === true) || (args.trace === true));
+ this._vars = null;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.Async.Deferred, MochiKit.Async.Deferred, {
+
+ 'name': function () {
+ return this._name;
+ },
+
+ 'args': function () {
+ return this._args;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'callback': function (aValue) {
+ if (this._shouldTrace) {
+ Clipperz.log("CALLBACK " + this._name, aValue);
+ }
+
+ if (this.chained == false) {
+ var message;
+
+ message = "ERROR [" + this._name + "]";
+ this.addErrback(function(aResult) {
+ if (! (aResult instanceof MochiKit.Async.CancelledError)) {
+ Clipperz.log(message, aResult);
+ }
+ return aResult;
+ });
+
+ if (this._shouldTrace) {
+ var resultMessage;
+
+ resultMessage = "RESULT " + this._name + " <==";
+// this.addCallback(function(aResult) {
+ Clipperz.Async.Deferred.superclass.addCallback.call(this, function(aResult) {
+ Clipperz.log(resultMessage, aResult);
+
+ return aResult;
+ });
+ }
+ }
+
+ if (CLIPPERZ_DEFERRED_CALL_LOGGING_ENABLED === true) {
+ Clipperz.log("callback " + this._name, this);
+ }
+
+ return Clipperz.Async.Deferred.superclass.callback.apply(this, arguments);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'addCallback': function () {
+ var message;
+
+ if (this._shouldTrace) {
+ this._count ++;
+ message = "[" + this._count + "] " + this._name + " ";
+// this.addBoth(function(aResult) {Clipperz.log(message + "-->", aResult); return aResult;});
+ this.addCallbacks(
+ function(aResult) {Clipperz.log("-OK- " + message + "-->"/*, aResult*/); return aResult;},
+ function(aResult) {Clipperz.log("FAIL " + message + "-->"/*, aResult*/); return aResult;}
+ );
+ }
+
+ Clipperz.Async.Deferred.superclass.addCallback.apply(this, arguments);
+
+ if (this._shouldTrace) {
+// this.addBoth(function(aResult) {Clipperz.log(message + "<--", aResult); return aResult;});
+ this.addCallbacks(
+ function(aResult) {Clipperz.log("-OK- " + message + "<--", aResult); return aResult;},
+ function(aResult) {Clipperz.log("FAIL " + message + "<--", aResult); return aResult;}
+ );
+ }
+ },
+
+ //=============================================================================
+
+ 'addCallbackPass': function() {
+ var passFunction;
+
+ passFunction = MochiKit.Base.partial.apply(null, arguments);
+
+ this.addCallback(function() {
+ var result;
+
+ result = arguments[arguments.length -1];
+ passFunction();
+
+ return result;
+ });
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'addErrbackPass': function() {
+ var passFunction;
+
+ passFunction = MochiKit.Base.partial.apply(null, arguments);
+
+ this.addErrback(function() {
+ var result;
+
+ result = arguments[arguments.length -1];
+ passFunction();
+
+ return result;
+ });
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'addBothPass': function() {
+ var passFunction;
+
+ passFunction = MochiKit.Base.partial.apply(null, arguments);
+
+ this.addBoth(function() {
+ var result;
+
+ result = arguments[arguments.length -1];
+ passFunction();
+
+ return result;
+ });
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'addIf': function (aThenBlock, anElseBlock) {
+ this.addCallback(MochiKit.Base.bind(function (aValue) {
+ var deferredResult;
+
+ if (!MochiKit.Base.isUndefinedOrNull(aValue) && aValue) {
+ deferredResult = Clipperz.Async.callbacks(this._name + " <then>", aThenBlock, null, aValue);
+ } else {
+ deferredResult = Clipperz.Async.callbacks(this._name + " <else>", anElseBlock, null, aValue);
+ }
+
+ return deferredResult;
+ }))
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'addMethod': function () {
+ this.addCallback(MochiKit.Base.method.apply(this, arguments));
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'addMethodcaller': function () {
+ this.addCallback(MochiKit.Base.methodcaller.apply(this, arguments));
+ },
+
+ //=============================================================================
+
+ 'addLog': function (aLog) {
+ if (CLIPPERZ_DEFERRED_LOGGING_ENABLED) {
+ this.addBothPass(function(res) {Clipperz.log(aLog + " ", res);});
+// this.addBothPass(function(res) {console.log(aLog + " ", res);});
+ }
+ },
+
+ //=============================================================================
+
+ 'acquireLock': function (aLock) {
+// this.addCallback(function (aResult) {
+// return Clipperz.Async.callbacks("Clipperz.Async.acquireLock", [
+// MochiKit.Base.method(aLock, 'acquire'),
+// MochiKit.Base.partial(MochiKit.Async.succeed, aResult)
+// ], {trace:false});
+// });
+
+ this.addCallback(MochiKit.Base.method(aLock, 'acquire'));
+ },
+
+ 'releaseLock': function (aLock) {
+// this.addCallback(function (aResult) {
+// return Clipperz.Async.callbacks("Clipperz.Async.release <ok>", [
+// MochiKit.Base.method(aLock, 'release'),
+// MochiKit.Base.partial(MochiKit.Async.succeed, aResult)
+// ], {trace:false});
+// });
+// this.addErrback(function (aResult) {
+///console.log("releaseLock.addErrback:", aResult);
+// return Clipperz.Async.callbacks("Clipperz.Async.release <fail>", [
+// MochiKit.Base.method(aLock, 'release'),
+// MochiKit.Base.partial(MochiKit.Async.fail, aResult)
+// ], {trace:false});
+// });
+
+// this.addBothPass(MochiKit.Base.method(aLock, 'release'));
+ this.addCallbackPass(MochiKit.Base.method(aLock, 'release'));
+ this.addErrback(function (anError) {
+ aLock.release();
+
+ return anError;
+ });
+ },
+
+ //=============================================================================
+
+ 'collectResults': function (someRequests) {
+ this.addCallback(Clipperz.Async.collectResults(this._name + " <collect results>", someRequests, this._args));
+ },
+
+ 'addCallbackList': function (aRequestList) {
+ this.addCallback(Clipperz.Async.callbacks, this._name + " <callback list>", aRequestList, this._args);
+ },
+
+ //=============================================================================
+
+ 'vars': function () {
+ if (this._vars == null) {
+ this._vars = {}
+ }
+
+ return this._vars;
+ },
+
+ 'setValue': function (aKey) {
+ this.addCallback(MochiKit.Base.bind(function (aValue) {
+ this.vars()[aKey] = aValue;
+ return aValue;
+ }, this));
+ },
+
+ 'getValue': function (aKey) {
+ this.addCallback(MochiKit.Base.bind(function () {
+ return this.vars()[aKey];
+ }, this));
+ },
+
+ //=============================================================================
+
+ __syntaxFix__: "syntax fix"
+});
+
+//#############################################################################
+
+Clipperz.Async.DeferredSynchronizer = function(aName, someMethods) {
+ this._name = aName || "Anonymous deferred Synchronizer";
+ this._methods = someMethods;
+
+ this._numberOfMethodsDone = 0;
+ this._methodResults = [];
+
+ this._result = new Clipperz.Async.Deferred("Clipperz.Async.DeferredSynchronizer # " + this.name(), {trace:false});
+ this._result.addMethod(this, 'methodResults');
+ this._result.addCallback(function(someResults) {
+ var cancels;
+ var errors;
+ var result;
+
+ cancels = MochiKit.Base.filter(function(aResult) { return (aResult instanceof MochiKit.Async.CancelledError)}, someResults);
+
+ if (cancels.length == 0) {
+ errors = MochiKit.Base.filter(function(aResult) { return (aResult instanceof Error)}, someResults);
+
+ if (errors.length == 0) {
+// result = MochiKit.Async.succeed(someResults);
+ result = someResults;
+ } else {
+ result = MochiKit.Async.fail(someResults);
+ }
+ } else {
+ result = MochiKit.Async.fail(cancels[0]);
+ }
+
+ return result;
+ }/*, this._methodResults */);
+
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.Async.DeferredSynchronizer.prototype, {
+
+ //-----------------------------------------------------------------------------
+
+ 'name': function() {
+ return this._name;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'methods': function() {
+ return this._methods;
+ },
+
+ 'methodResults': function() {
+ return this._methodResults;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'result': function() {
+ return this._result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'numberOfMethodsDone':function() {
+ return this._numberOfMethodsDone;
+ },
+
+ 'incrementNumberOfMethodsDone': function() {
+ this._numberOfMethodsDone ++;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'run': function(args, aValue) {
+ var deferredResults;
+ var i, c;
+
+ deferredResults = [];
+ args = args || {};
+
+ c = this.methods().length;
+ for (i=0; i<c; i++) {
+ var deferredResult;
+ var methodCalls;
+ var ii, cc;
+
+//console.log("TYPEOF", typeof(this.methods()[i]));
+ if (typeof(this.methods()[i]) == 'function') {
+ methodCalls = [ this.methods()[i] ];
+ } else {
+ methodCalls = this.methods()[i];
+ }
+
+ cc = methodCalls.length;
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.Async.DeferredSynchronizer.run => " + this.name() + "[" + i + "]", args);
+ for (ii=0; ii<cc; ii++) {
+ deferredResult.addCallback(methodCalls[ii]);
+ }
+ deferredResult.addBoth(MochiKit.Base.method(this, 'handleMethodCallDone', i));
+
+ deferredResults.push(deferredResult);
+ }
+
+ for (i=0; i<c; i++) {
+ deferredResults[i].callback(aValue);
+ }
+
+ return this.result();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleMethodCallDone': function(anIndexValue, aResult) {
+ this.incrementNumberOfMethodsDone();
+ this.methodResults()[anIndexValue] = aResult;
+
+ if (this.numberOfMethodsDone() < this.methods().length) {
+ // nothing to do here other than possibly log something
+ } else if (this.numberOfMethodsDone() == this.methods().length) {
+ this.result().callback();
+ } else if (this.numberOfMethodsDone() > this.methods().length) {
+ // WTF!!! :(
+ }
+
+ },
+
+ //-----------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+});
+
+//#############################################################################
+
+MochiKit.Base.update(Clipperz.Async, {
+
+ 'callbacks': function (aName, someFunctions, someArguments, aCallbackValue) {
+ var deferredResult;
+ var i, c;
+
+ deferredResult = new Clipperz.Async.Deferred(aName, someArguments);
+ c = someFunctions.length;
+ for (i=0; i<c; i++) {
+ deferredResult.addCallback(someFunctions[i]);
+ }
+ deferredResult.callback(aCallbackValue);
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'forkAndJoin': function (aName, someMethods, args) {
+ return MochiKit.Base.partial(function (aName, someMethods, args, aValue) {
+ var synchronizer;
+ var result;
+
+ args = args || {};
+ synchronizer = new Clipperz.Async.DeferredSynchronizer(aName, someMethods);
+ result = synchronizer.run(args, aValue);
+
+ return result;
+ }, aName, someMethods, args);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'collectResults': function(aName, someRequests, args) {
+ return MochiKit.Base.partial(function(aName, someRequests, args, aValue) {
+ var deferredResult;
+ var requestKeys;
+ var methods;
+
+ requestKeys = MochiKit.Base.keys(someRequests);
+ methods = MochiKit.Base.values(someRequests);
+
+ deferredResult = new Clipperz.Async.Deferred(aName, args);
+ deferredResult.addCallback(Clipperz.Async.forkAndJoin(aName + " [inner forkAndJoin]", methods, args));
+ deferredResult.addBoth(function(someResults) {
+ var returnFunction;
+ var results;
+ var i,c;
+ var result;
+
+ if (someResults instanceof MochiKit.Async.CancelledError) {
+ returnFunction = MochiKit.Async.fail;
+ result = someResults;
+ } else {
+ if (someResults instanceof Error) {
+ returnFunction = MochiKit.Async.fail;
+ results = someResults['message'];
+ } else {
+ returnFunction = MochiKit.Async.succeed;
+ results = someResults;
+ }
+
+ result = {};
+
+ c = requestKeys.length;
+ for (i=0; i<c; i++) {
+ result[requestKeys[i]] = results[i];
+ }
+ }
+
+ return returnFunction.call(null, result);
+ });
+ deferredResult.callback(aValue);
+
+ return deferredResult;
+ }, aName, someRequests, args);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'collectAll': function (someDeferredObjects) {
+ var deferredResult;
+
+ deferredResult = new MochiKit.Async.DeferredList(someDeferredObjects, false, false, false);
+ deferredResult.addCallback(function (aResultList) {
+ return MochiKit.Base.map(function (aResult) {
+ if (aResult[0]) {
+ return aResult[1];
+ } else {
+ throw aResult[1];
+ }
+ }, aResultList);
+ });
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setItem': function (anObject, aKey, aValue) {
+ anObject[aKey] = aValue;
+
+ return anObject;
+ },
+
+ 'setItemOnObject': function (aKey, aValue, anObject) {
+ anObject[aKey] = aValue;
+
+ return anObject;
+ },
+
+ 'setDeferredItemOnObject': function (aKey, aDeferredFunction, anObject) {
+ return Clipperz.Async.callbacks("Clipperz.Async.setDeferredItemOnObject", [
+ aDeferredFunction,
+ MochiKit.Base.partial(Clipperz.Async.setItem, anObject, aKey)
+ ], {trace:false}, anObject);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredIf': function (aName, aThenBlock, anElseBlock) {
+ return function (aValue) {
+ var deferredResult;
+
+ if (!MochiKit.Base.isUndefinedOrNull(aValue) && aValue) {
+ deferredResult = Clipperz.Async.callbacks(aName + " <then>", aThenBlock, null, aValue);
+ } else {
+ deferredResult = Clipperz.Async.callbacks(aName + " <else>", anElseBlock, null, aValue);
+ }
+
+ return deferredResult;
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'log': function(aMessage, aResult) {
+ if (CLIPPERZ_DEFERRED_LOGGING_ENABLED) {
+ Clipperz.log(aMessage + " ", aResult);
+ }
+
+ return aResult;
+ },
+
+ //=========================================================================
+
+ 'deferredCompare': function (aComparator, aDeferred, bDeferred) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.Async.deferredCompare", {trace:false});
+ deferredResult.addCallback(Clipperz.Async.collectAll, [aDeferred, bDeferred]);
+ deferredResult.addCallback(function (someResults) {
+ var result;
+
+ if (aComparator(someResults[0], someResults[1]) > 0) {
+ result = MochiKit.Async.succeed();
+ } else {
+ result = MochiKit.Async.fail();
+ };
+
+ return result;
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'insertIntoSortedArray': function (anObject, aDeferredComparator, aSortedResult) {
+ var deferredResult;
+ var i, c;
+
+ if (aSortedResult.length == 0) {
+ deferredResult = MochiKit.Async.succeed([anObject]);
+ } else {
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.Async.insertIntoSortedArray", {trace:false});
+ c = aSortedResult.length + 1;
+ for (i=0; i<c; i++) {
+ deferredResult.addCallback(function (aDeferredComparator, aObject, bObject, aContext) {
+ var innerDeferredResult;
+
+ innerDeferredResult = new Clipperz.Async.Deferred("Clipperz.Async.insertIntoSortedArray <inner compare>", {trace:false});
+ innerDeferredResult.addCallback(aDeferredComparator, aObject, bObject);
+ innerDeferredResult.addErrback(MochiKit.Async.fail, aContext);
+ innerDeferredResult.callback();
+
+ return innerDeferredResult;
+ }, aDeferredComparator, anObject, aSortedResult[i], i);
+ }
+ deferredResult.addMethod(aSortedResult, 'push', anObject);
+ deferredResult.addErrback(function (anError) {
+ aSortedResult.splice(anError.message, 0, anObject);
+ })
+ deferredResult.addBoth(MochiKit.Async.succeed, aSortedResult);
+ deferredResult.callback();
+ }
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredSort': function (aDeferredComparator, someObjects) {
+ var deferredResult;
+ var i, c;
+
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.Async.deferredSort", {trace:false});
+ c = someObjects.length;
+ for (i=0; i<c; i++) {
+ deferredResult.addCallback(Clipperz.Async.insertIntoSortedArray, someObjects[i], aDeferredComparator);
+ if ((i % 50) == 0) {
+// console.log("######### sort wait ##########");
+ deferredResult.addCallback(MochiKit.Async.wait, 0.5);
+ }
+ }
+ deferredResult.callback([]);
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'deferredFilter': function (aFunction, someObjects) {
+ var deferredResult;
+ var i, c;
+
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.Async.deferredFilter", {trace:false});
+ c = someObjects.length;
+ for (i=0; i<c; i++) {
+ deferredResult.addCallback(function (aFunction, anObject, anIndex, aResult) {
+ var innerDeferredResult;
+
+ innerDeferredResult = new Clipperz.Async.Deferred("Clipperz.Async.deferredFilter <inner - " + anIndex + ">", {trace:false});
+ innerDeferredResult.addCallback(aFunction, anObject);
+ innerDeferredResult.addCallback(function (aFilterResult) {
+ if (aFilterResult) {
+ aResult.push(anObject);
+ };
+ });
+ innerDeferredResult.addBoth(MochiKit.Async.succeed, aResult);
+ innerDeferredResult.callback();
+
+ return innerDeferredResult;
+ }, aFunction, someObjects[i], i);
+ }
+ deferredResult.callback([]);
+
+ return deferredResult;
+ },
+
+ 'forEach': function (aFunction) {
+ return MochiKit.Base.partial(function (aFunction, anIterable) {
+ MochiKit.Iter.forEach(anIterable, aFunction);
+ }, aFunction);
+ },
+
+ //=========================================================================
+
+ 'or': function (someValues) {
+ return Clipperz.Async.callbacks("Clipperz.Async.or", [
+ MochiKit.Base.values,
+ MochiKit.Base.flattenArguments,
+//function (aValue) { console.log("Record.hasAnyCleanTextData - flatten", aValue); return aValue; },
+ function(someInnerValues) {
+ return MochiKit.Iter.some(someInnerValues, MochiKit.Base.operator.identity);
+ }
+ ], {trace:false}, someValues);
+ },
+
+ //=========================================================================
+
+ 'clearResult': function () {},
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
+//#############################################################################
+
+CLIPPERZ_DEFERRED_LOGGING_ENABLED = true;
+CLIPPERZ_DEFERRED_TRACING_ENABLED = false;
+CLIPPERZ_DEFERRED_CALL_LOGGING_ENABLED = false;
diff --git a/frontend/gamma/js/Clipperz/Base.js b/frontend/gamma/js/Clipperz/Base.js
new file mode 100644
index 0000000..7f321ef
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Base.js
@@ -0,0 +1,531 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.Base) == 'undefined') { Clipperz.Base = {}; }
+
+Clipperz.Base.VERSION = "0.2";
+Clipperz.Base.NAME = "Clipperz.Base";
+
+MochiKit.Base.update(Clipperz.Base, {
+
+ //-------------------------------------------------------------------------
+
+ '__repr__': function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return this.__repr__();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'itemgetter': function (aKeyPath) {
+// return MochiKit.Base.compose.apply(null, [MochiKit.Base.itemgetter('key3')]);
+ return MochiKit.Base.compose.apply(null,
+ MochiKit.Base.map(
+ MochiKit.Base.itemgetter,
+ MochiKit.Iter.reversed(
+ aKeyPath.split('.')
+ )
+ )
+ );
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isUrl': function (aValue) {
+ return (MochiKit.Base.urlRegExp.test(aValue));
+ },
+
+ 'isEmail': function (aValue) {
+ return (MochiKit.Base.emailRegExp.test(aValue));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'caseInsensitiveCompare': function (a, b) {
+ return MochiKit.Base.compare(a.toLowerCase(), b.toLowerCase());
+ },
+
+ 'reverseComparator': function (aComparator) {
+ return MochiKit.Base.compose(function(aResult) { return -aResult; }, aComparator);
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'dependsOn': function(module, deps) {
+ if (!(module in Clipperz)) {
+ MochiKit[module] = {};
+ }
+
+ if (typeof(dojo) != 'undefined') {
+ dojo.provide('Clipperz.' + module);
+ }
+ for (var i = 0; i < deps.length; i++) {
+ if (typeof(dojo) != 'undefined') {
+ dojo.require('Clipperz.' + deps[i]);
+ }
+ if (typeof(JSAN) != 'undefined') {
+ JSAN.use('Clipperz.' + deps[i], []);
+ }
+ if (!(deps[i] in Clipperz)) {
+ throw 'Clipperz.' + module + ' depends on Clipperz.' + deps[i] + '!'
+ }
+ }
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'trim': function (aValue) {
+ return aValue.replace(/^\s+|\s+$/g, "");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'stringToByteArray': function (aValue) {
+ var result;
+ var i, c;
+
+ result = [];
+
+ c = aValue.length;
+ for (i=0; i<c; i++) {
+ result[i] = aValue.charCodeAt(i);
+ }
+
+ return result;
+ },
+
+ //.........................................................................
+
+ 'byteArrayToString': function (anArrayOfBytes) {
+ var result;
+ var i, c;
+
+ result = "";
+
+ c = anArrayOfBytes.length;
+ for (i=0; i<c; i++) {
+ result += String.fromCharCode(anArrayOfBytes[i]);
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getValueForKeyInFormContent': function (aFormContent, aKey) {
+ return aFormContent[1][MochiKit.Base.find(aFormContent[0], aKey)];
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'indexOfObjectInArray': function(anObject, anArray) {
+ var result;
+ var i, c;
+
+ result = -1;
+
+ c = anArray.length;
+ for (i=0; ((i<c) && (result < 0)); i++) {
+ if (anArray[i] === anObject) {
+ result = i;
+ }
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'removeObjectAtIndexFromArray': function(anIndex, anArray) {
+ anArray.splice(anIndex, 1);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'removeObjectFromArray': function(anObject, anArray) {
+ var objectIndex;
+
+ objectIndex = Clipperz.Base.indexOfObjectInArray(anObject, anArray);
+ if (objectIndex > -1) {
+ Clipperz.Base.removeObjectAtIndexFromArray(objectIndex, anArray);
+ } else {
+ Clipperz.log("Trying to remove an object not present in the array");
+ throw Clipperz.Base.exception.ObjectNotFound;
+ }
+ },
+
+ 'removeFromArray': function(anArray, anObject) {
+ return Clipperz.Base.removeObjectFromArray(anObject, anArray);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'splitStringAtFixedTokenSize': function(aString, aTokenSize) {
+ var result;
+ var stringToProcess;
+
+ stringToProcess = aString;
+ result = [];
+ if (stringToProcess != null) {
+ while (stringToProcess.length > aTokenSize) {
+ result.push(stringToProcess.substring(0, aTokenSize));
+ stringToProcess = stringToProcess.substring(aTokenSize);
+ }
+
+ result.push(stringToProcess);
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'objectType': function(anObject) {
+ var result;
+
+ if (anObject == null) {
+ result = null;
+ } else {
+ result = typeof(anObject);
+
+ if (result == "object") {
+ if (anObject instanceof Array) {
+ result = 'array'
+ } else if (anObject.constructor == Boolean) {
+ result = 'boolean'
+ } else if (anObject instanceof Date) {
+ result = 'date'
+ } else if (anObject instanceof Error) {
+ result = 'error'
+ } else if (anObject instanceof Function) {
+ result = 'function'
+ } else if (anObject.constructor == Number) {
+ result = 'number'
+ } else if (anObject.constructor == String) {
+ result = 'string'
+ } else if (anObject instanceof Object) {
+ result = 'object'
+ } else {
+ throw Clipperz.Base.exception.UnknownType;
+ }
+ }
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'escapeHTML': function(aValue) {
+ var result;
+
+ result = aValue;
+ result = result.replace(/</g, "&lt;");
+ result = result.replace(/>/g, "&gt;");
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deepClone': function(anObject) {
+ var result;
+
+ result = Clipperz.Base.evalJSON(Clipperz.Base.serializeJSON(anObject));
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+// 'deepCompare': function (aObject, bObject) {
+// return (Clipperz.Base.serializeJSON(aObject) == Clipperz.Base.serializeJSON(bObject));
+// },
+
+ //-------------------------------------------------------------------------
+
+ 'evalJSON': function(aString) {
+ return JSON.parse(aString);
+ },
+
+ 'serializeJSON': function(anObject) {
+ return JSON.stringify(anObject);
+ },
+
+ 'formatJSON': function (anObject, sIndent) {
+ var realTypeOf = function (v) {
+ if (typeof(v) == "object") {
+ if (v === null) return "null";
+ if (v.constructor == (new Array).constructor) return "array";
+ if (v.constructor == (new Date).constructor) return "date";
+ if (v.constructor == (new RegExp).constructor) return "regex";
+ return "object";
+ }
+ return typeof(v);
+ };
+
+// function FormatJSON(oData, sIndent) {
+ if (arguments.length < 2) {
+ var sIndent = "";
+ }
+// var sIndentStyle = " ";
+ var sIndentStyle = " ";
+ var sDataType = realTypeOf(anObject);
+
+ // open object
+ if (sDataType == "array") {
+ if (anObject.length == 0) {
+ return "[]";
+ }
+ var sHTML = "[";
+ } else if (sDataType == "object") {
+ var sHTML = "{";
+ } else {
+ return "{}";
+ }
+// } else {
+// var iCount = 0;
+// $.each(anObject, function() {
+// iCount++;
+// return;
+// });
+// if (iCount == 0) { // object is empty
+// return "{}";
+// }
+// var sHTML = "{";
+// }
+
+ // loop through items
+ var iCount = 0;
+// $.each(anObject, function(sKey, vValue) {
+ MochiKit.Iter.forEach(MochiKit.Base.keys(anObject), function(sKey) {
+ var vValue = anObject[sKey];
+
+ if (iCount > 0) {
+ sHTML += ",";
+ }
+ if (sDataType == "array") {
+ sHTML += ("\n" + sIndent + sIndentStyle);
+ } else {
+ sHTML += ("\n" + sIndent + sIndentStyle + "\"" + sKey + "\"" + ": ");
+ }
+
+ // display relevant data type
+ switch (realTypeOf(vValue)) {
+ case "array":
+ case "object":
+ sHTML += Clipperz.Base.formatJSON(vValue, (sIndent + sIndentStyle));
+ break;
+ case "boolean":
+ case "number":
+ sHTML += vValue.toString();
+ break;
+ case "null":
+ sHTML += "null";
+ break;
+ case "string":
+ sHTML += ("\"" + vValue + "\"");
+ break;
+ default:
+ sHTML += ("TYPEOF: " + typeof(vValue));
+ }
+
+ // loop
+ iCount++;
+ });
+
+ // close object
+ if (sDataType == "array") {
+ sHTML += ("\n" + sIndent + "]");
+ } else {
+ sHTML += ("\n" + sIndent + "}");
+ }
+
+ // return
+ return sHTML;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'mergeItems': function (anArrayOfValues) {
+ var result;
+ var i, c;
+
+ result = {};
+
+ c = anArrayOfValues.length;
+ for (i=0; i<c; i++) {
+ result[anArrayOfValues[i][0]] = anArrayOfValues[i][1];
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'map': function (fn, lstObj/*, lst... */) {
+ var result;
+
+ if (MochiKit.Base.isArrayLike(lstObj)) {
+ result = MochiKit.Base.map.apply(this, arguments);
+ } else {
+ var keys;
+ var values;
+ var computedValues;
+
+ keys = MochiKit.Base.keys(lstObj);
+ values = MochiKit.Base.values(lstObj);
+ computedValues = MochiKit.Base.map(fn, values);
+
+ result = Clipperz.Base.mergeItems(MochiKit.Base.zip(keys, computedValues));
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'sanitizeString': function(aValue) {
+ var result;
+
+ if (Clipperz.Base.objectType(aValue) == 'string') {
+ result = aValue;
+ result = result.replace(/</img,"&lt;");
+ result = result.replace(/>/img,"&gt;");
+ } else {
+ result = aValue;
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'module': function(aValue) {
+// aValue = 'Clipperz.PM.Compact'
+//
+// if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+// if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+// if (typeof(Clipperz.PM.UI.Common.Components) == 'undefined') { Clipperz.PM.UI.Common.Components = {}; }
+
+//console.log(">>> module: " + aValue);
+ var currentScope;
+ var pathElements;
+ var i,c;
+
+ currentScope = window;
+ pathElements = aValue.split('.');
+ c = pathElements.length;
+ for (i=0; i<c; i++) {
+//console.log("--- current path element: " + pathElements[i]);
+//console.log("--- current scope", currentScope);
+ if (typeof(currentScope[pathElements[i]]) == 'undefined') {
+ currentScope[pathElements[i]] = {};
+ }
+
+ currentScope = currentScope[pathElements[i]];
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'exception': {
+ 'AbstractMethod': new MochiKit.Base.NamedError("Clipperz.Base.exception.AbstractMethod"),
+ 'UnknownType': new MochiKit.Base.NamedError("Clipperz.Base.exception.UnknownType"),
+ 'VulnerabilityIssue': new MochiKit.Base.NamedError("Clipperz.Base.exception.VulnerabilityIssue"),
+ 'MandatoryParameter': new MochiKit.Base.NamedError("Clipperz.Base.exception.MandatoryParameter"),
+ 'ObjectNotFound': new MochiKit.Base.NamedError("Clipperz.Base.exception.ObjectNotFound"),
+ 'raise': function (aName) {
+ throw Clipperz.Base.exception[aName];
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'extend': YAHOO.extendX,
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
+// Original regExp courtesy of John Gruber: http://daringfireball.net/2009/11/liberal_regex_for_matching_urls
+// Updated to match Clipperz usage pattern.
+//MochiKit.Base.urlRegExp = new RegExp(/\b(([\w-]+:\/\/?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|\/)))/);
+MochiKit.Base.urlRegExp = new RegExp(/^((([\w-]+:\/\/?)|(www\.))[^\s()<>]+((?:\([\w\d]+\)|([^[:punct:]\s]|\/)))?)/);
+
+// RegExp found here: http://www.tipsntracks.com/117/validate-an-email-address-using-regular-expressions.html
+MochiKit.Base.emailRegExp = new RegExp(/^([a-zA-Z0-9_\-\.]+)@(([a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3}))|(([01]?\d\d?|2[0-4]\d|25[0-5])\.){3}([01]?\d\d?|25[0-5]|2[0-4]\d))$/);
+
+
+MochiKit.Base.registerComparator('Object dummy comparator',
+ function(a, b) {
+ return ((a.constructor == Object) && (b.constructor == Object));
+ },
+ function(a, b) {
+ var result;
+ var aKeys;
+ var bKeys;
+
+//MochiKit.Logging.logDebug(">>> comparator");
+//MochiKit.Logging.logDebug("- a: " + Clipperz.Base.serializeJSON(a));
+//MochiKit.Logging.logDebug("- b: " + Clipperz.Base.serializeJSON(a));
+ aKeys = MochiKit.Base.keys(a).sort();
+ bKeys = MochiKit.Base.keys(b).sort();
+
+ result = MochiKit.Base.compare(aKeys, bKeys);
+//if (result != 0) {
+// MochiKit.Logging.logDebug("- comparator 'keys':");
+// MochiKit.Logging.logDebug("- comparator aKeys: " + Clipperz.Base.serializeJSON(aKeys));
+// MochiKit.Logging.logDebug("- comparator bKeys: " + Clipperz.Base.serializeJSON(bKeys));
+//}
+ if (result == 0) {
+ var i, c;
+
+ c = aKeys.length;
+ for (i=0; (i<c) && (result == 0); i++) {
+ result = MochiKit.Base.compare(a[aKeys[i]], b[bKeys[i]]);
+//if (result != 0) {
+// MochiKit.Logging.logDebug("- comparator 'values':");
+// MochiKit.Logging.logDebug("- comparator a[aKeys[i]]: " + Clipperz.Base.serializeJSON(a[aKeys[i]]));
+// MochiKit.Logging.logDebug("- comparator b[bKeys[i]]: " + Clipperz.Base.serializeJSON(b[bKeys[i]]));
+//}
+ }
+ }
+
+//MochiKit.Logging.logDebug("<<< comparator - result: " + result);
+ return result;
+ },
+ true
+);
diff --git a/frontend/gamma/js/Clipperz/ByteArray.js b/frontend/gamma/js/Clipperz/ByteArray.js
new file mode 100644
index 0000000..86136c8
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/ByteArray.js
@@ -0,0 +1,1501 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+
+//=============================================================================
+
+Clipperz.ByteArray_abstract = function(args) {
+ return this;
+}
+
+Clipperz.ByteArray_abstract.prototype = MochiKit.Base.update(null, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function() {
+ return "Clipperz.ByteArray_abstract";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'equals': function(aValue) {
+ return (this.compare(aValue) == 0);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'compare': function(aValue) {
+ var result;
+ var i;
+
+ result = MochiKit.Base.compare(this.length(), aValue.length());
+ i = this.length();
+
+ while ((result == 0) && (i>0)) {
+ i--;
+ result = MochiKit.Base.compare(this.byteAtIndex(i), aValue.byteAtIndex(i));
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'clone': function() {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'newInstance': function() {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'reset': function() {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'length': function() {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'checkByteValue': function(aValue) {
+//Clipperz.log("aValue", aValue.toString(16));
+//Clipperz.log("(aValue & 0xff)", (aValue & 0xff).toString(16));
+
+ if ((aValue & 0xff) != aValue) {
+ MochiKit.Logging.logError("Clipperz.ByteArray.appendByte: the provided value (0x" + aValue.toString(16) + ") is not a byte value.");
+ throw Clipperz.ByteArray.exception.InvalidValue;
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'xorMergeWithBlock': function(aBlock, anAllignment, paddingMode) {
+ var result;
+ var a, b;
+ var aLength;
+ var bLength;
+ var i, c;
+
+ if (this.length() > aBlock.length()) {
+ a = this;
+ b = aBlock;
+ } else {
+ a = aBlock;
+ b = this;
+ }
+
+ aLength = a.length();
+ bLength = b.length();
+
+ if (aLength != bLength) {
+ if (paddingMode == 'truncate') {
+ if (anAllignment == 'left') {
+ a = a.split(0, bLength);
+ } else {
+ a = a.split(aLength - bLength);
+ }
+ } else {
+ var ii, cc;
+ var padding;
+
+// padding = new Clipperz.ByteArray();
+ padding = this.newInstance();
+ cc = aLength - bLength;
+ for (ii=0; ii<cc; ii++) {
+ padding.appendByte(0);
+ }
+
+ if (anAllignment == 'left') {
+ b = b.appendBlock(padding);
+ } else {
+ b = padding.appendBlock(b);
+ }
+ }
+ }
+
+
+// result = new Clipperz.ByteArray();
+ result = this.newInstance();
+ c = a.length();
+ for (i=0; i<c; i++) {
+ result.appendByte(a.byteAtIndex(i) ^ b.byteAtIndex(i));
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'shiftLeft': function(aNumberOfBitsToShift) {
+ var result;
+
+ result = this.clone(); // ???????????
+
+ return result;
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'appendBlock': function(aBlock) {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'appendByte': function(aValue) {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ 'appendBytes': function(args) {
+ var values;
+ var i,c;
+
+ if (args.constructor == Array) {
+ values = args;
+ } else {
+ values = arguments;
+ }
+
+ c = values.length;
+ for (i=0; i<c; i++) {
+ this.appendByte(values[i]);
+ }
+
+ return this;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'appendWord': function(aValue, isLittleEndian) {
+ var result;
+ var processAsLittleEndian;
+
+ processAsLittleEndian = isLittleEndian === true ? true : false;
+
+ if (processAsLittleEndian) {
+ result = this.appendBytes( (aValue) & 0xff, (aValue >> 8) & 0xff, (aValue >> 16) & 0xff, (aValue >> 24) & 0xff ); // little endian
+ } else {
+ result = this.appendBytes( (aValue >> 24) & 0xff, (aValue >> 16) & 0xff, (aValue >> 8) & 0xff, (aValue) & 0xff ); // big endian - DEFAULT
+ }
+
+ return result;
+ },
+
+ 'appendWords': function(args) {
+ var values;
+ var i,c;
+
+ if (args.constructor == Array) {
+ values = args;
+ } else {
+ values = arguments;
+ }
+
+ c = values.length;
+ for (i=0; i<c; i++) {
+ this.appendWord(values[i], false);
+ }
+
+ return this;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'appendBigEndianWords': function(args) {
+ var values;
+ var i,c;
+
+ if (args.constructor == Array) {
+ values = args;
+ } else {
+ values = arguments;
+ }
+
+ c = values.length;
+ for (i=0; i<c; i++) {
+ this.appendWord(values[i], true);
+ }
+
+ return this;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'appendBinaryString': function (aBinaryString) {
+ var i,c;
+
+ c = aBinaryString.length;
+ for (i=0; i<c; i++) {
+ this.appendByte(aBinaryString.charCodeAt(i));
+ };
+
+ return this;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'byteAtIndex': function(anIndex) {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ 'setByteAtIndex': function(aValue, anIndex) {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'bitAtIndex': function(aBitPosition) {
+ var result;
+ var bytePosition;
+ var bitPositionInSelectedByte;
+ var selectedByte;
+ var selectedByteMask;
+
+ bytePosition = this.length() - Math.ceil((aBitPosition + 1)/ 8);
+ bitPositionInSelectedByte = aBitPosition % 8;
+ selectedByte = this.byteAtIndex(bytePosition);
+
+ if (bitPositionInSelectedByte > 0) {
+ selectedByteMask = (1 << bitPositionInSelectedByte);
+ } else {
+ selectedByteMask = 1;
+ }
+ result = selectedByte & selectedByteMask ? 1 : 0;
+//console.log("aBitPosition: " + aBitPosition + ", length: " + this.length() + ", bytePosition: " + bytePosition + ", bitPositionInSelectedByte: " + bitPositionInSelectedByte + ", selectedByteMask: " + selectedByteMask);
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'bitBlockAtIndexWithSize': function(aBitPosition, aSize) {
+ var result;
+ var bitValue;
+ var i,c;
+
+ result = 0;
+ c = aSize;
+ for (i=0; i<c; i++) {
+ bitValue = this.bitAtIndex(aBitPosition + i);
+ result = result | bitValue << i;
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'asString': function() {
+ var result;
+ var length;
+ var i;
+
+//var startTime = new Date();
+
+//# result = "";
+ result = [];
+
+ i = 0;
+ length = this.length();
+
+ while (i < length) {
+ var currentCharacter;
+ var currentByte;
+ var unicode;
+
+ currentByte = this.byteAtIndex(i);
+
+ if ((currentByte & 0x80) == 0x00 ) { // 0xxxxxxx
+ unicode = currentByte;
+ currentCharacter = String.fromCharCode(unicode);
+ } else if ((currentByte & 0xe0) == 0xc0 ) { // 110xxxxx 10xxxxxx
+ unicode = (currentByte & 0x1f) << 6;
+ i++; currentByte = this.byteAtIndex(i);
+ unicode = unicode | (currentByte & 0x3f);
+
+ currentCharacter = String.fromCharCode(unicode);
+ } else if ((currentByte & 0xf0) == 0xe0 ) { // 1110xxxx 10xxxxxx 10xxxxxx
+ unicode = (currentByte & 0x0f) << (6+6);
+ i++; currentByte = this.byteAtIndex(i);
+ unicode = unicode | ((currentByte & 0x3f) << 6);
+ i++; currentByte = this.byteAtIndex(i);
+ unicode = unicode | (currentByte & 0x3f);
+
+ currentCharacter = String.fromCharCode(unicode);
+ } else { // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ unicode = (currentByte & 0x07) << (6+6+6);
+ i++; currentByte = this.byteAtIndex(i);
+ unicode = unicode | ((currentByte & 0x3f) << (6+6));
+ i++; currentByte = this.byteAtIndex(i);
+ unicode = unicode | ((currentByte & 0x3f) << 6);
+ i++; currentByte = this.byteAtIndex(i);
+ unicode = unicode | (currentByte & 0x3f);
+
+ currentCharacter = String.fromCharCode(unicode);
+ }
+
+// result += currentCharacter;
+ result.push(currentCharacter);
+ i++;
+ }
+
+//MochiKit.Logging.logDebug("[" + (new Date() - startTime) + "] ByteArray.asString");
+
+// return result;
+ return result.join("");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toHexString': function() {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'base64map': "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
+ 'base64mapIndex': "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(''),
+// 'base64mapInvertedIndex': {
+// 'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5, 'G': 6, 'H': 7, 'I': 8, 'J': 9,
+// 'K': 10, 'L': 11, 'M': 12, 'N': 13, 'O': 14, 'P': 15, 'Q': 16, 'R': 17, 'S': 18, 'T': 19,
+// 'U': 20, 'V': 21, 'W': 22, 'X': 23, 'Y': 24, 'Z': 25, 'a': 26, 'b': 27, 'c': 28, 'd': 29,
+// 'e': 30, 'f': 31, 'g': 32, 'h': 33, 'i': 34, 'j': 35, 'k': 36, 'l': 37, 'm': 38, 'n': 39,
+// 'o': 40, 'p': 41, 'q': 42, 'r': 43, 's': 44, 't': 45, 'u': 46, 'v': 47, 'w': 48, 'x': 49,
+// 'y': 50, 'z': 51, '0': 52, '1': 53, '2': 54, '3': 55, '4': 56, '5': 57, '6': 58, '7': 59,
+// '8': 60, '9': 61, '+': 62, '/': 63,
+// "=": -1},
+
+ //-------------------------------------------------------------------------
+
+ 'appendBase64String': function(aValue) {
+ var i;
+ var length;
+
+ length = aValue.length;
+
+ if ((length % 4) != 0) {
+ MochiKit.Logging.logError("the value passed to the 'ByteArray.setBase64Value' is not correct");
+ throw Clipperz.ByteArray.exception.InvalidValue;
+ }
+
+ i = 0;
+ while (i<length) {
+ var value1, value2, value3, value4;
+ var byte1, byte2, byte3;
+
+ value1 = this.base64map.indexOf(aValue.charAt(i));
+ value2 = this.base64map.indexOf(aValue.charAt(i+1));
+ value3 = this.base64map.indexOf(aValue.charAt(i+2));
+ value4 = this.base64map.indexOf(aValue.charAt(i+3));
+
+// value1 = this.base64mapInvertedIndex[aValue.charAt(i)];
+// value2 = this.base64mapInvertedIndex[aValue.charAt(i+1)];
+// value3 = this.base64mapInvertedIndex[aValue.charAt(i+2)];
+// value4 = this.base64mapInvertedIndex[aValue.charAt(i+3)];
+
+ byte1 = (value1 << 2) | ((value2 & 0x30) >> 4);
+ if (value3 != -1) {
+ byte2 = ((value2 & 0x0f) << 4) | ((value3 & 0x3c) >> 2);
+
+ if (value4 != -1) {
+ byte3 = ((value3 & 0x03) << 6) | (value4);
+ } else {
+ byte3 = null;
+ }
+ } else {
+ byte2 = null;
+ byte3 = null;
+ }
+
+ this.appendByte(byte1);
+ this.appendByte(byte2);
+ this.appendByte(byte3);
+
+ i += 4;
+ }
+
+ return this;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toBase64String': function() {
+ var result;
+ var length;
+ var i;
+ var byte1, byte2, byte3;
+ var char1, char2, char3, char4;
+
+ i = 0;
+ length = this.length();
+ result = new Array(Math.ceil(length/3));
+
+ while (i < length) {
+ byte1 = this.byteAtIndex(i);
+ if ((i+2) < length) {
+ byte2 = this.byteAtIndex(i+1);
+ byte3 = this.byteAtIndex(i+2);
+ } else if ((i+2) == length) {
+ byte2 = this.byteAtIndex(i+1);
+ byte3 = null;
+ } else {
+ byte2 = null;
+ byte3 = null;
+ }
+
+ char1 = this.base64mapIndex[byte1 >> 2];
+ if (byte2 != null) {
+ char2 = this.base64mapIndex[((byte1 & 0x03) << 4) | ((byte2 & 0xf0) >> 4)];
+ if (byte3 != null) {
+ char3 = this.base64mapIndex[((byte2 & 0x0f) << 2) | ((byte3 & 0xc0) >> 6)];
+ char4 = this.base64mapIndex[(byte3 & 0x3f)];
+ } else {
+ char3 = this.base64mapIndex[(byte2 & 0x0f) << 2];
+ char4 = "=";
+ }
+ } else {
+ char2 = this.base64mapIndex[(byte1 & 0x03) << 4];
+ char3 = "=";
+ char4 = "=";
+ }
+
+ result.push(char1 + char2 + char3 + char4);
+
+ i += 3;
+ }
+
+ return result.join("");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'base32map': "0123456789abcdefghjkmnpqrstvwxyz",
+ 'base32mapIndex': "0123456789abcdefghjkmnpqrstvwxyz".split(''),
+
+ //-------------------------------------------------------------------------
+
+ 'appendBase32String': function(aValue) {
+ var value;
+ var i;
+ var length;
+ var value1, value2, value3, value4, value5, value6, value7, value8;
+ var byte1, byte2, byte3, byte4, byte5;
+
+ value = aValue.toLowerCase();
+ value = value.replace(/[\s\-]/g, '');
+ value = value.replace(/[0o]/g, '0');
+ value = value.replace(/[1il]/g, '1');
+
+ length = value.length;
+
+ if ((length % 8) != 0) {
+ MochiKit.Logging.logError("the value passed to the 'ByteArray.setBase32Value' is not correct");
+ throw Clipperz.ByteArray.exception.InvalidValue;
+ }
+
+ i = 0;
+ while (i<length) {
+ value1 = this.base32map.indexOf(value.charAt(i));
+ value2 = this.base32map.indexOf(value.charAt(i+1));
+ value3 = this.base32map.indexOf(value.charAt(i+2));
+ value4 = this.base32map.indexOf(value.charAt(i+3));
+ value5 = this.base32map.indexOf(value.charAt(i+4));
+ value6 = this.base32map.indexOf(value.charAt(i+5));
+ value7 = this.base32map.indexOf(value.charAt(i+6));
+ value8 = this.base32map.indexOf(value.charAt(i+7));
+
+ byte1 = byte2 = byte3 = byte4 = byte5 = null;
+
+ byte1 = (value1 << 3) | ((value2 & 0x1c) >> 2);
+ if (value3 != -1) {
+ byte2 = ((value2 & 0x03) << 6) | (value3 << 1) | ((value4 & 0x10) >> 4);
+ if (value5 != -1) {
+ byte3 = ((value4 & 0x0f) << 4) | ((value5 & 0x1e) >> 1);
+ if (value6 != -1) {
+ byte4 = ((value5 & 0x01) << 7) | (value6 << 2) | ((value7 & 0x18) >> 3);
+ if (value8 != -1) {
+ byte5 = ((value7 & 0x07) << 5) | (value8);
+ }
+ }
+ }
+ }
+
+ this.appendByte(byte1);
+ this.appendByte(byte2);
+ this.appendByte(byte3);
+ this.appendByte(byte4);
+ this.appendByte(byte5);
+
+ i += 8;
+ }
+
+ return this;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toBase32String': function() {
+ var result;
+ var length;
+ var i;
+ var byte1, byte2, byte3, byte4, byte5;
+ var char1, char2, char3, char4, char5, char6, char7, char8;
+
+ i = 0;
+ length = this.length();
+ result = new Array(Math.ceil(length/5));
+
+ while (i < length) {
+ byte1 = this.byteAtIndex(i);
+
+ if ((i+4) < length) {
+ byte2 = this.byteAtIndex(i+1);
+ byte3 = this.byteAtIndex(i+2);
+ byte4 = this.byteAtIndex(i+3);
+ byte5 = this.byteAtIndex(i+4);
+ } else if ((i+4) == length) {
+ byte2 = this.byteAtIndex(i+1);
+ byte3 = this.byteAtIndex(i+2);
+ byte4 = this.byteAtIndex(i+3);
+ byte5 = null;
+ } else if ((i+3) == length) {
+ byte2 = this.byteAtIndex(i+1);
+ byte3 = this.byteAtIndex(i+2);
+ byte4 = null;
+ byte5 = null;
+ } else if ((i+2) == length) {
+ byte2 = this.byteAtIndex(i+1);
+ byte3 = null;
+ byte4 = null;
+ byte5 = null;
+ } else {
+ byte2 = null;
+ byte3 = null;
+ byte4 = null;
+ byte5 = null;
+ }
+
+
+ char1 = this.base32mapIndex[byte1 >> 3];
+ char2 = char3 = char4 = char5 = char6 = char7 = char8 = "=";
+
+ if (byte2 != null) {
+ char2 = this.base32mapIndex[((byte1 & 0x07) << 2) | ((byte2 & 0xc0) >> 6)];
+ char3 = this.base32mapIndex[((byte2 & 0x3e) >> 1)];
+ if (byte3 != null) {
+ char4 = this.base32mapIndex[((byte2 & 0x01) << 4) | ((byte3 & 0xf0) >> 4)];
+ if (byte4 != null) {
+ char5 = this.base32mapIndex[((byte3 & 0x0f) << 1) | ((byte4 & 0x80) >> 7)];
+ char6 = this.base32mapIndex[(byte4 & 0x7c) >> 2];
+ if (byte5 != null) {
+ char7 = this.base32mapIndex[((byte4 & 0x03) << 3) | ((byte5 & 0xe0) >> 5)];
+ char8 = this.base32mapIndex[(byte5 & 0x1f)];
+ } else {
+ char7 = this.base32mapIndex[(byte4 & 0x03) << 3];
+ }
+ } else {
+ char5 = this.base32mapIndex[(byte3 & 0x0f) << 1];
+ }
+
+ } else {
+ char4 = this.base32mapIndex[(byte2 & 0x01) << 4];
+ }
+ } else {
+ char2 = this.base32mapIndex[(byte1 & 0x07) << 2];
+ }
+
+ result.push(char1 + char2 + char3 + char4 + char5 + char6 + char7 + char8);
+ i += 5;
+ }
+
+ return result.join("");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toBinaryString': function () {
+ var i, c;
+ var result;
+
+ result = '';
+
+ c = this.length();
+ for (i=0; i<c; i++) {
+ result += String.fromCharCode(this.byteAtIndex(i));
+ }
+
+ return result;
+ },
+
+
+ //-------------------------------------------------------------------------
+
+ 'split': function(aStartingIndex, anEndingIndex) {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'increment': function() {
+ var i;
+ var done;
+
+ done = false;
+ i = this.length() - 1;
+
+ while ((i>=0) && (done == false)) {
+ var currentByteValue;
+
+ currentByteValue = this.byteAtIndex(i);
+
+ if (currentByteValue == 0xff) {
+ this.setByteAtIndex(0, i);
+ if (i>= 0) {
+ i --;
+ } else {
+ done = true;
+ }
+ } else {
+ this.setByteAtIndex(currentByteValue + 1, i);
+ done = true;
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'arrayValues': function() {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
+//=============================================================================
+//
+// Clipperz.ByteArray_hex
+//
+//=============================================================================
+/*
+Clipperz.ByteArray_hex = function (args) {
+ this._value = "";
+
+ if (typeof(args) != 'undefined') {
+ if (args.constructor == Array) {
+ this.appendBytes(args);
+ } else if (args.constructor == String) {
+ if (args.indexOf("0x") == 0) {
+ var value;
+
+ value = args.substring(2).toLowerCase();
+ if (/[0123456789abcdef]* /.test(value)) { the space in the regexp shoud be removed if the code is activate
+ if ((value.length % 2) == 0) {
+ this._value = value;
+ } else {
+ this._value = "0" + value;
+ }
+ } else {
+MochiKit.Logging.logError("Clipperz.ByteArray should be inizialized with an hex string.");
+ throw Clipperz.ByteArray.exception.InvalidValue;
+ }
+ } else {
+ var value;
+ var i,c;
+
+ c = args.length;
+ value = new Array(c);
+ for (i=0; i<c; i++) {
+ value.push(Clipperz.ByteArray.unicodeToUtf8HexString(args.charCodeAt(i)));
+ }
+
+ this._value = value.join("");
+ }
+ } else {
+ this.appendBytes(MochiKit.Base.extend(null, arguments));
+ }
+ }
+ return this;
+}
+
+Clipperz.ByteArray_hex.prototype = MochiKit.Base.update(new Clipperz.ByteArray_abstract(), {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function() {
+ return "Clipperz.ByteArray_hex";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'clone': function() {
+ var result;
+
+ result = this.newInstance();
+ result._value = this._value;
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'newInstance': function() {
+ return new Clipperz.ByteArray_hex();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'reset': function() {
+ this._value = "";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'length': function() {
+ return (this._value.length / 2);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'appendBlock': function(aBlock) {
+ this._value = this._value += aBlock.toHexString().substring(2);
+
+ return this;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'appendByte': function(aValue) {
+ if (aValue != null) {
+ this.checkByteValue(aValue);
+ this._value += Clipperz.ByteArray.byteToHex(aValue);
+ }
+
+ return this;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'byteAtIndex': function(anIndex) {
+ return parseInt(this._value.substr(anIndex*2, 2), 16);
+ },
+
+ 'setByteAtIndex': function(aValue, anIndex) {
+ var missingBytes;
+
+ this.checkByteValue(aValue);
+
+ missingBytes = anIndex - this.length();
+
+ if (missingBytes < 0) {
+ var currentValue;
+ var firstCutIndex;
+ var secondCutIndex;
+
+ firstCutIndex = anIndex * 2;
+ secondCutIndex = firstCutIndex + 2;
+ currentValue = this._value;
+ this._value = currentValue.substring(0, firstCutIndex) +
+ Clipperz.ByteArray.byteToHex(aValue) +
+ currentValue.substring(secondCutIndex);
+ } else if (missingBytes == 0) {
+ this.appendByte(aValue);
+ } else {
+ var i,c;
+
+ c = missingBytes;
+ for (i=0; i<c; i++) {
+ this.appendByte(0);
+ }
+
+ this.appendByte(aValue);
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toHexString': function() {
+ return "0x" + this._value;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'split': function(aStartingIndex, anEndingIndex) {
+ var result;
+ var startingIndex;
+ var endingIndex;
+
+ result = this.newInstance();
+
+ startingIndex = aStartingIndex * 2;
+ if (typeof(anEndingIndex) != 'undefined') {
+ endingIndex = anEndingIndex * 2;
+ result._value = this._value.substring(startingIndex, endingIndex);
+ } else {
+ result._value = this._value.substring(startingIndex);
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'arrayValues': function() {
+ var result;
+ var i,c;
+
+ c = this.length();
+
+ result = new Array(c);
+ for (i=0; i<c; i++) {
+ result[i] = this.byteAtIndex(i);
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+*/
+
+//=============================================================================
+//
+// Clipperz.ByteArray_array
+//
+//=============================================================================
+
+Clipperz.ByteArray_array = function (args) {
+ if (typeof(args) != 'undefined') {
+ if (args.constructor == Array) {
+ this._value = args.slice(0);
+ } else if (args.constructor == String) {
+ var result;
+ var value;
+ var i, c;
+
+ if (args.indexOf("0x") == 0) {
+
+ value = args.substring(2).toLowerCase();
+ if (/[0123456789abcdef]*/.test(value)) {
+ if ((value.length % 2) != 0) {
+ value = "0" + value;
+ }
+ } else {
+MochiKit.Logging.logError("Clipperz.ByteArray should be inizialized with an hex string.");
+ throw Clipperz.ByteArray.exception.InvalidValue;
+ }
+
+ c = value.length / 2
+ result = new Array(c);
+ for (i=0; i<c; i++) {
+ result[i] = parseInt(value.substr(i*2, 2), 16);
+ }
+
+ } else {
+ var unicode;
+ result = [];
+ c = args.length;
+ for (i=0; i<c; i++) {
+// Clipperz.ByteArray.pushUtf8BytesOfUnicodeChar(result, args.charCodeAt(i));
+
+ unicode = args.charCodeAt(i);
+ if (unicode <= 0x7f) { // 0x00000000 - 0x0000007f -> 0xxxxxxx
+ result.push(unicode);
+ // } else if ((unicode >= 0x80) && (unicode <= 0x7ff)) { // 0x00000080 - 0x000007ff -> 110xxxxx 10xxxxxx
+ } else if (unicode <= 0x7ff) { // 0x00000080 - 0x000007ff -> 110xxxxx 10xxxxxx
+ result.push((unicode >> 6) | 0xc0);
+ result.push((unicode & 0x3F) | 0x80);
+ // } else if ((unicode >= 0x0800) && (unicode <= 0xffff)) { // 0x00000800 - 0x0000ffff -> 1110xxxx 10xxxxxx 10xxxxxx
+ } else if (unicode <= 0xffff) { // 0x00000800 - 0x0000ffff -> 1110xxxx 10xxxxxx 10xxxxxx
+ result.push((unicode >> 12) | 0xe0);
+ result.push(((unicode >> 6) & 0x3f) | 0x80);
+ result.push((unicode & 0x3f) | 0x80);
+ } else { // 0x00010000 - 0x001fffff -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ result.push((unicode >> 18) | 0xf0);
+ result.push(((unicode >> 12) & 0x3f) | 0x80);
+ result.push(((unicode >> 6) & 0x3f) | 0x80);
+ result.push((unicode & 0x3f) | 0x80);
+ }
+ }
+ }
+
+
+ this._value = result;
+ } else {
+ this._value = [];
+ this.appendBytes(MochiKit.Base.extend(null, arguments));
+ }
+ } else {
+ this._value = [];
+ }
+
+ return this;
+}
+
+Clipperz.ByteArray_array.prototype = MochiKit.Base.update(new Clipperz.ByteArray_abstract(), {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function() {
+ return "Clipperz.ByteArray_array";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'clone': function() {
+ var result;
+
+ result = this.newInstance();
+ result.appendBytes(this._value);
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'newInstance': function() {
+ return new Clipperz.ByteArray_array();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'reset': function() {
+ this._value = [];
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'length': function() {
+ return (this._value.length);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'appendBlock': function(aBlock) {
+ MochiKit.Base.extend(this._value, aBlock._value);
+
+ return this;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'appendByte': function(aValue) {
+ if (aValue != null) {
+ this.checkByteValue(aValue);
+ this._value.push(aValue);
+ }
+
+ return this;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'byteAtIndex': function(anIndex) {
+ return this._value[anIndex];
+ },
+
+ 'setByteAtIndex': function(aValue, anIndex) {
+ var missingBytes;
+
+ this.checkByteValue(aValue);
+
+ missingBytes = anIndex - this.length();
+
+ if (missingBytes < 0) {
+ this._value[anIndex] = aValue;
+ } else if (missingBytes == 0) {
+ this._value.push(aValue);
+ } else {
+ var i,c;
+
+ c = missingBytes;
+ for (i=0; i<c; i++) {
+ this._value.push(0);
+ }
+
+ this._value.push(aValue);
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toHexString': function() {
+ var result;
+ var i, c;
+
+ result = "0x";
+ c = this.length();
+ for (i=0; i<c; i++) {
+ result += Clipperz.ByteArray.byteToHex(this._value[i]);
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'split': function(aStartingIndex, anEndingIndex) {
+ var result;
+
+ result = this.newInstance();
+ result._value = this._value.slice(aStartingIndex, anEndingIndex ? anEndingIndex : this.length());
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'arrayValues': function() {
+ return this._value.slice(0);
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+
+
+
+
+//=============================================================================
+//
+// Clipperz.ByteArray_string
+//
+//=============================================================================
+/*
+Clipperz.ByteArray_string = function (args) {
+ this._value = "";
+
+ if (typeof(args) != 'undefined') {
+ if (args.constructor == Array) {
+ this.appendBytes(args);
+ } else if (args.constructor == String) {
+ var result;
+ var value;
+ var i, c;
+
+ if (args.indexOf("0x") == 0) {
+
+ value = args.substring(2).toLowerCase();
+ if (/[0123456789abcdef]* /.test(value)) { the space in the regexp shoud be removed if the code is activated
+ if ((value.length % 2) != 0) {
+ value = "0" + value;
+ }
+ } else {
+MochiKit.Logging.logError("Clipperz.ByteArray should be inizialized with an hex string.");
+ throw Clipperz.ByteArray.exception.InvalidValue;
+ }
+ } else {
+ value = "";
+ c = args.length;
+ for (i=0; i<c; i++) {
+ value += Clipperz.ByteArray.unicodeToUtf8HexString(args.charCodeAt(i));
+ }
+ }
+
+ c = value.length / 2
+ for (i=0; i<c; i++) {
+ this.appendByte(parseInt(value.substr(i*2, 2), 16));
+ }
+ } else {
+ this.appendBytes(MochiKit.Base.extend(null, arguments));
+ }
+ }
+
+ return this;
+}
+
+Clipperz.ByteArray_string.prototype = MochiKit.Base.update(new Clipperz.ByteArray_abstract(), {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function() {
+ return "Clipperz.ByteArray_string";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'clone': function() {
+ var result;
+
+ result = this.newInstance();
+ result._value = this._value;
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'newInstance': function() {
+ return new Clipperz.ByteArray_string();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'reset': function() {
+ this._value = "";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'length': function() {
+ return (this._value.length);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'appendBlock': function(aBlock) {
+ this._value += aBlock._value;
+
+ return this;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'appendByte': function(aValue) {
+ if (aValue != null) {
+ this.checkByteValue(aValue);
+ this._value += String.fromCharCode(aValue);
+ }
+
+ return this;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'byteAtIndex': function(anIndex) {
+ return this._value.charCodeAt(anIndex);
+ },
+
+ 'setByteAtIndex': function(aValue, anIndex) {
+ var missingBytes;
+
+ this.checkByteValue(aValue);
+
+ missingBytes = anIndex - this.length();
+
+ if (missingBytes < 0) {
+ this._value = this._value.substring(0, anIndex) + String.fromCharCode(aValue) + this._value.substring(anIndex + 1);
+ } else if (missingBytes == 0) {
+ this.appendByte(aValue);
+ } else {
+ var i,c;
+
+ c = missingBytes;
+ for (i=0; i<c; i++) {
+ this.appendByte(0);
+ }
+
+ this.appendByte(aValue);
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toHexString': function() {
+ var result;
+ var i, c;
+
+ result = "0x";
+ c = this.length();
+ for (i=0; i<c; i++) {
+ result += Clipperz.ByteArray.byteToHex(this.byteAtIndex(i));
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'split': function(aStartingIndex, anEndingIndex) {
+ var result;
+ result = this.newInstance();
+ result._value = this._value.substring(aStartingIndex, anEndingIndex ? anEndingIndex : this.length());
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'arrayValues': function() {
+ var result;
+ var i,c;
+
+ c = this.length();
+
+ result = new Array(c);
+ for (i=0; i<c; i++) {
+ result[i] = this.byteAtIndex(i);
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+*/
+
+//=============================================================================
+//
+// Clipperz.ByteArray
+//
+//=============================================================================
+
+Clipperz.ByteArray = Clipperz.ByteArray_array;
+//Clipperz.ByteArray = Clipperz.ByteArray_string;
+//Clipperz.ByteArray = Clipperz.ByteArray_hex;
+
+//#############################################################################
+
+Clipperz.ByteArray.byteToHex = function(aByte) {
+ return ((aByte < 16) ? "0" : "") + aByte.toString(16);
+}
+
+
+Clipperz.ByteArray.unicodeToUtf8HexString = function(aUnicode) {
+ var result;
+ var self;
+
+ self = Clipperz.ByteArray;
+
+ if (aUnicode <= 0x7f) { // 0x00000000 - 0x0000007f -> 0xxxxxxx
+ result = self.byteToHex(aUnicode);
+// } else if ((aUnicode >= 0x80) && (aUnicode <= 0x7ff)) { // 0x00000080 - 0x000007ff -> 110xxxxx 10xxxxxx
+ } else if (aUnicode <= 0x7ff) { // 0x00000080 - 0x000007ff -> 110xxxxx 10xxxxxx
+ result = self.byteToHex((aUnicode >> 6) | 0xc0);
+ result += self.byteToHex((aUnicode & 0x3F) | 0x80);
+// } else if ((aUnicode >= 0x0800) && (aUnicode <= 0xffff)) { // 0x00000800 - 0x0000ffff -> 1110xxxx 10xxxxxx 10xxxxxx
+ } else if (aUnicode <= 0xffff) { // 0x00000800 - 0x0000ffff -> 1110xxxx 10xxxxxx 10xxxxxx
+ result = self.byteToHex((aUnicode >> 12) | 0xe0);
+ result += self.byteToHex(((aUnicode >> 6) & 0x3f) | 0x80);
+ result += self.byteToHex((aUnicode & 0x3f) | 0x80);
+ } else { // 0x00010000 - 0x001fffff -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ result = self.byteToHex((aUnicode >> 18) | 0xf0);
+ result += self.byteToHex(((aUnicode >> 12) & 0x3f) | 0x80);
+ result += self.byteToHex(((aUnicode >> 6) & 0x3f) | 0x80);
+ result += self.byteToHex((aUnicode & 0x3f) | 0x80);
+ }
+
+ return result;
+}
+
+Clipperz.ByteArray.pushUtf8BytesOfUnicodeChar = function(anArray, aUnicode) {
+ var self;
+
+ self = Clipperz.ByteArray;
+
+ if (aUnicode <= 0x7f) { // 0x00000000 - 0x0000007f -> 0xxxxxxx
+ anArray.push(aUnicode);
+// } else if ((aUnicode >= 0x80) && (aUnicode <= 0x7ff)) { // 0x00000080 - 0x000007ff -> 110xxxxx 10xxxxxx
+ } else if (aUnicode <= 0x7ff) { // 0x00000080 - 0x000007ff -> 110xxxxx 10xxxxxx
+ anArray.push((aUnicode >> 6) | 0xc0);
+ anArray.push((aUnicode & 0x3F) | 0x80);
+// } else if ((aUnicode >= 0x0800) && (aUnicode <= 0xffff)) { // 0x00000800 - 0x0000ffff -> 1110xxxx 10xxxxxx 10xxxxxx
+ } else if (aUnicode <= 0xffff) { // 0x00000800 - 0x0000ffff -> 1110xxxx 10xxxxxx 10xxxxxx
+ anArray.push((aUnicode >> 12) | 0xe0);
+ anArray.push(((aUnicode >> 6) & 0x3f) | 0x80);
+ anArray.push((aUnicode & 0x3f) | 0x80);
+ } else { // 0x00010000 - 0x001fffff -> 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+ anArray.push((aUnicode >> 18) | 0xf0);
+ anArray.push(((aUnicode >> 12) & 0x3f) | 0x80);
+ anArray.push(((aUnicode >> 6) & 0x3f) | 0x80);
+ anArray.push((aUnicode & 0x3f) | 0x80);
+ }
+}
+
+Clipperz.ByteArray.prefixMatchingBits = function (aValue, bValue) {
+ var result;
+ var i,c;
+
+ result = 0;
+
+ c = Math.min(aValue.length(), bValue.length());
+ i = 0;
+ while (i<c && (aValue.byteAtIndex(i) == bValue.byteAtIndex(i))) {
+ result += 8;
+ i++;
+ }
+
+ if (i<c) {
+ var xorValue;
+
+ xorValue = (aValue.byteAtIndex(i) ^ bValue.byteAtIndex(i));
+
+ if (xorValue >= 128) {
+ result += 0;
+ } else if (xorValue >= 64) {
+ result += 1;
+ } else if (xorValue >= 32) {
+ result += 2;
+ } else if (xorValue >= 16) {
+ result += 3;
+ } else if (xorValue >= 8) {
+ result += 4;
+ } else if (xorValue >= 4) {
+ result += 5;
+ } else if (xorValue >= 2) {
+ result += 6;
+ } else if (xorValue >= 1) {
+ result += 7;
+ }
+ }
+
+ return result;
+};
+
+Clipperz.ByteArray.exception = {
+ InvalidValue: new MochiKit.Base.NamedError("Clipperz.ByteArray.exception.InvalidValue")
+};
+
+//#############################################################################
+
+Clipperz.ByteArrayIterator = function(args) {
+ args = args || {};
+
+ this._byteArray = args.byteArray;
+ this._blockSize = args.blockSize;
+ this._finalPadding = args.finalPadding || false;
+
+ this._currentPosition = 0;
+
+ return this;
+}
+
+Clipperz.ByteArrayIterator.prototype = MochiKit.Base.update(null, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function() {
+ return "Clipperz.ByteArrayIterator";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'blockSize': function() {
+ var result;
+
+ result = this._blockSize;
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'currentPosition': function() {
+ var result;
+
+ result = this._currentPosition;
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'byteArray': function() {
+ var result;
+
+ result = this._byteArray;
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'finalPadding': function() {
+ var result;
+
+ result = this._finalPadding;
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'nextBlock': function() {
+ var result;
+ var currentPosition;
+ var byteArrayLength;
+
+ currentPosition = this._currentPosition;
+ byteArrayLength = this.byteArray().length();
+
+ if (currentPosition < byteArrayLength) {
+ var i,c;
+
+ c = this.blockSize();
+ result = new Array(c);
+ for (i=0; i<c; i++) {
+ if (currentPosition < byteArrayLength) {
+ result[i] = this.byteArray().byteAtIndex(currentPosition);
+ currentPosition++;
+ } else if (this.finalPadding() == true) {
+ result[i] = 0;
+ }
+ }
+
+ this._currentPosition = currentPosition;
+ } else {
+ result = null;
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'nextBlockArray': function() {
+ var result;
+ var nextBlock;
+
+ nextBlock = this.nextBlock();
+
+ if (nextBlock != null) {
+ result = new Clipperz.ByteArray(nextBlock);
+ } else {
+ result = null;
+ }
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
diff --git a/frontend/gamma/js/Clipperz/CSVProcessor.js b/frontend/gamma/js/Clipperz/CSVProcessor.js
new file mode 100644
index 0000000..d481ba2
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/CSVProcessor.js
@@ -0,0 +1,349 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+
+
+Clipperz.CSVProcessor = function(args) {
+ args = args || {};
+
+// this._status = undefined;
+// this._error_input = undefined;
+// this._string = undefined;
+// this._fields = undefined;
+
+ this._quoteChar = args['quoteChar'] || "\042";
+ this._eol = args['eol'] || "";
+ this._escapeChar = args['escapeChar'] || "\042";
+ this._separatorChar = args['separatorChar'] || ",";
+ this._binary = args['binary'] || false;
+ this._alwaysQuote = args['alwaysQuote'] || false;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.CSVProcessor.prototype = MochiKit.Base.update(null, {
+
+ //-------------------------------------------------------------------------
+
+ 'quoteChar': function() {
+ return this._quoteChar;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'eol': function() {
+ return this._eol;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'escapeChar': function() {
+ return this._escapeChar;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'separatorChar': function() {
+ return this._separatorChar;
+ },
+
+ 'setSeparatorChar': function(aValue) {
+ this._separatorChar = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'binary': function() {
+ return this._binary;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'alwaysQuote': function() {
+ return this._alwaysQuote;
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'parse': function(aValue) {
+ var result;
+ var lines;
+ var parameter;
+
+//MochiKit.Logging.logDebug(">>> CSVProcessor.parse");
+ result = [];
+
+ lines = aValue.replace(/\r?\n/g, "\n").replace(/^\n* /g, "").replace(/\n$/g, "");;
+ parameter = {
+ line: lines
+ }
+
+ do {
+ var fields;
+
+ fields = this.parseLine(parameter);
+
+ if (fields != null) {
+ result.push(fields);
+ }
+
+ parameter.line = parameter.line.replace(/^\n* /g, "").replace(/\n$/g, "");
+
+//MochiKit.Logging.logDebug("line: '" + parameter.line + "'");
+ } while (parameter.line != "");
+//MochiKit.Logging.logDebug("--- CSVProcessor.parse - result: " + Clipperz.Base.serializeJSON(result));
+//MochiKit.Logging.logDebug("<<< CSVProcessor.parse");
+
+ return result;
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'deferredParse_core': function(aContext) {
+ var deferredResult;
+
+ if (aContext.line == "") {
+ deferredResult = MochiKit.Async.succeed(aContext.result);
+ } else {
+ var fields;
+
+ fields = this.parseLine(aContext);
+ if (fields != null) {
+ aContext.result.push(fields);
+ }
+
+ aContext.line = aContext.line.replace(/^\n*/g, "").replace(/\n$/g, "");
+
+ deferredResult = new Clipperz.Async.Deferred("CVSProcessor.deferredParse_core");
+// deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'importProcessorProgressUpdate', {status:'processing', size:aContext.size, progress:(aContext.size - aContext.line.length)});
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'importProcessorProgressUpdate', {status:'processing', size:aContext.size, progress:(aContext.size - aContext.line.length)});
+ deferredResult.addCallback(MochiKit.Async.wait, 0.2);
+ deferredResult.addMethod(this, 'deferredParse_core')
+ deferredResult.callback(aContext);
+ }
+
+ return deferredResult;
+ },
+
+ //.........................................................................
+
+ 'deferredParse': function(aValue) {
+ var deferredResult;
+ var lines;
+ var context;
+
+ lines = aValue.replace(/\r?\n/g, "\n").replace(/^\n*/g, "").replace(/\n$/g, "");
+
+ context = {
+ line: lines,
+ size: lines.length,
+ result: []
+ }
+
+ deferredResult = new Clipperz.Async.Deferred("CSVProcessor.deferredParse");
+ deferredResult.addMethod(this, 'deferredParse_core');
+ deferredResult.callback(context);
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'parseLine': function(aParameter) {
+ var result;
+ var palatable;
+ var line;
+ var processedField;
+
+ result = [];
+
+ do {
+ processedField = this.parseField(aParameter);
+ if (processedField != null) {
+ result.push(processedField)
+ };
+ } while (processedField != null);
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'parseField': function(aParameter) {
+ var result;
+
+ var inQuotes;
+ var validRegExp;
+ var singleQuoteBeginRegexp;
+ var escapedQuoteBeginRegexp;
+ var singleQuoteCommaEndRegexp;
+ var singleQuoteNewLineEndRegexp;
+ var commaBeginRegexp;
+ var newlineRegexp;
+
+
+ singleQuoteBeginRegexp = new RegExp("^" + '\\' + this.quoteChar());
+ escapedQuoteBeginRegexp = new RegExp("^" + '\\' + this.escapeChar() + '\\' + this.quoteChar());
+ singleQuoteCommaEndRegexp = new RegExp("^" + '\\' + this.quoteChar() + '\\' + this.separatorChar());
+ singleQuoteNewLineEndRegexp = new RegExp("^" + '\\' + this.quoteChar() + "\n");
+ commaBeginRegexp = new RegExp("^" + '\\' + this.separatorChar());
+ newlineRegexp = new RegExp("^\n");
+
+ inQuotes = false;
+
+//MochiKit.Logging.logDebug("#################################### '" + aParameter.line + "'");
+ if (aParameter.line == "") {
+ if (aParameter.isThereAnEmptyFinalField == true) {
+ aParameter.isThereAnEmptyFinalField = false;
+ result = "";
+ } else {
+ result = null;
+ }
+ } else {
+ if (this.binary()) {
+ validRegexp = /^./;
+// validRegexp = /^[^\\]/;
+ } else {
+ validRegexp = /^[\t\040-\176]/;
+ }
+
+ try {
+ var done;
+
+ done = false;
+ result = "";
+
+ while (!done) {
+ if (aParameter.line.length < 1) {
+//MochiKit.Logging.logDebug("---> 1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ if (inQuotes == true) {
+//MochiKit.Logging.logDebug("---> 1.1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ throw new Error("CSV Parsing error; end of string, missing closing double-quote...");
+ } else {
+//MochiKit.Logging.logDebug("---> 1.2: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ done = true;
+ }
+ } else if (escapedQuoteBeginRegexp.test(aParameter.line)) {
+//MochiKit.Logging.logDebug("---> 2.1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ result += this.quoteChar();
+ aParameter.line = aParameter.line.substr(2, aParameter.line.length - 1);
+//MochiKit.Logging.logDebug("<--- 2.2: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ } else if (singleQuoteBeginRegexp.test(aParameter.line)) {
+//MochiKit.Logging.logDebug("---> 3: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ if (inQuotes == true) {
+ if (aParameter.line.length == 1) {
+//MochiKit.Logging.logDebug("---> 3.1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ aParameter.line = '';
+ done = true;
+ } else if (singleQuoteCommaEndRegexp.test(aParameter.line)) {
+//MochiKit.Logging.logDebug("---> 3.3: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ aParameter.line = aParameter.line.substr(2, aParameter.line.length - 1);
+ done = true;
+//MochiKit.Logging.logDebug("<--- 3.3: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ } else if (singleQuoteNewLineEndRegexp.test(aParameter.line)) {
+ aParameter.line = aParameter.line.substr(1, aParameter.line.length - 1);
+ done = true;
+ } else {
+ throw new Error("CSV Parsing error; double-quote, followed by undesirable character (bad character sequence)... " + aParameter.line);
+ }
+ } else {
+//MochiKit.Logging.logDebug("---> 4: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ if (result == "") {
+//MochiKit.Logging.logDebug("---> 4.1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ inQuotes = true;
+ aParameter.line = aParameter.line.substr(1, aParameter.line.length - 1);
+//MochiKit.Logging.logDebug("<--- 4.1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ } else {
+ throw new Error("CSV Parsing error; double-quote, outside of double-quotes (bad character sequence)...");
+ }
+ }
+ } else if (commaBeginRegexp.test(aParameter.line)) {
+//MochiKit.Logging.logDebug("---> 5: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ if (inQuotes) {
+//MochiKit.Logging.logDebug("---> 5.1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ result += aParameter.line.substr(0 ,1);
+ aParameter.line = aParameter.line.substr(1, aParameter.line.length - 1);
+//MochiKit.Logging.logDebug("<--- 5.1: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ } else {
+//MochiKit.Logging.logDebug("---> 5.2: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ aParameter.line = aParameter.line.substr(1, aParameter.line.length - 1);
+ if (newlineRegexp.test(aParameter.line) || aParameter.line == "") {
+//MochiKit.Logging.logDebug("######");
+ aParameter.isThereAnEmptyFinalField = true;
+ };
+ done = true;
+//MochiKit.Logging.logDebug("<--- 5.2: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ }
+ } else if (validRegexp.test(aParameter.line)) {
+//MochiKit.Logging.logDebug("---> 6: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ result += aParameter.line.substr(0, 1);
+ aParameter.line = aParameter.line.substr(1, aParameter.line.length - 1);
+//MochiKit.Logging.logDebug("<--- 6: '" + aParameter.line.replace(/\n/g, "\\n") + "'");
+ } else if (newlineRegexp.test(aParameter.line)) {
+ if (inQuotes == true) {
+ result += aParameter.line.substr(0 ,1);
+ aParameter.line = aParameter.line.substr(1, aParameter.line.length - 1);
+ } else {
+ if (result == "") {
+ if (aParameter.isThereAnEmptyFinalField == true) {
+ aParameter.isThereAnEmptyFinalField = false;
+ } else {
+ result = null;
+ }
+ }
+
+ done = true;
+ }
+ } else {
+ throw new Error("CSV Parsing error; an undesirable character... '" + aParameter.line.substr(0,1) + "'");
+ }
+ }
+ } catch(exception) {
+ MochiKit.Logging.logError(exception.message);
+// result = null;
+ throw exception;
+ }
+ }
+
+//if (result != null) {
+// MochiKit.Logging.logDebug("<=== result: '" + result.replace(/\n/g, "\\n") + "'");
+//} else {
+// MochiKit.Logging.logDebug("<=== result: NULL");
+//}
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+
diff --git a/frontend/gamma/js/Clipperz/Crypto/AES.js b/frontend/gamma/js/Clipperz/Crypto/AES.js
new file mode 100644
index 0000000..36fc731
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/AES.js
@@ -0,0 +1,869 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.Crypto.AES depends on Clipperz.ByteArray!";
+}
+
+// Dependency commented to avoid a circular reference
+//try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) {
+// throw "Clipperz.Crypto.AES depends on Clipperz.Crypto.PRNG!";
+//}
+
+if (typeof(Clipperz.Crypto.AES) == 'undefined') { Clipperz.Crypto.AES = {}; }
+
+//#############################################################################
+
+Clipperz.Crypto.AES.DeferredExecutionContext = function(args) {
+ args = args || {};
+
+ this._key = args.key;
+ this._message = args.message;
+ this._result = args.message.clone();
+ this._nonce = args.nonce;
+ this._messageLength = this._message.length();
+
+ this._messageArray = this._message.arrayValues();
+ this._resultArray = this._result.arrayValues();
+ this._nonceArray = this._nonce.arrayValues();
+
+ this._executionStep = 0;
+
+// this._elaborationChunkSize = 1024; // 4096; // 16384; // 4096;
+ this._elaborationChunks = 10;
+ this._pauseTime = 0.02; // 0.02 // 0.2;
+
+ return this;
+}
+
+Clipperz.Crypto.AES.DeferredExecutionContext.prototype = MochiKit.Base.update(null, {
+
+ 'key': function() {
+ return this._key;
+ },
+
+ 'message': function() {
+ return this._message;
+ },
+
+ 'messageLength': function() {
+ return this._messageLength;
+ },
+
+ 'result': function() {
+ return new Clipperz.ByteArray(this.resultArray());
+ },
+
+ 'nonce': function() {
+ return this._nonce;
+ },
+
+ 'messageArray': function() {
+ return this._messageArray;
+ },
+
+ 'resultArray': function() {
+ return this._resultArray;
+ },
+
+ 'nonceArray': function() {
+ return this._nonceArray;
+ },
+
+ 'elaborationChunkSize': function() {
+// return Clipperz.Crypto.AES.DeferredExecution.chunkSize;
+// return this._elaborationChunkSize;
+ return (this._elaborationChunks * 1024);
+ },
+
+ 'executionStep': function() {
+ return this._executionStep;
+ },
+
+ 'setExecutionStep': function(aValue) {
+ this._executionStep = aValue;
+ },
+
+ 'tuneExecutionParameters': function (anElapsedTime) {
+//var originalChunks = this._elaborationChunks;
+ if (anElapsedTime > 0) {
+ this._elaborationChunks = Math.round(this._elaborationChunks * ((anElapsedTime + 1000)/(anElapsedTime * 2)));
+ }
+//Clipperz.log("tuneExecutionParameters - elapsedTime: " + anElapsedTime + /*originalChunks,*/ " chunks # " + this._elaborationChunks + " [" + this._executionStep + " / " + this._messageLength + "]");
+ },
+
+ 'pause': function(aValue) {
+// return MochiKit.Async.wait(Clipperz.Crypto.AES.DeferredExecution.pauseTime, aValue);
+ return MochiKit.Async.wait(this._pauseTime, aValue);
+ },
+
+ 'isDone': function () {
+//console.log("isDone", this.executionStep(), this.messageLength());
+ return (this._executionStep >= this._messageLength);
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
+//#############################################################################
+
+Clipperz.Crypto.AES.Key = function(args) {
+ args = args || {};
+
+ this._key = args.key;
+ this._keySize = args.keySize || this.key().length();
+
+ if (this.keySize() == 128/8) {
+ this._b = 176;
+ this._numberOfRounds = 10;
+ } else if (this.keySize() == 256/8) {
+ this._b = 240;
+ this._numberOfRounds = 14;
+ } else {
+ MochiKit.Logging.logError("AES unsupported key size: " + (this.keySize() * 8) + " bits");
+ throw Clipperz.Crypto.AES.exception.UnsupportedKeySize;
+ }
+
+ this._stretchedKey = null;
+
+ return this;
+}
+
+Clipperz.Crypto.AES.Key.prototype = MochiKit.Base.update(null, {
+
+ 'asString': function() {
+ return "Clipperz.Crypto.AES.Key (" + this.key().toHexString() + ")";
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'key': function() {
+ return this._key;
+ },
+
+ 'keySize': function() {
+ return this._keySize;
+ },
+
+ 'b': function() {
+ return this._b;
+ },
+
+ 'numberOfRounds': function() {
+ return this._numberOfRounds;
+ },
+ //=========================================================================
+
+ 'keyScheduleCore': function(aWord, aRoundConstantsIndex) {
+ var result;
+ var sbox;
+
+ sbox = Clipperz.Crypto.AES.sbox();
+
+ result = [ sbox[aWord[1]] ^ Clipperz.Crypto.AES.roundConstants()[aRoundConstantsIndex],
+ sbox[aWord[2]],
+ sbox[aWord[3]],
+ sbox[aWord[0]] ];
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'xorWithPreviousStretchValues': function(aKey, aWord, aPreviousWordIndex) {
+ var result;
+ var i,c;
+
+ result = [];
+ c = 4;
+ for (i=0; i<c; i++) {
+ result[i] = aWord[i] ^ aKey.byteAtIndex(aPreviousWordIndex + i);
+ }
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'sboxShakeup': function(aWord) {
+ var result;
+ var sbox;
+ var i,c;
+
+ result = [];
+ sbox = Clipperz.Crypto.AES.sbox();
+ c =4;
+ for (i=0; i<c; i++) {
+ result[i] = sbox[aWord[i]];
+ }
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'stretchKey': function(aKey) {
+ var currentWord;
+ var keyLength;
+ var previousStretchIndex;
+ var i,c;
+
+ keyLength = aKey.length();
+ previousStretchIndex = keyLength - this.keySize();
+
+ currentWord = [ aKey.byteAtIndex(keyLength - 4),
+ aKey.byteAtIndex(keyLength - 3),
+ aKey.byteAtIndex(keyLength - 2),
+ aKey.byteAtIndex(keyLength - 1) ];
+ currentWord = this.keyScheduleCore(currentWord, keyLength / this.keySize());
+
+ if (this.keySize() == 256/8) {
+ c = 8;
+ } else if (this.keySize() == 128/8){
+ c = 4;
+ }
+
+ for (i=0; i<c; i++) {
+ if (i == 4) {
+ // fifth streatch word
+ currentWord = this.sboxShakeup(currentWord);
+ }
+
+ currentWord = this.xorWithPreviousStretchValues(aKey, currentWord, previousStretchIndex + (i*4));
+ aKey.appendBytes(currentWord);
+ }
+
+ return aKey;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'stretchedKey': function() {
+ if (this._stretchedKey == null) {
+ var stretchedKey;
+
+ stretchedKey = this.key().clone();
+
+ while (stretchedKey.length() < this.keySize()) {
+ stretchedKey.appendByte(0);
+ }
+
+ while (stretchedKey.length() < this.b()) {
+ stretchedKey = this.stretchKey(stretchedKey);
+ }
+
+ this._stretchedKey = stretchedKey.split(0, this.b());
+ }
+
+ return this._stretchedKey;
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+//#############################################################################
+
+Clipperz.Crypto.AES.State = function(args) {
+ args = args || {};
+
+ this._data = args.block;
+ this._key = args.key;
+
+ return this;
+}
+
+Clipperz.Crypto.AES.State.prototype = MochiKit.Base.update(null, {
+
+ 'key': function() {
+ return this._key;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'data': function() {
+ return this._data;
+ },
+
+ 'setData': function(aValue) {
+ this._data = aValue;
+ },
+
+ //=========================================================================
+
+ 'addRoundKey': function(aRoundNumber) {
+ // each byte of the state is combined with the round key; each round key is derived from the cipher key using a key schedule.
+ var data;
+ var stretchedKey;
+ var firstStretchedKeyIndex;
+ var i,c;
+
+ data = this.data();
+ stretchedKey = this.key().stretchedKey();
+ firstStretchedKeyIndex = aRoundNumber * (128/8);
+ c = 128/8;
+ for (i=0; i<c; i++) {
+ data[i] = data[i] ^ stretchedKey.byteAtIndex(firstStretchedKeyIndex + i);
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'subBytes': function() {
+ // a non-linear substitution step where each byte is replaced with another according to a lookup table.
+ var i,c;
+ var data;
+ var sbox;
+
+ data = this.data();
+ sbox = Clipperz.Crypto.AES.sbox();
+
+ c = 16;
+ for (i=0; i<c; i++) {
+ data[i] = sbox[data[i]];
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'shiftRows': function() {
+ // a transposition step where each row of the state is shifted cyclically a certain number of steps.
+ var newValue;
+ var data;
+ var shiftMapping;
+ var i,c;
+
+ newValue = new Array(16);
+ data = this.data();
+ shiftMapping = Clipperz.Crypto.AES.shiftRowMapping();
+// [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
+ c = 16;
+ for (i=0; i<c; i++) {
+ newValue[i] = data[shiftMapping[i]];
+ }
+ for (i=0; i<c; i++) {
+ data[i] = newValue[i];
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+/*
+ 'mixColumnsWithValues': function(someValues) {
+ var result;
+ var a;
+ var i,c;
+
+ c = 4;
+ result = [];
+ a = [];
+ for (i=0; i<c; i++) {
+ a[i] = [];
+ a[i][1] = someValues[i]
+ if ((a[i][1] & 0x80) == 0x80) {
+ a[i][2] = (a[i][1] << 1) ^ 0x11b;
+ } else {
+ a[i][2] = a[i][1] << 1;
+ }
+
+ a[i][3] = a[i][2] ^ a[i][1];
+ }
+
+ for (i=0; i<c; i++) {
+ var x;
+
+ x = Clipperz.Crypto.AES.mixColumnsMatrix()[i];
+ result[i] = a[0][x[0]] ^ a[1][x[1]] ^ a[2][x[2]] ^ a[3][x[3]];
+ }
+
+ return result;
+ },
+
+ 'mixColumns': function() {
+ // a mixing operation which operates on the columns of the state, combining the four bytes in each column using a linear transformation.
+ var data;
+ var i, c;
+
+ data = this.data();
+ c = 4;
+ for(i=0; i<c; i++) {
+ var blockIndex;
+ var mixedValues;
+
+ blockIndex = i * 4;
+ mixedValues = this.mixColumnsWithValues([ data[blockIndex + 0],
+ data[blockIndex + 1],
+ data[blockIndex + 2],
+ data[blockIndex + 3]]);
+ data[blockIndex + 0] = mixedValues[0];
+ data[blockIndex + 1] = mixedValues[1];
+ data[blockIndex + 2] = mixedValues[2];
+ data[blockIndex + 3] = mixedValues[3];
+ }
+ },
+*/
+
+ 'mixColumns': function() {
+ // a mixing operation which operates on the columns of the state, combining the four bytes in each column using a linear transformation.
+ var data;
+ var i, c;
+ var a_1;
+ var a_2;
+
+ a_1 = new Array(4);
+ a_2 = new Array(4);
+
+ data = this.data();
+ c = 4;
+ for(i=0; i<c; i++) {
+ var blockIndex;
+ var ii, cc;
+
+ blockIndex = i * 4;
+
+ cc = 4;
+ for (ii=0; ii<cc; ii++) {
+ var value;
+
+ value = data[blockIndex + ii];
+ a_1[ii] = value;
+ a_2[ii] = (value & 0x80) ? ((value << 1) ^ 0x011b) : (value << 1);
+ }
+
+ data[blockIndex + 0] = a_2[0] ^ a_1[1] ^ a_2[1] ^ a_1[2] ^ a_1[3];
+ data[blockIndex + 1] = a_1[0] ^ a_2[1] ^ a_1[2] ^ a_2[2] ^ a_1[3];
+ data[blockIndex + 2] = a_1[0] ^ a_1[1] ^ a_2[2] ^ a_1[3] ^ a_2[3];
+ data[blockIndex + 3] = a_1[0] ^ a_2[0] ^ a_1[1] ^ a_1[2] ^ a_2[3];
+ }
+ },
+
+ //=========================================================================
+
+ 'spinRound': function(aRoundNumber) {
+ this.addRoundKey(aRoundNumber);
+ this.subBytes();
+ this.shiftRows();
+ this.mixColumns();
+ },
+
+ 'spinLastRound': function() {
+ this.addRoundKey(this.key().numberOfRounds() - 1);
+ this.subBytes();
+ this.shiftRows();
+ this.addRoundKey(this.key().numberOfRounds());
+ },
+
+ //=========================================================================
+
+ 'encrypt': function() {
+ var i,c;
+
+ c = this.key().numberOfRounds() - 1;
+ for (i=0; i<c; i++) {
+ this.spinRound(i);
+ }
+
+ this.spinLastRound();
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+//#############################################################################
+
+Clipperz.Crypto.AES.VERSION = "0.1";
+Clipperz.Crypto.AES.NAME = "Clipperz.Crypto.AES";
+
+MochiKit.Base.update(Clipperz.Crypto.AES, {
+
+// http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-AES.html
+// http://en.wikipedia.org/wiki/Advanced_Encryption_Standard
+// http://en.wikipedia.org/wiki/Rijndael_key_schedule
+// http://en.wikipedia.org/wiki/Rijndael_S-box
+
+ '__repr__': function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+ },
+
+ 'toString': function () {
+ return this.__repr__();
+ },
+
+ //=============================================================================
+
+ '_sbox': null,
+ 'sbox': function() {
+ if (Clipperz.Crypto.AES._sbox == null) {
+ Clipperz.Crypto.AES._sbox = [
+0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+ ];
+ }
+
+ return Clipperz.Crypto.AES._sbox;
+ },
+
+ //-----------------------------------------------------------------------------
+ //
+ // 0 4 8 12 0 4 8 12
+ // 1 5 9 13 => 5 9 13 1
+ // 2 6 10 14 10 14 2 6
+ // 3 7 11 15 15 3 7 11
+ //
+ '_shiftRowMapping': null,
+ 'shiftRowMapping': function() {
+ if (Clipperz.Crypto.AES._shiftRowMapping == null) {
+ Clipperz.Crypto.AES._shiftRowMapping = [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
+ }
+
+ return Clipperz.Crypto.AES._shiftRowMapping;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ '_mixColumnsMatrix': null,
+ 'mixColumnsMatrix': function() {
+ if (Clipperz.Crypto.AES._mixColumnsMatrix == null) {
+ Clipperz.Crypto.AES._mixColumnsMatrix = [ [2, 3, 1 ,1],
+ [1, 2, 3, 1],
+ [1, 1, 2, 3],
+ [3, 1, 1, 2] ];
+ }
+
+ return Clipperz.Crypto.AES._mixColumnsMatrix;
+ },
+
+ '_roundConstants': null,
+ 'roundConstants': function() {
+ if (Clipperz.Crypto.AES._roundConstants == null) {
+ Clipperz.Crypto.AES._roundConstants = [ , 1, 2, 4, 8, 16, 32, 64, 128, 27, 54, 108, 216, 171, 77, 154];
+// Clipperz.Crypto.AES._roundConstants = [ , 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a];
+ }
+
+ return Clipperz.Crypto.AES._roundConstants;
+ },
+
+ //=============================================================================
+
+ 'incrementNonce': function(aNonce) {
+//Clipperz.Profile.start("Clipperz.Crypto.AES.incrementNonce");
+ var i;
+ var done;
+
+ done = false;
+ i = aNonce.length - 1;
+
+ while ((i>=0) && (done == false)) {
+ var currentByteValue;
+
+ currentByteValue = aNonce[i];
+
+ if (currentByteValue == 0xff) {
+ aNonce[i] = 0;
+ if (i>= 0) {
+ i --;
+ } else {
+ done = true;
+ }
+ } else {
+ aNonce[i] = currentByteValue + 1;
+ done = true;
+ }
+ }
+//Clipperz.Profile.stop("Clipperz.Crypto.AES.incrementNonce");
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'encryptBlock': function(aKey, aBlock) {
+ var result;
+ var state;
+
+ state = new Clipperz.Crypto.AES.State({block:aBlock, key:aKey});
+//is(state.data(), 'before');
+ state.encrypt();
+ result = state.data();
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'encryptBlocks': function(aKey, aMessage, aNonce) {
+ var result;
+ var nonce;
+ var self;
+ var messageIndex;
+ var messageLength;
+ var blockSize;
+
+ self = Clipperz.Crypto.AES;
+ blockSize = 128/8;
+ messageLength = aMessage.length;
+ nonce = aNonce;
+
+ result = aMessage;
+ messageIndex = 0;
+ while (messageIndex < messageLength) {
+ var encryptedBlock;
+ var i,c;
+
+ self.incrementNonce(nonce);
+ encryptedBlock = self.encryptBlock(aKey, nonce);
+
+ if ((messageLength - messageIndex) > blockSize) {
+ c = blockSize;
+ } else {
+ c = messageLength - messageIndex;
+ }
+
+ for (i=0; i<c; i++) {
+ result[messageIndex + i] = result[messageIndex + i] ^ encryptedBlock[i];
+ }
+
+ messageIndex += blockSize;
+ }
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'encrypt': function(aKey, someData, aNonce) {
+ var result;
+ var nonce;
+ var encryptedData;
+ var key;
+
+ key = new Clipperz.Crypto.AES.Key({key:aKey});
+ nonce = aNonce ? aNonce.clone() : Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8);
+
+ encryptedData = Clipperz.Crypto.AES.encryptBlocks(key, someData.arrayValues(), nonce.arrayValues());
+
+ result = nonce.appendBytes(encryptedData);
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'decrypt': function(aKey, someData) {
+ var result;
+ var nonce;
+ var encryptedData;
+ var decryptedData;
+ var dataIterator;
+ var key;
+
+ key = new Clipperz.Crypto.AES.Key({key:aKey});
+
+ encryptedData = someData.arrayValues();
+ nonce = encryptedData.slice(0, (128/8));
+ encryptedData = encryptedData.slice(128/8);
+ decryptedData = Clipperz.Crypto.AES.encryptBlocks(key, encryptedData, nonce);
+
+ result = new Clipperz.ByteArray(decryptedData);
+
+ return result;
+ },
+
+ //=============================================================================
+
+ 'deferredEncryptExecutionChunk': function(anExecutionContext) {
+ var result;
+ var nonce;
+ var self;
+ var messageIndex;
+ var messageLength;
+ var blockSize;
+ var executionLimit;
+ var startTime, endTime;
+
+ self = Clipperz.Crypto.AES;
+ startTime = new Date();
+ blockSize = 128/8;
+ messageLength = anExecutionContext.messageArray().length;
+ nonce = anExecutionContext.nonceArray();
+ result = anExecutionContext.resultArray();
+
+ messageIndex = anExecutionContext.executionStep();
+ executionLimit = messageIndex + anExecutionContext.elaborationChunkSize();
+ executionLimit = Math.min(executionLimit, messageLength);
+
+ while (messageIndex < executionLimit) {
+ var encryptedBlock;
+ var i,c;
+
+ self.incrementNonce(nonce);
+ encryptedBlock = self.encryptBlock(anExecutionContext.key(), nonce);
+
+ if ((executionLimit - messageIndex) > blockSize) {
+ c = blockSize;
+ } else {
+ c = executionLimit - messageIndex;
+ }
+
+ for (i=0; i<c; i++) {
+ result[messageIndex + i] = result[messageIndex + i] ^ encryptedBlock[i];
+ }
+
+ messageIndex += blockSize;
+ }
+ anExecutionContext.setExecutionStep(messageIndex);
+ endTime = new Date();
+ anExecutionContext.tuneExecutionParameters(endTime - startTime);
+
+ return anExecutionContext;
+ },
+
+ //-----------------------------------------------------------------------------
+/*
+ 'deferredEncryptBlocks': function(anExecutionContext) {
+ var deferredResult;
+ var messageSize;
+ var i,c;
+
+ messageSize = anExecutionContext.messageLength();
+
+ deferredResult = new Clipperz.Async.Deferred("AES.deferredEncryptBloks");
+
+ c = Math.ceil(messageSize / anExecutionContext.elaborationChunkSize());
+ for (i=0; i<c; i++) {
+ deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptExecutionChunk);
+ deferredResult.addMethod(anExecutionContext, 'pause');
+ }
+
+ deferredResult.callback(anExecutionContext);
+
+ return deferredResult;
+ },
+*/
+
+ 'deferredEncryptBlocks': function(anExecutionContext) {
+ var deferredResult;
+
+ if (! anExecutionContext.isDone()) {
+ deferredResult = Clipperz.Async.callbacks("Clipperz.Crypto.AES.deferredEncryptBloks", [
+ Clipperz.Crypto.AES.deferredEncryptExecutionChunk,
+ MochiKit.Base.method(anExecutionContext, 'pause'),
+ Clipperz.Crypto.AES.deferredEncryptBlocks
+ ], {trace:false}, anExecutionContext);
+ } else {
+ deferredResult = MochiKit.Async.succeed(anExecutionContext);
+ }
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'deferredEncrypt': function(aKey, someData, aNonce) {
+ var deferredResult;
+ var executionContext;
+ var result;
+ var nonce;
+ var key;
+
+ key = new Clipperz.Crypto.AES.Key({key:aKey});
+ nonce = aNonce ? aNonce.clone() : Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(128/8);
+
+ executionContext = new Clipperz.Crypto.AES.DeferredExecutionContext({key:key, message:someData, nonce:nonce});
+
+ deferredResult = new Clipperz.Async.Deferred("AES.deferredEncrypt");
+//deferredResult.addCallback(function (aValue) { console.log(">>> deferredEncrypt"); return aValue; });
+ deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptBlocks);
+ deferredResult.addCallback(function(anExecutionContext) {
+ var result;
+
+ result = anExecutionContext.nonce().clone();
+ result.appendBytes(anExecutionContext.resultArray());
+
+ return result;
+ });
+//deferredResult.addCallback(function (aValue) { console.log("<<< deferredEncrypt"); return aValue; });
+ deferredResult.callback(executionContext)
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'deferredDecrypt': function(aKey, someData) {
+ var deferredResult
+ var nonce;
+ var message;
+ var key;
+
+ key = new Clipperz.Crypto.AES.Key({key:aKey});
+ nonce = someData.split(0, (128/8));
+ message = someData.split(128/8);
+ executionContext = new Clipperz.Crypto.AES.DeferredExecutionContext({key:key, message:message, nonce:nonce});
+
+ deferredResult = new Clipperz.Async.Deferred("AES.deferredDecrypt");
+//deferredResult.addCallback(function (aValue) { console.log(">>> deferredDecrypt"); return aValue; });
+ deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncryptBlocks);
+ deferredResult.addCallback(function(anExecutionContext) {
+ return anExecutionContext.result();
+ });
+//deferredResult.addCallback(function (aValue) { console.log("<<< deferredDecrypt"); return aValue; });
+ deferredResult.callback(executionContext);
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
+//#############################################################################
+
+//Clipperz.Crypto.AES.DeferredExecution = {
+// 'chunkSize': 16384, // 4096, // 1024 4096 8192 16384 32768;
+// 'pauseTime': 0.02 // 0.2
+//}
+
+Clipperz.Crypto.AES.exception = {
+ 'UnsupportedKeySize': new MochiKit.Base.NamedError("Clipperz.Crypto.AES.exception.UnsupportedKeySize")
+};
diff --git a/frontend/gamma/js/Clipperz/Crypto/Base.js b/frontend/gamma/js/Clipperz/Crypto/Base.js
new file mode 100644
index 0000000..b69dcc8
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/Base.js
@@ -0,0 +1,1852 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try { if (typeof(Clipperz.Base) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.Crypto.Base depends on Clipperz.Base!";
+}
+
+if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
+if (typeof(Clipperz.Crypto.Base) == 'undefined') { Clipperz.Crypto.Base = {}; }
+
+Clipperz.Crypto.Base.VERSION = "0.1";
+Clipperz.Crypto.Base.NAME = "Clipperz.Crypto.Base";
+
+//#############################################################################
+// Downloaded on March 30, 2006 from http://anmar.eu.org/projects/jssha2/files/jssha2-0.3.zip (jsSha2/sha256.js)
+//#############################################################################
+
+/* A JavaScript implementation of the Secure Hash Algorithm, SHA-256
+ * Version 0.3 Copyright Angel Marin 2003-2004 - http://anmar.eu.org/
+ * Distributed under the BSD License
+ * Some bits taken from Paul Johnston's SHA-1 implementation
+ */
+var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
+function safe_add (x, y) {
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+}
+function S (X, n) {return ( X >>> n ) | (X << (32 - n));}
+function R (X, n) {return ( X >>> n );}
+function Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
+function Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
+function Sigma0256(x) {return (S(x, 2) ^ S(x, 13) ^ S(x, 22));}
+function Sigma1256(x) {return (S(x, 6) ^ S(x, 11) ^ S(x, 25));}
+function Gamma0256(x) {return (S(x, 7) ^ S(x, 18) ^ R(x, 3));}
+function Gamma1256(x) {return (S(x, 17) ^ S(x, 19) ^ R(x, 10));}
+function core_sha256 (m, l) {
+ var K = new Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2);
+ var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19);
+ var W = new Array(64);
+ var a, b, c, d, e, f, g, h, i, j;
+ var T1, T2;
+ /* append padding */
+ m[l >> 5] |= 0x80 << (24 - l % 32);
+ m[((l + 64 >> 9) << 4) + 15] = l;
+ for ( var i = 0; i<m.length; i+=16 ) {
+ a = HASH[0]; b = HASH[1]; c = HASH[2]; d = HASH[3]; e = HASH[4]; f = HASH[5]; g = HASH[6]; h = HASH[7];
+ for ( var j = 0; j<64; j++) {
+ if (j < 16) W[j] = m[j + i];
+ else W[j] = safe_add(safe_add(safe_add(Gamma1256(W[j - 2]), W[j - 7]), Gamma0256(W[j - 15])), W[j - 16]);
+ T1 = safe_add(safe_add(safe_add(safe_add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), W[j]);
+ T2 = safe_add(Sigma0256(a), Maj(a, b, c));
+ h = g; g = f; f = e; e = safe_add(d, T1); d = c; c = b; b = a; a = safe_add(T1, T2);
+ }
+ HASH[0] = safe_add(a, HASH[0]); HASH[1] = safe_add(b, HASH[1]); HASH[2] = safe_add(c, HASH[2]); HASH[3] = safe_add(d, HASH[3]); HASH[4] = safe_add(e, HASH[4]); HASH[5] = safe_add(f, HASH[5]); HASH[6] = safe_add(g, HASH[6]); HASH[7] = safe_add(h, HASH[7]);
+ }
+ return HASH;
+}
+function str2binb (str) {
+ var bin = Array();
+ var mask = (1 << chrsz) - 1;
+ for(var i = 0; i < str.length * chrsz; i += chrsz)
+ bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32);
+ return bin;
+}
+function binb2hex (binarray) {
+ var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
+ var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+ var str = "";
+ for (var i = 0; i < binarray.length * 4; i++) {
+ str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF);
+ }
+ return str;
+}
+function hex_sha256(s){return binb2hex(core_sha256(str2binb(s),s.length * chrsz));}
+
+
+
+//#############################################################################
+// Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (entropy.js)
+//#############################################################################
+
+ // Entropy collection utilities
+
+ /* Start by declaring static storage and initialise
+ the entropy vector from the time we come through
+ here. */
+
+ var entropyData = new Array(); // Collected entropy data
+ var edlen = 0; // Keyboard array data length
+
+ addEntropyTime(); // Start entropy collection with page load time
+ ce(); // Roll milliseconds into initial entropy
+
+ // Add a byte to the entropy vector
+
+ function addEntropyByte(b) {
+ entropyData[edlen++] = b;
+ }
+
+ /* Capture entropy. When the user presses a key or performs
+ various other events for which we can request
+ notification, add the time in 255ths of a second to the
+ entropyData array. The name of the function is short
+ so it doesn't bloat the form object declarations in
+ which it appears in various "onXXX" events. */
+
+ function ce() {
+ addEntropyByte(Math.floor((((new Date).getMilliseconds()) * 255) / 999));
+ }
+
+ // Add a 32 bit quantity to the entropy vector
+
+ function addEntropy32(w) {
+ var i;
+
+ for (i = 0; i < 4; i++) {
+ addEntropyByte(w & 0xFF);
+ w >>= 8;
+ }
+ }
+
+ /* Add the current time and date (milliseconds since the epoch,
+ truncated to 32 bits) to the entropy vector. */
+
+ function addEntropyTime() {
+ addEntropy32((new Date()).getTime());
+ }
+
+ /* Start collection of entropy from mouse movements. The
+ argument specifies the number of entropy items to be
+ obtained from mouse motion, after which mouse motion
+ will be ignored. Note that you can re-enable mouse
+ motion collection at any time if not already underway. */
+
+ var mouseMotionCollect = 0;
+ var oldMoveHandler; // For saving and restoring mouse move handler in IE4
+
+ function mouseMotionEntropy(maxsamp) {
+ if (mouseMotionCollect <= 0) {
+ mouseMotionCollect = maxsamp;
+ if ((document.implementation.hasFeature("Events", "2.0")) &&
+ document.addEventListener) {
+ // Browser supports Document Object Model (DOM) 2 events
+ document.addEventListener("mousemove", mouseMoveEntropy, false);
+ } else {
+ if (document.attachEvent) {
+ // Internet Explorer 5 and above event model
+ document.attachEvent("onmousemove", mouseMoveEntropy);
+ } else {
+ // Internet Explorer 4 event model
+ oldMoveHandler = document.onmousemove;
+ document.onmousemove = mouseMoveEntropy;
+ }
+ }
+//dump("Mouse enable", mouseMotionCollect);
+ }
+ }
+
+ /* Collect entropy from mouse motion events. Note that
+ this is craftily coded to work with either DOM2 or Internet
+ Explorer style events. Note that we don't use every successive
+ mouse movement event. Instead, we XOR the three bytes collected
+ from the mouse and use that to determine how many subsequent
+ mouse movements we ignore before capturing the next one. */
+
+ var mouseEntropyTime = 0; // Delay counter for mouse entropy collection
+
+ function mouseMoveEntropy(e) {
+ if (!e) {
+ e = window.event; // Internet Explorer event model
+ }
+ if (mouseMotionCollect > 0) {
+ if (mouseEntropyTime-- <= 0) {
+ addEntropyByte(e.screenX & 0xFF);
+ addEntropyByte(e.screenY & 0xFF);
+ ce();
+ mouseMotionCollect--;
+ mouseEntropyTime = (entropyData[edlen - 3] ^ entropyData[edlen - 2] ^
+ entropyData[edlen - 1]) % 19;
+//dump("Mouse Move", byteArrayToHex(entropyData.slice(-3)));
+ }
+ if (mouseMotionCollect <= 0) {
+ if (document.removeEventListener) {
+ document.removeEventListener("mousemove", mouseMoveEntropy, false);
+ } else if (document.detachEvent) {
+ document.detachEvent("onmousemove", mouseMoveEntropy);
+ } else {
+ document.onmousemove = oldMoveHandler;
+ }
+//dump("Spung!", 0);
+ }
+ }
+ }
+
+ /* Compute a 32 byte key value from the entropy vector.
+ We compute the value by taking the MD5 sum of the even
+ and odd bytes respectively of the entropy vector, then
+ concatenating the two MD5 sums. */
+
+ function keyFromEntropy() {
+ var i, k = new Array(32);
+
+ if (edlen == 0) {
+ alert("Blooie! Entropy vector void at call to keyFromEntropy.");
+ }
+//dump("Entropy bytes", edlen);
+
+ md5_init();
+ for (i = 0; i < edlen; i += 2) {
+ md5_update(entropyData[i]);
+ }
+ md5_finish();
+ for (i = 0; i < 16; i++) {
+ k[i] = digestBits[i];
+ }
+
+ md5_init();
+ for (i = 1; i < edlen; i += 2) {
+ md5_update(entropyData[i]);
+ }
+ md5_finish();
+ for (i = 0; i < 16; i++) {
+ k[i + 16] = digestBits[i];
+ }
+
+//dump("keyFromEntropy", byteArrayToHex(k));
+ return k;
+ }
+
+//#############################################################################
+// Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (aesprng.js)
+//#############################################################################
+
+
+ // AES based pseudorandom number generator
+
+ /* Constructor. Called with an array of 32 byte (0-255) values
+ containing the initial seed. */
+
+ function AESprng(seed) {
+ this.key = new Array();
+ this.key = seed;
+ this.itext = hexToByteArray("9F489613248148F9C27945C6AE62EECA3E3367BB14064E4E6DC67A9F28AB3BD1");
+ this.nbytes = 0; // Bytes left in buffer
+
+ this.next = AESprng_next;
+ this.nextbits = AESprng_nextbits;
+ this.nextInt = AESprng_nextInt;
+ this.round = AESprng_round;
+
+ /* Encrypt the initial text with the seed key
+ three times, feeding the output of the encryption
+ back into the key for the next round. */
+
+ bsb = blockSizeInBits;
+ blockSizeInBits = 256;
+ var i, ct;
+ for (i = 0; i < 3; i++) {
+ this.key = rijndaelEncrypt(this.itext, this.key, "ECB");
+ }
+
+ /* Now make between one and four additional
+ key-feedback rounds, with the number determined
+ by bits from the result of the first three
+ rounds. */
+
+ var n = 1 + (this.key[3] & 2) + (this.key[9] & 1);
+ for (i = 0; i < n; i++) {
+ this.key = rijndaelEncrypt(this.itext, this.key, "ECB");
+ }
+ blockSizeInBits = bsb;
+ }
+
+ function AESprng_round() {
+ bsb = blockSizeInBits;
+ blockSizeInBits = 256;
+ this.key = rijndaelEncrypt(this.itext, this.key, "ECB");
+ this.nbytes = 32;
+ blockSizeInBits = bsb;
+ }
+
+ // Return next byte from the generator
+
+ function AESprng_next() {
+ if (this.nbytes <= 0) {
+ this.round();
+ }
+ return(this.key[--this.nbytes]);
+ }
+
+ // Return n bit integer value (up to maximum integer size)
+
+ function AESprng_nextbits(n) {
+ var i, w = 0, nbytes = Math.floor((n + 7) / 8);
+
+ for (i = 0; i < nbytes; i++) {
+ w = (w << 8) | this.next();
+ }
+ return w & ((1 << n) - 1);
+ }
+
+ // Return integer between 0 and n inclusive
+
+ function AESprng_nextInt(n) {
+ var p = 1, nb = 0;
+
+ // Determine smallest p, 2^p > n
+ // nb = log_2 p
+
+ while (n >= p) {
+ p <<= 1;
+ nb++;
+ }
+ p--;
+
+ /* Generate values from 0 through n by first generating
+ values v from 0 to (2^p)-1, then discarding any results v > n.
+ For the rationale behind this (and why taking
+ values mod (n + 1) is biased toward smaller values, see
+ Ferguson and Schneier, "Practical Cryptography",
+ ISBN 0-471-22357-3, section 10.8). */
+
+ while (true) {
+ var v = this.nextbits(nb) & p;
+
+ if (v <= n) {
+ return v;
+ }
+ }
+ }
+
+//#############################################################################
+// Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (md5.js)
+//#############################################################################
+
+/*
+ * md5.jvs 1.0b 27/06/96
+ *
+ * Javascript implementation of the RSA Data Security, Inc. MD5
+ * Message-Digest Algorithm.
+ *
+ * Copyright (c) 1996 Henri Torgemane. All Rights Reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for any purposes and without
+ * fee is hereby granted provided that this copyright notice
+ * appears in all copies.
+ *
+ * Of course, this soft is provided "as is" without express or implied
+ * warranty of any kind.
+
+ This version contains some trivial reformatting modifications
+ by John Walker.
+
+ */
+
+function array(n) {
+ for (i = 0; i < n; i++) {
+ this[i] = 0;
+ }
+ this.length = n;
+}
+
+/* Some basic logical functions had to be rewritten because of a bug in
+ * Javascript.. Just try to compute 0xffffffff >> 4 with it..
+ * Of course, these functions are slower than the original would be, but
+ * at least, they work!
+ */
+
+function integer(n) {
+ return n % (0xffffffff + 1);
+}
+
+function shr(a, b) {
+ a = integer(a);
+ b = integer(b);
+ if (a - 0x80000000 >= 0) {
+ a = a % 0x80000000;
+ a >>= b;
+ a += 0x40000000 >> (b - 1);
+ } else {
+ a >>= b;
+ }
+ return a;
+}
+
+function shl1(a) {
+ a = a % 0x80000000;
+ if (a & 0x40000000 == 0x40000000) {
+ a -= 0x40000000;
+ a *= 2;
+ a += 0x80000000;
+ } else {
+ a *= 2;
+ }
+ return a;
+}
+
+function shl(a, b) {
+ a = integer(a);
+ b = integer(b);
+ for (var i = 0; i < b; i++) {
+ a = shl1(a);
+ }
+ return a;
+}
+
+function and(a, b) {
+ a = integer(a);
+ b = integer(b);
+ var t1 = a - 0x80000000;
+ var t2 = b - 0x80000000;
+ if (t1 >= 0) {
+ if (t2 >= 0) {
+ return ((t1 & t2) + 0x80000000);
+ } else {
+ return (t1 & b);
+ }
+ } else {
+ if (t2 >= 0) {
+ return (a & t2);
+ } else {
+ return (a & b);
+ }
+ }
+}
+
+function or(a, b) {
+ a = integer(a);
+ b = integer(b);
+ var t1 = a - 0x80000000;
+ var t2 = b - 0x80000000;
+ if (t1 >= 0) {
+ if (t2 >= 0) {
+ return ((t1 | t2) + 0x80000000);
+ } else {
+ return ((t1 | b) + 0x80000000);
+ }
+ } else {
+ if (t2 >= 0) {
+ return ((a | t2) + 0x80000000);
+ } else {
+ return (a | b);
+ }
+ }
+}
+
+function xor(a, b) {
+ a = integer(a);
+ b = integer(b);
+ var t1 = a - 0x80000000;
+ var t2 = b - 0x80000000;
+ if (t1 >= 0) {
+ if (t2 >= 0) {
+ return (t1 ^ t2);
+ } else {
+ return ((t1 ^ b) + 0x80000000);
+ }
+ } else {
+ if (t2 >= 0) {
+ return ((a ^ t2) + 0x80000000);
+ } else {
+ return (a ^ b);
+ }
+ }
+}
+
+function not(a) {
+ a = integer(a);
+ return 0xffffffff - a;
+}
+
+/* Here begin the real algorithm */
+
+var state = new array(4);
+var count = new array(2);
+ count[0] = 0;
+ count[1] = 0;
+var buffer = new array(64);
+var transformBuffer = new array(16);
+var digestBits = new array(16);
+
+var S11 = 7;
+var S12 = 12;
+var S13 = 17;
+var S14 = 22;
+var S21 = 5;
+var S22 = 9;
+var S23 = 14;
+var S24 = 20;
+var S31 = 4;
+var S32 = 11;
+var S33 = 16;
+var S34 = 23;
+var S41 = 6;
+var S42 = 10;
+var S43 = 15;
+var S44 = 21;
+
+function F(x, y, z) {
+ return or(and(x, y), and(not(x), z));
+}
+
+function G(x, y, z) {
+ return or(and(x, z), and(y, not(z)));
+}
+
+function H(x, y, z) {
+ return xor(xor(x, y), z);
+}
+
+function I(x, y, z) {
+ return xor(y ,or(x , not(z)));
+}
+
+function rotateLeft(a, n) {
+ return or(shl(a, n), (shr(a, (32 - n))));
+}
+
+function FF(a, b, c, d, x, s, ac) {
+ a = a + F(b, c, d) + x + ac;
+ a = rotateLeft(a, s);
+ a = a + b;
+ return a;
+}
+
+function GG(a, b, c, d, x, s, ac) {
+ a = a + G(b, c, d) + x + ac;
+ a = rotateLeft(a, s);
+ a = a + b;
+ return a;
+}
+
+function HH(a, b, c, d, x, s, ac) {
+ a = a + H(b, c, d) + x + ac;
+ a = rotateLeft(a, s);
+ a = a + b;
+ return a;
+}
+
+function II(a, b, c, d, x, s, ac) {
+ a = a + I(b, c, d) + x + ac;
+ a = rotateLeft(a, s);
+ a = a + b;
+ return a;
+}
+
+function transform(buf, offset) {
+ var a = 0, b = 0, c = 0, d = 0;
+ var x = transformBuffer;
+
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+
+ for (i = 0; i < 16; i++) {
+ x[i] = and(buf[i * 4 + offset], 0xFF);
+ for (j = 1; j < 4; j++) {
+ x[i] += shl(and(buf[i * 4 + j + offset] ,0xFF), j * 8);
+ }
+ }
+
+ /* Round 1 */
+ a = FF( a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ d = FF( d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ c = FF( c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ b = FF( b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ a = FF( a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ d = FF( d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ c = FF( c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ b = FF( b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ a = FF( a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ d = FF( d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ c = FF( c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ b = FF( b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ a = FF( a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ d = FF( d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ c = FF( c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ b = FF( b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ a = GG( a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ d = GG( d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ c = GG( c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ b = GG( b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ a = GG( a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ d = GG( d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ c = GG( c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ b = GG( b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ a = GG( a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ d = GG( d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ c = GG( c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ b = GG( b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ a = GG( a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ d = GG( d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ c = GG( c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ b = GG( b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ a = HH( a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ d = HH( d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ c = HH( c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ b = HH( b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ a = HH( a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ d = HH( d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ c = HH( c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ b = HH( b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ a = HH( a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ d = HH( d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ c = HH( c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ b = HH( b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ a = HH( a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ d = HH( d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ c = HH( c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ b = HH( b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ a = II( a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ d = II( d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ c = II( c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ b = II( b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ a = II( a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ d = II( d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ c = II( c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ b = II( b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ a = II( a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ d = II( d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ c = II( c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ b = II( b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ a = II( a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ d = II( d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ c = II( c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ b = II( b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+}
+
+function md5_init() {
+ count[0] = count[1] = 0;
+ state[0] = 0x67452301;
+ state[1] = 0xefcdab89;
+ state[2] = 0x98badcfe;
+ state[3] = 0x10325476;
+ for (i = 0; i < digestBits.length; i++) {
+ digestBits[i] = 0;
+ }
+}
+
+function md5_update(b) {
+ var index, i;
+
+ index = and(shr(count[0],3) , 0x3F);
+ if (count[0] < 0xFFFFFFFF - 7) {
+ count[0] += 8;
+ } else {
+ count[1]++;
+ count[0] -= 0xFFFFFFFF + 1;
+ count[0] += 8;
+ }
+ buffer[index] = and(b, 0xff);
+ if (index >= 63) {
+ transform(buffer, 0);
+ }
+}
+
+function md5_finish() {
+ var bits = new array(8);
+ var padding;
+ var i = 0, index = 0, padLen = 0;
+
+ for (i = 0; i < 4; i++) {
+ bits[i] = and(shr(count[0], (i * 8)), 0xFF);
+ }
+ for (i = 0; i < 4; i++) {
+ bits[i + 4] = and(shr(count[1], (i * 8)), 0xFF);
+ }
+ index = and(shr(count[0], 3), 0x3F);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ padding = new array(64);
+ padding[0] = 0x80;
+ for (i = 0; i < padLen; i++) {
+ md5_update(padding[i]);
+ }
+ for (i = 0; i < 8; i++) {
+ md5_update(bits[i]);
+ }
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ digestBits[i * 4 + j] = and(shr(state[i], (j * 8)) , 0xFF);
+ }
+ }
+}
+
+/* End of the MD5 algorithm */
+
+//#############################################################################
+// Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (aes.js)
+//#############################################################################
+
+
+/* rijndael.js Rijndael Reference Implementation
+
+ This is a modified version of the software described below,
+ produced in September 2003 by John Walker for use in the
+ JavsScrypt browser-based encryption package. The principal
+ changes are replacing the original getRandomBytes function with
+ one which calls our pseudorandom generator (which must
+ be instantiated and seeded before the first call on getRandomBytes),
+ and changing keySizeInBits to 256. Some code not required by the
+ JavsScrypt application has been commented out. Please see
+ http://www.fourmilab.ch/javascrypt/ for further information on
+ JavaScrypt.
+
+ The following is the original copyright and application
+ information.
+
+ Copyright (c) 2001 Fritz Schneider
+
+ This software is provided as-is, without express or implied warranty.
+ Permission to use, copy, modify, distribute or sell this software, with or
+ without fee, for any purpose and by any individual or organization, is hereby
+ granted, provided that the above copyright notice and this paragraph appear
+ in all copies. Distribution as a part of an application or binary must
+ include the above copyright notice in the documentation and/or other materials
+ provided with the application or distribution.
+
+ As the above disclaimer notes, you are free to use this code however you
+ want. However, I would request that you send me an email
+ (fritz /at/ cs /dot/ ucsd /dot/ edu) to say hi if you find this code useful
+ or instructional. Seeing that people are using the code acts as
+ encouragement for me to continue development. If you *really* want to thank
+ me you can buy the book I wrote with Thomas Powell, _JavaScript:
+ _The_Complete_Reference_ :)
+
+ This code is an UNOPTIMIZED REFERENCE implementation of Rijndael.
+ If there is sufficient interest I can write an optimized (word-based,
+ table-driven) version, although you might want to consider using a
+ compiled language if speed is critical to your application. As it stands,
+ one run of the monte carlo test (10,000 encryptions) can take up to
+ several minutes, depending upon your processor. You shouldn't expect more
+ than a few kilobytes per second in throughput.
+
+ Also note that there is very little error checking in these functions.
+ Doing proper error checking is always a good idea, but the ideal
+ implementation (using the instanceof operator and exceptions) requires
+ IE5+/NS6+, and I've chosen to implement this code so that it is compatible
+ with IE4/NS4.
+
+ And finally, because JavaScript doesn't have an explicit byte/char data
+ type (although JavaScript 2.0 most likely will), when I refer to "byte"
+ in this code I generally mean "32 bit integer with value in the interval
+ [0,255]" which I treat as a byte.
+
+ See http://www-cse.ucsd.edu/~fritz/rijndael.html for more documentation
+ of the (very simple) API provided by this code.
+
+ Fritz Schneider
+ fritz at cs.ucsd.edu
+
+*/
+
+
+// Rijndael parameters -- Valid values are 128, 192, or 256
+
+var keySizeInBits = 256;
+var blockSizeInBits = 128;
+
+//
+// Note: in the following code the two dimensional arrays are indexed as
+// you would probably expect, as array[row][column]. The state arrays
+// are 2d arrays of the form state[4][Nb].
+
+
+// The number of rounds for the cipher, indexed by [Nk][Nb]
+var roundsArray = [ ,,,,[,,,,10,, 12,, 14],,
+ [,,,,12,, 12,, 14],,
+ [,,,,14,, 14,, 14] ];
+
+// The number of bytes to shift by in shiftRow, indexed by [Nb][row]
+var shiftOffsets = [ ,,,,[,1, 2, 3],,[,1, 2, 3],,[,1, 3, 4] ];
+
+// The round constants used in subkey expansion
+var Rcon = [
+0x01, 0x02, 0x04, 0x08, 0x10, 0x20,
+0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8,
+0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc,
+0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4,
+0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 ];
+
+// Precomputed lookup table for the SBox
+var SBox = [
+ 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171,
+118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164,
+114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113,
+216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226,
+235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214,
+179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203,
+190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69,
+249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245,
+188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68,
+23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42,
+144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73,
+ 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109,
+141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37,
+ 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62,
+181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225,
+248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
+140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187,
+ 22 ];
+
+// Precomputed lookup table for the inverse SBox
+var SBoxInverse = [
+ 82, 9, 106, 213, 48, 54, 165, 56, 191, 64, 163, 158, 129, 243, 215,
+251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142, 67, 68, 196, 222,
+233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76, 149, 11, 66,
+250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162, 73,
+109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92,
+204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21,
+ 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247,
+228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2,
+193, 175, 189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220,
+234, 151, 242, 207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173,
+ 53, 133, 226, 249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29,
+ 41, 197, 137, 111, 183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75,
+198, 210, 121, 32, 154, 219, 192, 254, 120, 205, 90, 244, 31, 221, 168,
+ 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128, 236, 95, 96, 81,
+127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201, 156, 239, 160,
+224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83, 153, 97,
+ 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85, 33, 12,
+125 ];
+
+// This method circularly shifts the array left by the number of elements
+// given in its parameter. It returns the resulting array and is used for
+// the ShiftRow step. Note that shift() and push() could be used for a more
+// elegant solution, but they require IE5.5+, so I chose to do it manually.
+
+function cyclicShiftLeft(theArray, positions) {
+ var temp = theArray.slice(0, positions);
+ theArray = theArray.slice(positions).concat(temp);
+ return theArray;
+}
+
+// Cipher parameters ... do not change these
+var Nk = keySizeInBits / 32;
+var Nb = blockSizeInBits / 32;
+var Nr = roundsArray[Nk][Nb];
+
+// Multiplies the element "poly" of GF(2^8) by x. See the Rijndael spec.
+
+function xtime(poly) {
+ poly <<= 1;
+ return ((poly & 0x100) ? (poly ^ 0x11B) : (poly));
+}
+
+// Multiplies the two elements of GF(2^8) together and returns the result.
+// See the Rijndael spec, but should be straightforward: for each power of
+// the indeterminant that has a 1 coefficient in x, add y times that power
+// to the result. x and y should be bytes representing elements of GF(2^8)
+
+function mult_GF256(x, y) {
+ var bit, result = 0;
+
+ for (bit = 1; bit < 256; bit *= 2, y = xtime(y)) {
+ if (x & bit)
+ result ^= y;
+ }
+ return result;
+}
+
+// Performs the substitution step of the cipher. State is the 2d array of
+// state information (see spec) and direction is string indicating whether
+// we are performing the forward substitution ("encrypt") or inverse
+// substitution (anything else)
+
+function byteSub(state, direction) {
+ var S;
+ if (direction == "encrypt") // Point S to the SBox we're using
+ S = SBox;
+ else
+ S = SBoxInverse;
+ for (var i = 0; i < 4; i++) // Substitute for every byte in state
+ for (var j = 0; j < Nb; j++)
+ state[i][j] = S[state[i][j]];
+}
+
+// Performs the row shifting step of the cipher.
+
+function shiftRow(state, direction) {
+ for (var i=1; i<4; i++) // Row 0 never shifts
+ if (direction == "encrypt")
+ state[i] = cyclicShiftLeft(state[i], shiftOffsets[Nb][i]);
+ else
+ state[i] = cyclicShiftLeft(state[i], Nb - shiftOffsets[Nb][i]);
+
+}
+
+// Performs the column mixing step of the cipher. Most of these steps can
+// be combined into table lookups on 32bit values (at least for encryption)
+// to greatly increase the speed.
+
+function mixColumn(state, direction) {
+ var b = []; // Result of matrix multiplications
+ for (var j = 0; j < Nb; j++) { // Go through each column...
+ for (var i = 0; i < 4; i++) { // and for each row in the column...
+ if (direction == "encrypt")
+ b[i] = mult_GF256(state[i][j], 2) ^ // perform mixing
+ mult_GF256(state[(i+1)%4][j], 3) ^
+ state[(i+2)%4][j] ^
+ state[(i+3)%4][j];
+ else
+ b[i] = mult_GF256(state[i][j], 0xE) ^
+ mult_GF256(state[(i+1)%4][j], 0xB) ^
+ mult_GF256(state[(i+2)%4][j], 0xD) ^
+ mult_GF256(state[(i+3)%4][j], 9);
+ }
+ for (var i = 0; i < 4; i++) // Place result back into column
+ state[i][j] = b[i];
+ }
+}
+
+// Adds the current round key to the state information. Straightforward.
+
+function addRoundKey(state, roundKey) {
+ for (var j = 0; j < Nb; j++) { // Step through columns...
+ state[0][j] ^= (roundKey[j] & 0xFF); // and XOR
+ state[1][j] ^= ((roundKey[j]>>8) & 0xFF);
+ state[2][j] ^= ((roundKey[j]>>16) & 0xFF);
+ state[3][j] ^= ((roundKey[j]>>24) & 0xFF);
+ }
+}
+
+// This function creates the expanded key from the input (128/192/256-bit)
+// key. The parameter key is an array of bytes holding the value of the key.
+// The returned value is an array whose elements are the 32-bit words that
+// make up the expanded key.
+
+function keyExpansion(key) {
+ var expandedKey = new Array();
+ var temp;
+
+ // in case the key size or parameters were changed...
+ Nk = keySizeInBits / 32;
+ Nb = blockSizeInBits / 32;
+ Nr = roundsArray[Nk][Nb];
+
+ for (var j=0; j < Nk; j++) // Fill in input key first
+ expandedKey[j] =
+ (key[4*j]) | (key[4*j+1]<<8) | (key[4*j+2]<<16) | (key[4*j+3]<<24);
+
+ // Now walk down the rest of the array filling in expanded key bytes as
+ // per Rijndael's spec
+ for (j = Nk; j < Nb * (Nr + 1); j++) { // For each word of expanded key
+ temp = expandedKey[j - 1];
+ if (j % Nk == 0)
+ temp = ( (SBox[(temp>>8) & 0xFF]) |
+ (SBox[(temp>>16) & 0xFF]<<8) |
+ (SBox[(temp>>24) & 0xFF]<<16) |
+ (SBox[temp & 0xFF]<<24) ) ^ Rcon[Math.floor(j / Nk) - 1];
+ else if (Nk > 6 && j % Nk == 4)
+ temp = (SBox[(temp>>24) & 0xFF]<<24) |
+ (SBox[(temp>>16) & 0xFF]<<16) |
+ (SBox[(temp>>8) & 0xFF]<<8) |
+ (SBox[temp & 0xFF]);
+ expandedKey[j] = expandedKey[j-Nk] ^ temp;
+ }
+ return expandedKey;
+}
+
+// Rijndael's round functions...
+
+function Round(state, roundKey) {
+ byteSub(state, "encrypt");
+ shiftRow(state, "encrypt");
+ mixColumn(state, "encrypt");
+ addRoundKey(state, roundKey);
+}
+
+function InverseRound(state, roundKey) {
+ addRoundKey(state, roundKey);
+ mixColumn(state, "decrypt");
+ shiftRow(state, "decrypt");
+ byteSub(state, "decrypt");
+}
+
+function FinalRound(state, roundKey) {
+ byteSub(state, "encrypt");
+ shiftRow(state, "encrypt");
+ addRoundKey(state, roundKey);
+}
+
+function InverseFinalRound(state, roundKey){
+ addRoundKey(state, roundKey);
+ shiftRow(state, "decrypt");
+ byteSub(state, "decrypt");
+}
+
+// encrypt is the basic encryption function. It takes parameters
+// block, an array of bytes representing a plaintext block, and expandedKey,
+// an array of words representing the expanded key previously returned by
+// keyExpansion(). The ciphertext block is returned as an array of bytes.
+
+function encrypt(block, expandedKey) {
+ var i;
+ if (!block || block.length*8 != blockSizeInBits)
+ return;
+ if (!expandedKey)
+ return;
+
+ block = packBytes(block);
+ addRoundKey(block, expandedKey);
+ for (i=1; i<Nr; i++)
+ Round(block, expandedKey.slice(Nb*i, Nb*(i+1)));
+ FinalRound(block, expandedKey.slice(Nb*Nr));
+ return unpackBytes(block);
+}
+
+// decrypt is the basic decryption function. It takes parameters
+// block, an array of bytes representing a ciphertext block, and expandedKey,
+// an array of words representing the expanded key previously returned by
+// keyExpansion(). The decrypted block is returned as an array of bytes.
+
+function decrypt(block, expandedKey) {
+ var i;
+ if (!block || block.length*8 != blockSizeInBits)
+ return;
+ if (!expandedKey)
+ return;
+
+ block = packBytes(block);
+ InverseFinalRound(block, expandedKey.slice(Nb*Nr));
+ for (i = Nr - 1; i>0; i--)
+ InverseRound(block, expandedKey.slice(Nb*i, Nb*(i+1)));
+ addRoundKey(block, expandedKey);
+ return unpackBytes(block);
+}
+
+/* !NEEDED
+// This method takes a byte array (byteArray) and converts it to a string by
+// applying String.fromCharCode() to each value and concatenating the result.
+// The resulting string is returned. Note that this function SKIPS zero bytes
+// under the assumption that they are padding added in formatPlaintext().
+// Obviously, do not invoke this method on raw data that can contain zero
+// bytes. It is really only appropriate for printable ASCII/Latin-1
+// values. Roll your own function for more robust functionality :)
+
+function byteArrayToString(byteArray) {
+ var result = "";
+ for(var i=0; i<byteArray.length; i++)
+ if (byteArray[i] != 0)
+ result += String.fromCharCode(byteArray[i]);
+ return result;
+}
+*/
+
+// This function takes an array of bytes (byteArray) and converts them
+// to a hexadecimal string. Array element 0 is found at the beginning of
+// the resulting string, high nibble first. Consecutive elements follow
+// similarly, for example [16, 255] --> "10ff". The function returns a
+// string.
+
+function byteArrayToHex(byteArray) {
+ var result = "";
+ if (!byteArray)
+ return;
+ for (var i=0; i<byteArray.length; i++)
+ result += ((byteArray[i]<16) ? "0" : "") + byteArray[i].toString(16);
+
+ return result;
+}
+
+// This function converts a string containing hexadecimal digits to an
+// array of bytes. The resulting byte array is filled in the order the
+// values occur in the string, for example "10FF" --> [16, 255]. This
+// function returns an array.
+
+function hexToByteArray(hexString) {
+ var byteArray = [];
+ if (hexString.length % 2) // must have even length
+ return;
+ if (hexString.indexOf("0x") == 0 || hexString.indexOf("0X") == 0)
+ hexString = hexString.substring(2);
+ for (var i = 0; i<hexString.length; i += 2)
+ byteArray[Math.floor(i/2)] = parseInt(hexString.slice(i, i+2), 16);
+ return byteArray;
+}
+
+// This function packs an array of bytes into the four row form defined by
+// Rijndael. It assumes the length of the array of bytes is divisible by
+// four. Bytes are filled in according to the Rijndael spec (starting with
+// column 0, row 0 to 3). This function returns a 2d array.
+
+function packBytes(octets) {
+ var state = new Array();
+ if (!octets || octets.length % 4)
+ return;
+
+ state[0] = new Array(); state[1] = new Array();
+ state[2] = new Array(); state[3] = new Array();
+ for (var j=0; j<octets.length; j+= 4) {
+ state[0][j/4] = octets[j];
+ state[1][j/4] = octets[j+1];
+ state[2][j/4] = octets[j+2];
+ state[3][j/4] = octets[j+3];
+ }
+ return state;
+}
+
+// This function unpacks an array of bytes from the four row format preferred
+// by Rijndael into a single 1d array of bytes. It assumes the input "packed"
+// is a packed array. Bytes are filled in according to the Rijndael spec.
+// This function returns a 1d array of bytes.
+
+function unpackBytes(packed) {
+ var result = new Array();
+ for (var j=0; j<packed[0].length; j++) {
+ result[result.length] = packed[0][j];
+ result[result.length] = packed[1][j];
+ result[result.length] = packed[2][j];
+ result[result.length] = packed[3][j];
+ }
+ return result;
+}
+
+// This function takes a prospective plaintext (string or array of bytes)
+// and pads it with pseudorandom bytes if its length is not a multiple of the block
+// size. If plaintext is a string, it is converted to an array of bytes
+// in the process. The type checking can be made much nicer using the
+// instanceof operator, but this operator is not available until IE5.0 so I
+// chose to use the heuristic below.
+
+function formatPlaintext(plaintext) {
+ var bpb = blockSizeInBits / 8; // bytes per block
+ var fillWithRandomBits;
+ var i;
+
+ // if primitive string or String instance
+ if ((!((typeof plaintext == "object") &&
+ ((typeof (plaintext[0])) == "number"))) &&
+ ((typeof plaintext == "string") || plaintext.indexOf))
+ {
+ plaintext = plaintext.split("");
+ // Unicode issues here (ignoring high byte)
+ for (i=0; i<plaintext.length; i++) {
+ plaintext[i] = plaintext[i].charCodeAt(0) & 0xFF;
+ }
+ }
+
+ i = plaintext.length % bpb;
+ if (i > 0) {
+//alert("adding " + (bpb - 1) + " bytes");
+// plaintext = plaintext.concat(getRandomBytes(bpb - i));
+ {
+ var paddingBytes;
+ var ii,cc;
+
+ paddingBytes = new Array();
+ cc = bpb - i;
+ for (ii=0; ii<cc; ii++) {
+ paddingBytes[ii] = cc;
+ }
+
+//is("cc", cc);
+//is(getRandomBytes(bpb - i) + "", paddingBytes + "");
+ plaintext = plaintext.concat(paddingBytes);
+ }
+ }
+
+ return plaintext;
+}
+
+// Returns an array containing "howMany" random bytes.
+
+function getRandomBytes(howMany) {
+ var i, bytes = new Array();
+
+//alert("getting some random bytes");
+ for (i = 0; i < howMany; i++) {
+ bytes[i] = prng.nextInt(255);
+ }
+ return bytes;
+}
+
+// rijndaelEncrypt(plaintext, key, mode)
+// Encrypts the plaintext using the given key and in the given mode.
+// The parameter "plaintext" can either be a string or an array of bytes.
+// The parameter "key" must be an array of key bytes. If you have a hex
+// string representing the key, invoke hexToByteArray() on it to convert it
+// to an array of bytes. The third parameter "mode" is a string indicating
+// the encryption mode to use, either "ECB" or "CBC". If the parameter is
+// omitted, ECB is assumed.
+//
+// An array of bytes representing the cihpertext is returned. To convert
+// this array to hex, invoke byteArrayToHex() on it.
+
+function rijndaelEncrypt(plaintext, key, mode) {
+ var expandedKey, i, aBlock;
+ var bpb = blockSizeInBits / 8; // bytes per block
+ var ct; // ciphertext
+
+ if (!plaintext || !key)
+ return;
+ if (key.length*8 != keySizeInBits)
+ return;
+ if (mode == "CBC") {
+ ct = getRandomBytes(bpb); // get IV
+//dump("IV", byteArrayToHex(ct));
+ } else {
+ mode = "ECB";
+ ct = new Array();
+ }
+
+ // convert plaintext to byte array and pad with zeros if necessary.
+ plaintext = formatPlaintext(plaintext);
+
+ expandedKey = keyExpansion(key);
+
+ for (var block = 0; block < plaintext.length / bpb; block++) {
+ aBlock = plaintext.slice(block * bpb, (block + 1) * bpb);
+ if (mode == "CBC") {
+ for (var i = 0; i < bpb; i++) {
+ aBlock[i] ^= ct[(block * bpb) + i];
+ }
+ }
+ ct = ct.concat(encrypt(aBlock, expandedKey));
+ }
+
+ return ct;
+}
+
+// rijndaelDecrypt(ciphertext, key, mode)
+// Decrypts the using the given key and mode. The parameter "ciphertext"
+// must be an array of bytes. The parameter "key" must be an array of key
+// bytes. If you have a hex string representing the ciphertext or key,
+// invoke hexToByteArray() on it to convert it to an array of bytes. The
+// parameter "mode" is a string, either "CBC" or "ECB".
+//
+// An array of bytes representing the plaintext is returned. To convert
+// this array to a hex string, invoke byteArrayToHex() on it. To convert it
+// to a string of characters, you can use byteArrayToString().
+
+function rijndaelDecrypt(ciphertext, key, mode) {
+ var expandedKey;
+ var bpb = blockSizeInBits / 8; // bytes per block
+ var pt = new Array(); // plaintext array
+ var aBlock; // a decrypted block
+ var block; // current block number
+
+ if (!ciphertext || !key || typeof ciphertext == "string")
+ return;
+ if (key.length*8 != keySizeInBits)
+ return;
+ if (!mode) {
+ mode = "ECB"; // assume ECB if mode omitted
+ }
+
+ expandedKey = keyExpansion(key);
+
+ // work backwards to accomodate CBC mode
+ for (block=(ciphertext.length / bpb)-1; block>0; block--) {
+ aBlock =
+ decrypt(ciphertext.slice(block*bpb,(block+1)*bpb), expandedKey);
+ if (mode == "CBC")
+ for (var i=0; i<bpb; i++)
+ pt[(block-1)*bpb + i] = aBlock[i] ^ ciphertext[(block-1)*bpb + i];
+ else
+ pt = aBlock.concat(pt);
+ }
+
+ // do last block if ECB (skips the IV in CBC)
+ if (mode == "ECB")
+ pt = decrypt(ciphertext.slice(0, bpb), expandedKey).concat(pt);
+
+ return pt;
+}
+
+//#############################################################################
+// Downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip (utf-8.js)
+//#############################################################################
+
+
+ /* Encoding and decoding of Unicode character strings as
+ UTF-8 byte streams. */
+
+ // UNICODE_TO_UTF8 -- Encode Unicode argument string as UTF-8 return value
+
+ function unicode_to_utf8(s) {
+ var utf8 = "";
+
+ for (var n = 0; n < s.length; n++) {
+ var c = s.charCodeAt(n);
+
+ if (c <= 0x7F) {
+ // 0x00 - 0x7F: Emit as single byte, unchanged
+ utf8 += String.fromCharCode(c);
+ } else if ((c >= 0x80) && (c <= 0x7FF)) {
+ // 0x80 - 0x7FF: Output as two byte code, 0xC0 in first byte
+ // 0x80 in second byte
+ utf8 += String.fromCharCode((c >> 6) | 0xC0);
+ utf8 += String.fromCharCode((c & 0x3F) | 0x80);
+ } else {
+ // 0x800 - 0xFFFF: Output as three bytes, 0xE0 in first byte
+ // 0x80 in second byte
+ // 0x80 in third byte
+ utf8 += String.fromCharCode((c >> 12) | 0xE0);
+ utf8 += String.fromCharCode(((c >> 6) & 0x3F) | 0x80);
+ utf8 += String.fromCharCode((c & 0x3F) | 0x80);
+ }
+ }
+ return utf8;
+ }
+
+ // UTF8_TO_UNICODE -- Decode UTF-8 argument into Unicode string return value
+
+ function utf8_to_unicode(utf8) {
+ var s = "", i = 0, b1, b2, b2;
+
+ while (i < utf8.length) {
+ b1 = utf8.charCodeAt(i);
+ if (b1 < 0x80) { // One byte code: 0x00 0x7F
+ s += String.fromCharCode(b1);
+ i++;
+ } else if((b1 >= 0xC0) && (b1 < 0xE0)) { // Two byte code: 0x80 - 0x7FF
+ b2 = utf8.charCodeAt(i + 1);
+ s += String.fromCharCode(((b1 & 0x1F) << 6) | (b2 & 0x3F));
+ i += 2;
+ } else { // Three byte code: 0x800 - 0xFFFF
+ b2 = utf8.charCodeAt(i + 1);
+ b3 = utf8.charCodeAt(i + 2);
+ s += String.fromCharCode(((b1 & 0xF) << 12) |
+ ((b2 & 0x3F) << 6) |
+ (b3 & 0x3F));
+ i += 3;
+ }
+ }
+ return s;
+ }
+
+ /* ENCODE_UTF8 -- Encode string as UTF8 only if it contains
+ a character of 0x9D (Unicode OPERATING
+ SYSTEM COMMAND) or a character greater
+ than 0xFF. This permits all strings
+ consisting exclusively of 8 bit
+ graphic characters to be encoded as
+ themselves. We choose 0x9D as the sentinel
+ character as opposed to one of the more
+ logical PRIVATE USE characters because 0x9D
+ is not overloaded by the regrettable
+ "Windows-1252" character set. Now such characters
+ don't belong in JavaScript strings, but you never
+ know what somebody is going to paste into a
+ text box, so this choice keeps Windows-encoded
+ strings from bloating to UTF-8 encoding. */
+
+ function encode_utf8(s) {
+ var i, necessary = false;
+
+ for (i = 0; i < s.length; i++) {
+ if ((s.charCodeAt(i) == 0x9D) ||
+ (s.charCodeAt(i) > 0xFF)) {
+ necessary = true;
+ break;
+ }
+ }
+ if (!necessary) {
+ return s;
+ }
+ return String.fromCharCode(0x9D) + unicode_to_utf8(s);
+ }
+
+ /* DECODE_UTF8 -- Decode a string encoded with encode_utf8
+ above. If the string begins with the
+ sentinel character 0x9D (OPERATING
+ SYSTEM COMMAND), then we decode the
+ balance as a UTF-8 stream. Otherwise,
+ the string is output unchanged, as
+ it's guaranteed to contain only 8 bit
+ characters excluding 0x9D. */
+
+ function decode_utf8(s) {
+ if ((s.length > 0) && (s.charCodeAt(0) == 0x9D)) {
+ return utf8_to_unicode(s.substring(1));
+ }
+ return s;
+ }
+
+
+//#############################################################################
+// Downloaded on April 26, 2006 from http://pajhome.org.uk/crypt/md5/md5.js
+//#############################################################################
+
+/*
+ * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
+ * Digest Algorithm, as defined in RFC 1321.
+ * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for more info.
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
+var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
+var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
+function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
+function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
+function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
+function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
+function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }
+
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function md5_vm_test()
+{
+ return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
+}
+
+/*
+ * Calculate the MD5 of an array of little-endian words, and a bit length
+ */
+function core_md5(x, len)
+{
+ /* append padding */
+ x[len >> 5] |= 0x80 << ((len) % 32);
+ x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+ var a = 1732584193;
+ var b = -271733879;
+ var c = -1732584194;
+ var d = 271733878;
+
+ for(var i = 0; i < x.length; i += 16)
+ {
+ var olda = a;
+ var oldb = b;
+ var oldc = c;
+ var oldd = d;
+
+ a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
+ d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
+ c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
+ b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
+ a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
+ d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
+ c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
+ b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
+ a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
+ d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
+ c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
+ b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
+ a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
+ d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
+ c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
+ b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
+
+ a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
+ d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
+ c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
+ b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
+ a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
+ d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
+ c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
+ b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
+ a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
+ d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
+ c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
+ b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
+ a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
+ d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
+ c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
+ b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
+
+ a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
+ d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
+ c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
+ b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
+ a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
+ d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
+ c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
+ b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
+ a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
+ d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
+ c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
+ b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
+ a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
+ d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
+ c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
+ b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
+
+ a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
+ d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
+ c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
+ b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
+ a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
+ d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
+ c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
+ b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
+ a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
+ d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
+ c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
+ b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
+ a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
+ d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
+ c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
+ b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
+
+ a = safe_add(a, olda);
+ b = safe_add(b, oldb);
+ c = safe_add(c, oldc);
+ d = safe_add(d, oldd);
+ }
+ return Array(a, b, c, d);
+
+}
+
+/*
+ * These functions implement the four basic operations the algorithm uses.
+ */
+function md5_cmn(q, a, b, x, s, t)
+{
+ return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
+}
+function md5_ff(a, b, c, d, x, s, t)
+{
+ return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
+}
+function md5_gg(a, b, c, d, x, s, t)
+{
+ return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
+}
+function md5_hh(a, b, c, d, x, s, t)
+{
+ return md5_cmn(b ^ c ^ d, a, b, x, s, t);
+}
+function md5_ii(a, b, c, d, x, s, t)
+{
+ return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
+}
+
+/*
+ * Calculate the HMAC-MD5, of a key and some data
+ */
+function core_hmac_md5(key, data)
+{
+ var bkey = str2binl(key);
+ if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);
+
+ var ipad = Array(16), opad = Array(16);
+ for(var i = 0; i < 16; i++)
+ {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5C5C5C5C;
+ }
+
+ var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
+ return core_md5(opad.concat(hash), 512 + 128);
+}
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x, y)
+{
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function bit_rol(num, cnt)
+{
+ return (num << cnt) | (num >>> (32 - cnt));
+}
+
+/*
+ * Convert a string to an array of little-endian words
+ * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
+ */
+function str2binl(str)
+{
+ var bin = Array();
+ var mask = (1 << chrsz) - 1;
+ for(var i = 0; i < str.length * chrsz; i += chrsz)
+ bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
+ return bin;
+}
+
+/*
+ * Convert an array of little-endian words to a string
+ */
+function binl2str(bin)
+{
+ var str = "";
+ var mask = (1 << chrsz) - 1;
+ for(var i = 0; i < bin.length * 32; i += chrsz)
+ str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
+ return str;
+}
+
+/*
+ * Convert an array of little-endian words to a hex string.
+ */
+function binl2hex(binarray)
+{
+ var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+ var str = "";
+ for(var i = 0; i < binarray.length * 4; i++)
+ {
+ str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
+ hex_tab.charAt((binarray[i>>2] >> ((i%4)*8 )) & 0xF);
+ }
+ return str;
+}
+
+/*
+ * Convert an array of little-endian words to a base-64 string
+ */
+function binl2b64(binarray)
+{
+ var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var str = "";
+ for(var i = 0; i < binarray.length * 4; i += 3)
+ {
+ var triplet = (((binarray[i >> 2] >> 8 * ( i %4)) & 0xFF) << 16)
+ | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
+ | ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
+ for(var j = 0; j < 4; j++)
+ {
+ if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
+ else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
+ }
+ }
+ return str;
+}
+
+
+//#############################################################################
+//#############################################################################
+//#############################################################################
+
+
+
+MochiKit.Base.update(Clipperz.Crypto.Base, {
+
+ '__repr__': function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+ },
+
+ 'toString': function () {
+ return this.__repr__();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'encryptUsingSecretKey': function (aKey, aMessage) {
+//Clipperz.Profile.start("Clipperz.Crypto.Base.encryptUsingSecretKey");
+ var result;
+ var plaintext;
+ var header;
+ var key;
+
+ key = hexToByteArray(Clipperz.Crypto.Base.computeHashValue(aKey));
+
+ addEntropyTime();
+ prng = new AESprng(keyFromEntropy());
+
+ plaintext = encode_utf8(aMessage);
+
+ header = Clipperz.Base.byteArrayToString(hexToByteArray(Clipperz.Crypto.Base.computeMD5HashValue(plaintext)));
+
+ // Add message length in bytes to header
+ i = plaintext.length;
+ header += String.fromCharCode(i >>> 24);
+ header += String.fromCharCode(i >>> 16);
+ header += String.fromCharCode(i >>> 8);
+ header += String.fromCharCode(i & 0xFF);
+
+ // The format of the actual message passed to rijndaelEncrypt
+ // is:
+ //
+ // Bytes Content
+ // 0-15 MD5 signature of plaintext
+ // 16-19 Length of plaintext, big-endian order
+ // 20-end Plaintext
+ //
+ // Note that this message will be padded with zero bytes
+ // to an integral number of AES blocks (blockSizeInBits / 8).
+ // This does not include the initial vector for CBC
+ // encryption, which is added internally by rijndaelEncrypt.
+ result = byteArrayToHex(rijndaelEncrypt(header + plaintext, key, "CBC"));
+
+ delete prng;
+
+//Clipperz.Profile.stop("Clipperz.Crypto.Base.encryptUsingSecretKey");
+ return result;
+ },
+
+ //.............................................................................
+
+ 'decryptUsingSecretKey': function (aKey, aMessage) {
+//Clipperz.Profile.start("Clipperz.Crypto.Base.decryptUsingSecretKey");
+ var key;
+ var decryptedText;
+ var textLength;
+ var header;
+ var headerDigest;
+ var plaintext;
+ var i;
+
+ key = hexToByteArray(Clipperz.Crypto.Base.computeHashValue(aKey));
+
+ decryptedText = rijndaelDecrypt(hexToByteArray(aMessage), key, "CBC");
+
+ header = decryptedText.slice(0, 20);
+ decryptedText = decryptedText.slice(20);
+
+ headerDigest = byteArrayToHex(header.slice(0,16));
+ textLength = (header[16] << 24) | (header[17] << 16) | (header[18] << 8) | header[19];
+
+ if ((textLength < 0) || (textLength > decryptedText.length)) {
+// jslog.warning("Message (length " + decryptedText.length + ") truncated. " + textLength + " characters expected.");
+ // Try to sauve qui peut by setting length to entire message
+ textLength = decryptedText.length;
+ }
+
+ plainText = "";
+
+ for (i=0; i<textLength; i++) {
+ plainText += String.fromCharCode(decryptedText[i]);
+ }
+
+ if (Clipperz.Crypto.Base.computeMD5HashValue(plainText) != headerDigest) {
+// jslog.warning("Message corrupted. Checksum of decrypted message does not match.");
+ throw Clipperz.Crypto.Base.exception.CorruptedMessage;
+// throw new Error("Message corrupted. Checksum of decrypted message does not match. Parsed result: " + decode_utf8(plainText));
+ }
+
+ // That's it; plug plaintext into the result field
+
+ result = decode_utf8(plainText);
+
+//Clipperz.Profile.stop("Clipperz.Crypto.Base.decryptUsingSecretKey");
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'computeHashValue': function (aMessage) {
+//Clipperz.Profile.start("Clipperz.Crypto.Base.computeHashValue");
+ var result;
+
+ result = hex_sha256(aMessage);
+//Clipperz.Profile.stop("Clipperz.Crypto.Base.computeHashValue");
+
+ return result;
+ },
+
+ //.........................................................................
+
+ 'computeMD5HashValue': function (aMessage) {
+ var result;
+//Clipperz.Profile.start("Clipperz.Crypto.Base.computeMD5HashValue");
+ result = hex_md5(aMessage);
+//Clipperz.Profile.stop("Clipperz.Crypto.Base.computeMD5HashValue");
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'generateRandomSeed': function () {
+//Clipperz.Profile.start("Clipperz.Crypto.Base.generateRandomSeed");
+ var result;
+ var seed;
+ var prng;
+ var charA;
+ var i;
+
+ addEntropyTime();
+
+ seed = keyFromEntropy();
+ prng = new AESprng(seed);
+
+ result = "";
+ charA = ("A").charCodeAt(0);
+
+ for (i = 0; i < 64; i++) {
+ result += String.fromCharCode(charA + prng.nextInt(25));
+ }
+
+ delete prng;
+
+ result = Clipperz.Crypto.Base.computeHashValue(result);
+
+//Clipperz.Profile.stop("Clipperz.Crypto.Base.generateRandomSeed");
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'exception': {
+ 'CorruptedMessage': new MochiKit.Base.NamedError("Clipperz.Crypto.Base.exception.CorruptedMessage")
+ },
+
+ //.........................................................................
+ __syntaxFix__: "syntax fix"
+});
+
diff --git a/frontend/gamma/js/Clipperz/Crypto/BigInt.js b/frontend/gamma/js/Clipperz/Crypto/BigInt.js
new file mode 100644
index 0000000..d4d05d2
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/BigInt.js
@@ -0,0 +1,1760 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
+
+//#############################################################################
+// Downloaded on March 05, 2007 from http://www.leemon.com/crypto/BigInt.js
+//#############################################################################
+
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Big Integer Library v. 5.0
+// Created 2000, last modified 2006
+// Leemon Baird
+// www.leemon.com
+//
+// This file is public domain. You can use it for any purpose without restriction.
+// I do not guarantee that it is correct, so use it at your own risk. If you use
+// it for something interesting, I'd appreciate hearing about it. If you find
+// any bugs or make any improvements, I'd appreciate hearing about those too.
+// It would also be nice if my name and address were left in the comments.
+// But none of that is required.
+//
+// This code defines a bigInt library for arbitrary-precision integers.
+// A bigInt is an array of integers storing the value in chunks of bpe bits,
+// little endian (buff[0] is the least significant word).
+// Negative bigInts are stored two's complement.
+// Some functions assume their parameters have at least one leading zero element.
+// Functions with an underscore at the end of the name have unpredictable behavior in case of overflow,
+// so the caller must make sure overflow won't happen.
+// For each function where a parameter is modified, that same
+// variable must not be used as another argument too.
+// So, you cannot square x by doing multMod_(x,x,n).
+// You must use squareMod_(x,n) instead, or do y=dup(x); multMod_(x,y,n).
+//
+// These functions are designed to avoid frequent dynamic memory allocation in the inner loop.
+// For most functions, if it needs a BigInt as a local variable it will actually use
+// a global, and will only allocate to it when it's not the right size. This ensures
+// that when a function is called repeatedly with same-sized parameters, it only allocates
+// memory on the first call.
+//
+// Note that for cryptographic purposes, the calls to Math.random() must
+// be replaced with calls to a better pseudorandom number generator.
+//
+// In the following, "bigInt" means a bigInt with at least one leading zero element,
+// and "integer" means a nonnegative integer less than radix. In some cases, integer
+// can be negative. Negative bigInts are 2s complement.
+//
+// The following functions do not modify their inputs, but dynamically allocate memory every time they are called:
+//
+// function bigInt2str(x,base) //convert a bigInt into a string in a given base, from base 2 up to base 95
+// function dup(x) //returns a copy of bigInt x
+// function findPrimes(n) //return array of all primes less than integer n
+// function int2bigInt(t,n,m) //convert integer t to a bigInt with at least n bits and m array elements
+// function int2bigInt(s,b,n,m) //convert string s in base b to a bigInt with at least n bits and m array elements
+// function trim(x,k) //return a copy of x with exactly k leading zero elements
+//
+// The following functions do not modify their inputs, so there is never a problem with the result being too big:
+//
+// function bitSize(x) //returns how many bits long the bigInt x is, not counting leading zeros
+// function equals(x,y) //is the bigInt x equal to the bigint y?
+// function equalsInt(x,y) //is bigint x equal to integer y?
+// function greater(x,y) //is x>y? (x and y are nonnegative bigInts)
+// function greaterShift(x,y,shift)//is (x <<(shift*bpe)) > y?
+// function isZero(x) //is the bigInt x equal to zero?
+// function millerRabin(x,b) //does one round of Miller-Rabin base integer b say that bigInt x is possibly prime (as opposed to definitely composite)?
+// function modInt(x,n) //return x mod n for bigInt x and integer n.
+// function negative(x) //is bigInt x negative?
+//
+// The following functions do not modify their inputs, but allocate memory and call functions with underscores
+//
+// function add(x,y) //return (x+y) for bigInts x and y.
+// function addInt(x,n) //return (x+n) where x is a bigInt and n is an integer.
+// function expand(x,n) //return a copy of x with at least n elements, adding leading zeros if needed
+// function inverseMod(x,n) //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null
+// function mod(x,n) //return a new bigInt equal to (x mod n) for bigInts x and n.
+// function mult(x,y) //return x*y for bigInts x and y. This is faster when y<x.
+// function multMod(x,y,n) //return (x*y mod n) for bigInts x,y,n. For greater speed, let y<x.
+// function powMod(x,y,n) //return (x**y mod n) where x,y,n are bigInts and ** is exponentiation. 0**0=1. Faster for odd n.
+// function randTruePrime(k) //return a new, random, k-bit, true prime using Maurer's algorithm.
+// function sub(x,y) //return (x-y) for bigInts x and y. Negative answers will be 2s complement
+//
+// The following functions write a bigInt result to one of the parameters, but
+// the result is never bigger than the original, so there can't be overflow problems:
+//
+// function divInt_(x,n) //do x=floor(x/n) for bigInt x and integer n, and return the remainder
+// function GCD_(x,y) //set x to the greatest common divisor of bigInts x and y, (y is destroyed).
+// function halve_(x) //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement
+// function mod_(x,n) //do x=x mod n for bigInts x and n.
+// function rightShift_(x,n) //right shift bigInt x by n bits. 0 <= n < bpe.
+//
+// The following functions write a bigInt result to one of the parameters. The caller is responsible for
+// ensuring it is large enough to hold the result.
+//
+// function addInt_(x,n) //do x=x+n where x is a bigInt and n is an integer
+// function add_(x,y) //do x=x+y for bigInts x and y
+// function addShift_(x,y,ys) //do x=x+(y<<(ys*bpe))
+// function copy_(x,y) //do x=y on bigInts x and y
+// function copyInt_(x,n) //do x=n on bigInt x and integer n
+// function carry_(x) //do carries and borrows so each element of the bigInt x fits in bpe bits.
+// function divide_(x,y,q,r) //divide_ x by y giving quotient q and remainder r
+// function eGCD_(x,y,d,a,b) //sets a,b,d to positive big integers such that d = GCD_(x,y) = a*x-b*y
+// function inverseMod_(x,n) //do x=x**(-1) mod n, for bigInts x and n. Returns 1 (0) if inverse does (doesn't) exist
+// function inverseModInt_(x,n) //return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse
+// function leftShift_(x,n) //left shift bigInt x by n bits. n<bpe.
+// function linComb_(x,y,a,b) //do x=a*x+b*y for bigInts x and y and integers a and b
+// function linCombShift_(x,y,b,ys) //do x=x+b*(y<<(ys*bpe)) for bigInts x and y, and integers b and ys
+// function mont_(x,y,n,np) //Montgomery multiplication (see comments where the function is defined)
+// function mult_(x,y) //do x=x*y for bigInts x and y.
+// function multInt_(x,n) //do x=x*n where x is a bigInt and n is an integer.
+// function multMod_(x,y,n) //do x=x*y mod n for bigInts x,y,n.
+// function powMod_(x,y,n) //do x=x**y mod n, where x,y,n are bigInts (n is odd) and ** is exponentiation. 0**0=1.
+// function randBigInt_(b,n,s) //do b = an n-bit random BigInt. if s=1, then nth bit (most significant bit) is set to 1. n>=1.
+// function randTruePrime_(ans,k) //do ans = a random k-bit true random prime (not just probable prime) with 1 in the msb.
+// function squareMod_(x,n) //do x=x*x mod n for bigInts x,n
+// function sub_(x,y) //do x=x-y for bigInts x and y. Negative answers will be 2s complement.
+// function subShift_(x,y,ys) //do x=x-(y<<(ys*bpe)). Negative answers will be 2s complement.
+//
+// The following functions are based on algorithms from the _Handbook of Applied Cryptography_
+// powMod_() = algorithm 14.94, Montgomery exponentiation
+// eGCD_,inverseMod_() = algorithm 14.61, Binary extended GCD_
+// GCD_() = algorothm 14.57, Lehmer's algorithm
+// mont_() = algorithm 14.36, Montgomery multiplication
+// divide_() = algorithm 14.20 Multiple-precision division
+// squareMod_() = algorithm 14.16 Multiple-precision squaring
+// randTruePrime_() = algorithm 4.62, Maurer's algorithm
+// millerRabin() = algorithm 4.24, Miller-Rabin algorithm
+//
+// Profiling shows:
+// randTruePrime_() spends:
+// 10% of its time in calls to powMod_()
+// 85% of its time in calls to millerRabin()
+// millerRabin() spends:
+// 99% of its time in calls to powMod_() (always with a base of 2)
+// powMod_() spends:
+// 94% of its time in calls to mont_() (almost always with x==y)
+//
+// This suggests there are several ways to speed up this library slightly:
+// - convert powMod_ to use a Montgomery form of k-ary window (or maybe a Montgomery form of sliding window)
+// -- this should especially focus on being fast when raising 2 to a power mod n
+// - convert randTruePrime_() to use a minimum r of 1/3 instead of 1/2 with the appropriate change to the test
+// - tune the parameters in randTruePrime_(), including c, m, and recLimit
+// - speed up the single loop in mont_() that takes 95% of the runtime, perhaps by reducing checking
+// within the loop when all the parameters are the same length.
+//
+// There are several ideas that look like they wouldn't help much at all:
+// - replacing trial division in randTruePrime_() with a sieve (that speeds up something taking almost no time anyway)
+// - increase bpe from 15 to 30 (that would help if we had a 32*32->64 multiplier, but not with JavaScript's 32*32->32)
+// - speeding up mont_(x,y,n,np) when x==y by doing a non-modular, non-Montgomery square
+// followed by a Montgomery reduction. The intermediate answer will be twice as long as x, so that
+// method would be slower. This is unfortunate because the code currently spends almost all of its time
+// doing mont_(x,x,...), both for randTruePrime_() and powMod_(). A faster method for Montgomery squaring
+// would have a large impact on the speed of randTruePrime_() and powMod_(). HAC has a couple of poorly-worded
+// sentences that seem to imply it's faster to do a non-modular square followed by a single
+// Montgomery reduction, but that's obviously wrong.
+////////////////////////////////////////////////////////////////////////////////////////
+
+//globals
+bpe=0; //bits stored per array element
+mask=0; //AND this with an array element to chop it down to bpe bits
+radix=mask+1; //equals 2^bpe. A single 1 bit to the left of the last bit of mask.
+
+//the digits for converting to different bases
+digitsStr='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_=!@#$%^&*()[]{}|;:,.<>/?`~ \\\'\"+-';
+
+//initialize the global variables
+for (bpe=0; (1<<(bpe+1)) > (1<<bpe); bpe++); //bpe=number of bits in the mantissa on this platform
+bpe>>=1; //bpe=number of bits in one element of the array representing the bigInt
+mask=(1<<bpe)-1; //AND the mask with an integer to get its bpe least significant bits
+radix=mask+1; //2^bpe. a single 1 bit to the left of the first bit of mask
+one=int2bigInt(1,1,1); //constant used in powMod_()
+
+//the following global variables are scratchpad memory to
+//reduce dynamic memory allocation in the inner loop
+t=new Array(0);
+ss=t; //used in mult_()
+s0=t; //used in multMod_(), squareMod_()
+s1=t; //used in powMod_(), multMod_(), squareMod_()
+s2=t; //used in powMod_(), multMod_()
+s3=t; //used in powMod_()
+s4=t; s5=t; //used in mod_()
+s6=t; //used in bigInt2str()
+s7=t; //used in powMod_()
+T=t; //used in GCD_()
+sa=t; //used in mont_()
+mr_x1=t; mr_r=t; mr_a=t; //used in millerRabin()
+eg_v=t; eg_u=t; eg_A=t; eg_B=t; eg_C=t; eg_D=t; //used in eGCD_(), inverseMod_()
+md_q1=t; md_q2=t; md_q3=t; md_r=t; md_r1=t; md_r2=t; md_tt=t; //used in mod_()
+
+primes=t; pows=t; s_i=t; s_i2=t; s_R=t; s_rm=t; s_q=t; s_n1=t;
+ s_a=t; s_r2=t; s_n=t; s_b=t; s_d=t; s_x1=t; s_x2=t, s_aa=t; //used in randTruePrime_()
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+//return array of all primes less than integer n
+function findPrimes(n) {
+ var i,s,p,ans;
+ s=new Array(n);
+ for (i=0;i<n;i++)
+ s[i]=0;
+ s[0]=2;
+ p=0; //first p elements of s are primes, the rest are a sieve
+ for(;s[p]<n;) { //s[p] is the pth prime
+ for(i=s[p]*s[p]; i<n; i+=s[p]) //mark multiples of s[p]
+ s[i]=1;
+ p++;
+ s[p]=s[p-1]+1;
+ for(; s[p]<n && s[s[p]]; s[p]++); //find next prime (where s[p]==0)
+ }
+ ans=new Array(p);
+ for(i=0;i<p;i++)
+ ans[i]=s[i];
+ return ans;
+}
+
+//does a single round of Miller-Rabin base b consider x to be a possible prime?
+//x is a bigInt, and b is an integer
+function millerRabin(x,b) {
+ var i,j,k,s;
+
+ if (mr_x1.length!=x.length) {
+ mr_x1=dup(x);
+ mr_r=dup(x);
+ mr_a=dup(x);
+ }
+
+ copyInt_(mr_a,b);
+ copy_(mr_r,x);
+ copy_(mr_x1,x);
+
+ addInt_(mr_r,-1);
+ addInt_(mr_x1,-1);
+
+ //s=the highest power of two that divides mr_r
+ k=0;
+ for (i=0;i<mr_r.length;i++)
+ for (j=1;j<mask;j<<=1)
+ if (x[i] & j) {
+ s=(k<mr_r.length+bpe ? k : 0);
+ i=mr_r.length;
+ j=mask;
+ } else
+ k++;
+
+ if (s)
+ rightShift_(mr_r,s);
+
+ powMod_(mr_a,mr_r,x);
+
+ if (!equalsInt(mr_a,1) && !equals(mr_a,mr_x1)) {
+ j=1;
+ while (j<=s-1 && !equals(mr_a,mr_x1)) {
+ squareMod_(mr_a,x);
+ if (equalsInt(mr_a,1)) {
+ return 0;
+ }
+ j++;
+ }
+ if (!equals(mr_a,mr_x1)) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+//returns how many bits long the bigInt is, not counting leading zeros.
+function bitSize(x) {
+ var j,z,w;
+ for (j=x.length-1; (x[j]==0) && (j>0); j--);
+ for (z=0,w=x[j]; w; (w>>=1),z++);
+ z+=bpe*j;
+ return z;
+}
+
+//return a copy of x with at least n elements, adding leading zeros if needed
+function expand(x,n) {
+ var ans=int2bigInt(0,(x.length>n ? x.length : n)*bpe,0);
+ copy_(ans,x);
+ return ans;
+}
+
+//return a k-bit true random prime using Maurer's algorithm.
+function randTruePrime(k) {
+ var ans=int2bigInt(0,k,0);
+ randTruePrime_(ans,k);
+ return trim(ans,1);
+}
+
+//return a new bigInt equal to (x mod n) for bigInts x and n.
+function mod(x,n) {
+ var ans=dup(x);
+ mod_(ans,n);
+ return trim(ans,1);
+}
+
+//return (x+n) where x is a bigInt and n is an integer.
+function addInt(x,n) {
+ var ans=expand(x,x.length+1);
+ addInt_(ans,n);
+ return trim(ans,1);
+}
+
+//return x*y for bigInts x and y. This is faster when y<x.
+function mult(x,y) {
+ var ans=expand(x,x.length+y.length);
+ mult_(ans,y);
+ return trim(ans,1);
+}
+
+//return (x**y mod n) where x,y,n are bigInts and ** is exponentiation. 0**0=1. Faster for odd n.
+function powMod(x,y,n) {
+ var ans=expand(x,n.length);
+ powMod_(ans,trim(y,2),trim(n,2),0); //this should work without the trim, but doesn't
+ return trim(ans,1);
+}
+
+//return (x-y) for bigInts x and y. Negative answers will be 2s complement
+function sub(x,y) {
+ var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1));
+ sub_(ans,y);
+ return trim(ans,1);
+}
+
+//return (x+y) for bigInts x and y.
+function add(x,y) {
+ var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1));
+ add_(ans,y);
+ return trim(ans,1);
+}
+
+//return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null
+function inverseMod(x,n) {
+ var ans=expand(x,n.length);
+ var s;
+ s=inverseMod_(ans,n);
+ return s ? trim(ans,1) : null;
+}
+
+//return (x*y mod n) for bigInts x,y,n. For greater speed, let y<x.
+function multMod(x,y,n) {
+ var ans=expand(x,n.length);
+ multMod_(ans,y,n);
+ return trim(ans,1);
+}
+
+//generate a k-bit true random prime using Maurer's algorithm,
+//and put it into ans. The bigInt ans must be large enough to hold it.
+function randTruePrime_(ans,k) {
+ var c,m,pm,dd,j,r,B,divisible,z,zz,recSize;
+
+ if (primes.length==0)
+ primes=findPrimes(30000); //check for divisibility by primes <=30000
+
+ if (pows.length==0) {
+ pows=new Array(512);
+ for (j=0;j<512;j++) {
+ pows[j]=Math.pow(2,j/511.-1.);
+ }
+ }
+
+ //c and m should be tuned for a particular machine and value of k, to maximize speed
+ //this was: c=primes[primes.length-1]/k/k; //check using all the small primes. (c=0.1 in HAC)
+ c=0.1;
+ m=20; //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
+ recLimit=20; /*must be at least 2 (was 29)*/ //stop recursion when k <=recLimit
+
+ if (s_i2.length!=ans.length) {
+ s_i2=dup(ans);
+ s_R =dup(ans);
+ s_n1=dup(ans);
+ s_r2=dup(ans);
+ s_d =dup(ans);
+ s_x1=dup(ans);
+ s_x2=dup(ans);
+ s_b =dup(ans);
+ s_n =dup(ans);
+ s_i =dup(ans);
+ s_rm=dup(ans);
+ s_q =dup(ans);
+ s_a =dup(ans);
+ s_aa=dup(ans);
+ }
+
+ if (k <= recLimit) { //generate small random primes by trial division up to its square root
+ pm=(1<<((k+2)>>1))-1; //pm is binary number with all ones, just over sqrt(2^k)
+ copyInt_(ans,0);
+ for (dd=1;dd;) {
+ dd=0;
+ ans[0]= 1 | (1<<(k-1)) | Math.floor(Math.random()*(1<<k)); //random, k-bit, odd integer, with msb 1
+ for (j=1;(j<primes.length) && ((primes[j]&pm)==primes[j]);j++) { //trial division by all primes 3...sqrt(2^k)
+ if (0==(ans[0]%primes[j])) {
+ dd=1;
+ break;
+ }
+ }
+ }
+ carry_(ans);
+ return;
+ }
+
+ B=c*k*k; //try small primes up to B (or all the primes[] array if the largest is less than B).
+ if (k>2*m) //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
+ for (r=1; k-k*r<=m; )
+ r=pows[Math.floor(Math.random()*512)]; //r=Math.pow(2,Math.random()-1);
+ else
+ r=.5;
+
+ //simulation suggests the more complex algorithm using r=.333 is only slightly faster.
+
+ recSize=Math.floor(r*k)+1;
+
+ randTruePrime_(s_q,recSize);
+ copyInt_(s_i2,0);
+ s_i2[Math.floor((k-2)/bpe)] |= (1<<((k-2)%bpe)); //s_i2=2^(k-2)
+ divide_(s_i2,s_q,s_i,s_rm); //s_i=floor((2^(k-1))/(2q))
+
+ z=bitSize(s_i);
+
+ for (;;) {
+ for (;;) { //generate z-bit numbers until one falls in the range [0,s_i-1]
+ randBigInt_(s_R,z,0);
+ if (greater(s_i,s_R))
+ break;
+ } //now s_R is in the range [0,s_i-1]
+ addInt_(s_R,1); //now s_R is in the range [1,s_i]
+ add_(s_R,s_i); //now s_R is in the range [s_i+1,2*s_i]
+
+ copy_(s_n,s_q);
+ mult_(s_n,s_R);
+ multInt_(s_n,2);
+ addInt_(s_n,1); //s_n=2*s_R*s_q+1
+
+ copy_(s_r2,s_R);
+ multInt_(s_r2,2); //s_r2=2*s_R
+
+ //check s_n for divisibility by small primes up to B
+ for (divisible=0,j=0; (j<primes.length) && (primes[j]<B); j++)
+ if (modInt(s_n,primes[j])==0) {
+ divisible=1;
+ break;
+ }
+
+ if (!divisible) //if it passes small primes check, then try a single Miller-Rabin base 2
+ if (!millerRabin(s_n,2)) //this line represents 75% of the total runtime for randTruePrime_
+ divisible=1;
+
+ if (!divisible) { //if it passes that test, continue checking s_n
+ addInt_(s_n,-3);
+ for (j=s_n.length-1;(s_n[j]==0) && (j>0); j--); //strip leading zeros
+ for (zz=0,w=s_n[j]; w; (w>>=1),zz++);
+ zz+=bpe*j; //zz=number of bits in s_n, ignoring leading zeros
+ for (;;) { //generate z-bit numbers until one falls in the range [0,s_n-1]
+ randBigInt_(s_a,zz,0);
+ if (greater(s_n,s_a))
+ break;
+ } //now s_a is in the range [0,s_n-1]
+ addInt_(s_n,3); //now s_a is in the range [0,s_n-4]
+ addInt_(s_a,2); //now s_a is in the range [2,s_n-2]
+ copy_(s_b,s_a);
+ copy_(s_n1,s_n);
+ addInt_(s_n1,-1);
+ powMod_(s_b,s_n1,s_n); //s_b=s_a^(s_n-1) modulo s_n
+ addInt_(s_b,-1);
+ if (isZero(s_b)) {
+ copy_(s_b,s_a);
+ powMod_(s_b,s_r2,s_n);
+ addInt_(s_b,-1);
+ copy_(s_aa,s_n);
+ copy_(s_d,s_b);
+ GCD_(s_d,s_n); //if s_b and s_n are relatively prime, then s_n is a prime
+ if (equalsInt(s_d,1)) {
+ copy_(ans,s_aa);
+ return; //if we've made it this far, then s_n is absolutely guaranteed to be prime
+ }
+ }
+ }
+ }
+}
+
+//set b to an n-bit random BigInt. If s=1, then nth bit (most significant bit) is set to 1.
+//array b must be big enough to hold the result. Must have n>=1
+function randBigInt_(b,n,s) {
+ var i,a;
+ for (i=0;i<b.length;i++)
+ b[i]=0;
+ a=Math.floor((n-1)/bpe)+1; //# array elements to hold the BigInt
+ for (i=0;i<a;i++) {
+ b[i]=Math.floor(Math.random()*(1<<(bpe-1)));
+ }
+ b[a-1] &= (2<<((n-1)%bpe))-1;
+ if (s)
+ b[a-1] |= (1<<((n-1)%bpe));
+}
+
+//set x to the greatest common divisor of x and y.
+//x,y are bigInts with the same number of elements. y is destroyed.
+function GCD_(x,y) {
+ var i,xp,yp,A,B,C,D,q,sing;
+ if (T.length!=x.length)
+ T=dup(x);
+
+ sing=1;
+ while (sing) { //while y has nonzero elements other than y[0]
+ sing=0;
+ for (i=1;i<y.length;i++) //check if y has nonzero elements other than 0
+ if (y[i]) {
+ sing=1;
+ break;
+ }
+ if (!sing) break; //quit when y all zero elements except possibly y[0]
+
+ for (i=x.length;!x[i] && i>=0;i--); //find most significant element of x
+ xp=x[i];
+ yp=y[i];
+ A=1; B=0; C=0; D=1;
+ while ((yp+C) && (yp+D)) {
+ q =Math.floor((xp+A)/(yp+C));
+ qp=Math.floor((xp+B)/(yp+D));
+ if (q!=qp)
+ break;
+ t= A-q*C; A=C; C=t; // do (A,B,xp, C,D,yp) = (C,D,yp, A,B,xp) - q*(0,0,0, C,D,yp)
+ t= B-q*D; B=D; D=t;
+ t=xp-q*yp; xp=yp; yp=t;
+ }
+ if (B) {
+ copy_(T,x);
+ linComb_(x,y,A,B); //x=A*x+B*y
+ linComb_(y,T,D,C); //y=D*y+C*T
+ } else {
+ mod_(x,y);
+ copy_(T,x);
+ copy_(x,y);
+ copy_(y,T);
+ }
+ }
+ if (y[0]==0)
+ return;
+ t=modInt(x,y[0]);
+ copyInt_(x,y[0]);
+ y[0]=t;
+ while (y[0]) {
+ x[0]%=y[0];
+ t=x[0]; x[0]=y[0]; y[0]=t;
+ }
+}
+
+//do x=x**(-1) mod n, for bigInts x and n.
+//If no inverse exists, it sets x to zero and returns 0, else it returns 1.
+//The x array must be at least as large as the n array.
+function inverseMod_(x,n) {
+ var k=1+2*Math.max(x.length,n.length);
+
+ if(!(x[0]&1) && !(n[0]&1)) { //if both inputs are even, then inverse doesn't exist
+ copyInt_(x,0);
+ return 0;
+ }
+
+ if (eg_u.length!=k) {
+ eg_u=new Array(k);
+ eg_v=new Array(k);
+ eg_A=new Array(k);
+ eg_B=new Array(k);
+ eg_C=new Array(k);
+ eg_D=new Array(k);
+ }
+
+ copy_(eg_u,x);
+ copy_(eg_v,n);
+ copyInt_(eg_A,1);
+ copyInt_(eg_B,0);
+ copyInt_(eg_C,0);
+ copyInt_(eg_D,1);
+ for (;;) {
+ while(!(eg_u[0]&1)) { //while eg_u is even
+ halve_(eg_u);
+ if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if eg_A==eg_B==0 mod 2
+ halve_(eg_A);
+ halve_(eg_B);
+ } else {
+ add_(eg_A,n); halve_(eg_A);
+ sub_(eg_B,x); halve_(eg_B);
+ }
+ }
+
+ while (!(eg_v[0]&1)) { //while eg_v is even
+ halve_(eg_v);
+ if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if eg_C==eg_D==0 mod 2
+ halve_(eg_C);
+ halve_(eg_D);
+ } else {
+ add_(eg_C,n); halve_(eg_C);
+ sub_(eg_D,x); halve_(eg_D);
+ }
+ }
+
+ if (!greater(eg_v,eg_u)) { //eg_v <= eg_u
+ sub_(eg_u,eg_v);
+ sub_(eg_A,eg_C);
+ sub_(eg_B,eg_D);
+ } else { //eg_v > eg_u
+ sub_(eg_v,eg_u);
+ sub_(eg_C,eg_A);
+ sub_(eg_D,eg_B);
+ }
+
+ if (equalsInt(eg_u,0)) {
+ if (negative(eg_C)) //make sure answer is nonnegative
+ add_(eg_C,n);
+ copy_(x,eg_C);
+
+ if (!equalsInt(eg_v,1)) { //if GCD_(x,n)!=1, then there is no inverse
+ copyInt_(x,0);
+ return 0;
+ }
+ return 1;
+ }
+ }
+}
+
+//return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse
+function inverseModInt_(x,n) {
+ var a=1,b=0,t;
+ for (;;) {
+ if (x==1) return a;
+ if (x==0) return 0;
+ b-=a*Math.floor(n/x);
+ n%=x;
+
+ if (n==1) return b; //to avoid negatives, change this b to n-b, and each -= to +=
+ if (n==0) return 0;
+ a-=b*Math.floor(x/n);
+ x%=n;
+ }
+}
+
+//Given positive bigInts x and y, change the bigints v, a, and b to positive bigInts such that:
+// v = GCD_(x,y) = a*x-b*y
+//The bigInts v, a, b, must have exactly as many elements as the larger of x and y.
+function eGCD_(x,y,v,a,b) {
+ var g=0;
+ var k=Math.max(x.length,y.length);
+ if (eg_u.length!=k) {
+ eg_u=new Array(k);
+ eg_A=new Array(k);
+ eg_B=new Array(k);
+ eg_C=new Array(k);
+ eg_D=new Array(k);
+ }
+ while(!(x[0]&1) && !(y[0]&1)) { //while x and y both even
+ halve_(x);
+ halve_(y);
+ g++;
+ }
+ copy_(eg_u,x);
+ copy_(v,y);
+ copyInt_(eg_A,1);
+ copyInt_(eg_B,0);
+ copyInt_(eg_C,0);
+ copyInt_(eg_D,1);
+ for (;;) {
+ while(!(eg_u[0]&1)) { //while u is even
+ halve_(eg_u);
+ if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if A==B==0 mod 2
+ halve_(eg_A);
+ halve_(eg_B);
+ } else {
+ add_(eg_A,y); halve_(eg_A);
+ sub_(eg_B,x); halve_(eg_B);
+ }
+ }
+
+ while (!(v[0]&1)) { //while v is even
+ halve_(v);
+ if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if C==D==0 mod 2
+ halve_(eg_C);
+ halve_(eg_D);
+ } else {
+ add_(eg_C,y); halve_(eg_C);
+ sub_(eg_D,x); halve_(eg_D);
+ }
+ }
+
+ if (!greater(v,eg_u)) { //v<=u
+ sub_(eg_u,v);
+ sub_(eg_A,eg_C);
+ sub_(eg_B,eg_D);
+ } else { //v>u
+ sub_(v,eg_u);
+ sub_(eg_C,eg_A);
+ sub_(eg_D,eg_B);
+ }
+ if (equalsInt(eg_u,0)) {
+ if (negative(eg_C)) { //make sure a (C)is nonnegative
+ add_(eg_C,y);
+ sub_(eg_D,x);
+ }
+ multInt_(eg_D,-1); ///make sure b (D) is nonnegative
+ copy_(a,eg_C);
+ copy_(b,eg_D);
+ leftShift_(v,g);
+ return;
+ }
+ }
+}
+
+
+//is bigInt x negative?
+function negative(x) {
+ return ((x[x.length-1]>>(bpe-1))&1);
+}
+
+
+//is (x << (shift*bpe)) > y?
+//x and y are nonnegative bigInts
+//shift is a nonnegative integer
+function greaterShift(x,y,shift) {
+ var kx=x.length, ky=y.length;
+ k=((kx+shift)<ky) ? (kx+shift) : ky;
+ for (i=ky-1-shift; i<kx && i>=0; i++)
+ if (x[i]>0)
+ return 1; //if there are nonzeros in x to the left of the first column of y, then x is bigger
+ for (i=kx-1+shift; i<ky; i++)
+ if (y[i]>0)
+ return 0; //if there are nonzeros in y to the left of the first column of x, then x is not bigger
+ for (i=k-1; i>=shift; i--)
+ if (x[i-shift]>y[i]) return 1;
+ else if (x[i-shift]<y[i]) return 0;
+ return 0;
+}
+
+//is x > y? (x and y both nonnegative)
+function greater(x,y) {
+ var i;
+ var k=(x.length<y.length) ? x.length : y.length;
+
+ for (i=x.length;i<y.length;i++)
+ if (y[i])
+ return 0; //y has more digits
+
+ for (i=y.length;i<x.length;i++)
+ if (x[i])
+ return 1; //x has more digits
+
+ for (i=k-1;i>=0;i--)
+ if (x[i]>y[i])
+ return 1;
+ else if (x[i]<y[i])
+ return 0;
+ return 0;
+}
+
+//divide_ x by y giving quotient q and remainder r. (q=floor(x/y), r=x mod y). All 4 are bigints.
+//x must have at least one leading zero element.
+//y must be nonzero.
+//q and r must be arrays that are exactly the same length as x.
+//the x array must have at least as many elements as y.
+function divide_(x,y,q,r) {
+ var kx, ky;
+ var i,j,y1,y2,c,a,b;
+ copy_(r,x);
+ for (ky=y.length;y[ky-1]==0;ky--); //kx,ky is number of elements in x,y, not including leading zeros
+ for (kx=r.length;r[kx-1]==0 && kx>ky;kx--);
+
+ //normalize: ensure the most significant element of y has its highest bit set
+ b=y[ky-1];
+ for (a=0; b; a++)
+ b>>=1;
+ a=bpe-a; //a is how many bits to shift so that the high order bit of y is leftmost in its array element
+ leftShift_(y,a); //multiply both by 1<<a now, then divide_ both by that at the end
+ leftShift_(r,a);
+
+ copyInt_(q,0); // q=0
+ while (!greaterShift(y,r,kx-ky)) { // while (leftShift_(y,kx-ky) <= r) {
+ subShift_(r,y,kx-ky); // r=r-leftShift_(y,kx-ky)
+ q[kx-ky]++; // q[kx-ky]++;
+ } // }
+
+ for (i=kx-1; i>=ky; i--) {
+ if (r[i]==y[ky-1])
+ q[i-ky]=mask;
+ else
+ q[i-ky]=Math.floor((r[i]*radix+r[i-1])/y[ky-1]);
+
+ //The following for(;;) loop is equivalent to the commented while loop,
+ //except that the uncommented version avoids overflow.
+ //The commented loop comes from HAC, which assumes r[-1]==y[-1]==0
+ // while (q[i-ky]*(y[ky-1]*radix+y[ky-2]) > r[i]*radix*radix+r[i-1]*radix+r[i-2])
+ // q[i-ky]--;
+ for (;;) {
+ y2=(ky>1 ? y[ky-2] : 0)*q[i-ky];
+ c=y2>>bpe;
+ y2=y2 & mask;
+ y1=c+q[i-ky]*y[ky-1];
+ c=y1>>bpe;
+ y1=y1 & mask;
+
+ if (c==r[i] ? y1==r[i-1] ? y2>(i>1 ? r[i-2] : 0) : y1>r[i-1] : c>r[i])
+ q[i-ky]--;
+ else
+ break;
+ }
+
+ linCombShift_(r,y,-q[i-ky],i-ky); //r=r-q[i-ky]*leftShift_(y,i-ky)
+ if (negative(r)) {
+ addShift_(r,y,i-ky); //r=r+leftShift_(y,i-ky)
+ q[i-ky]--;
+ }
+ }
+
+ rightShift_(y,a); //undo the normalization step
+ rightShift_(r,a); //undo the normalization step
+}
+
+//do carries and borrows so each element of the bigInt x fits in bpe bits.
+function carry_(x) {
+ var i,k,c,b;
+ k=x.length;
+ c=0;
+ for (i=0;i<k;i++) {
+ c+=x[i];
+ b=0;
+ if (c<0) {
+ b=-(c>>bpe);
+ c+=b*radix;
+ }
+ x[i]=c & mask;
+ c=(c>>bpe)-b;
+ }
+}
+
+//return x mod n for bigInt x and integer n.
+function modInt(x,n) {
+ var i,c=0;
+ for (i=x.length-1; i>=0; i--)
+ c=(c*radix+x[i])%n;
+ return c;
+}
+
+//convert the integer t into a bigInt with at least the given number of bits.
+//the returned array stores the bigInt in bpe-bit chunks, little endian (buff[0] is least significant word)
+//Pad the array with leading zeros so that it has at least minSize elements.
+//There will always be at least one leading 0 element.
+function int2bigInt(t,bits,minSize) {
+ var i,k;
+ k=Math.ceil(bits/bpe)+1;
+ k=minSize>k ? minSize : k;
+ buff=new Array(k);
+ copyInt_(buff,t);
+ return buff;
+}
+
+//return the bigInt given a string representation in a given base.
+//Pad the array with leading zeros so that it has at least minSize elements.
+//If base=-1, then it reads in a space-separated list of array elements in decimal.
+//The array will always have at least one leading zero, unless base=-1.
+function str2bigInt(s,base,minSize) {
+ var d, i, j, x, y, kk;
+ var k=s.length;
+ if (base==-1) { //comma-separated list of array elements in decimal
+ x=new Array(0);
+ for (;;) {
+ y=new Array(x.length+1);
+ for (i=0;i<x.length;i++)
+ y[i+1]=x[i];
+ y[0]=parseInt(s,10);
+ x=y;
+ d=s.indexOf(',',0);
+ if (d<1)
+ break;
+ s=s.substring(d+1);
+ if (s.length==0)
+ break;
+ }
+ if (x.length<minSize) {
+ y=new Array(minSize);
+ copy_(y,x);
+ return y;
+ }
+ return x;
+ }
+
+ x=int2bigInt(0,base*k,0);
+ for (i=0;i<k;i++) {
+ d=digitsStr.indexOf(s.substring(i,i+1),0);
+ if (base<=36 && d>=36) //convert lowercase to uppercase if base<=36
+ d-=26;
+ if (d<base && d>=0) { //ignore illegal characters
+ multInt_(x,base);
+ addInt_(x,d);
+ }
+ }
+
+ for (k=x.length;k>0 && !x[k-1];k--); //strip off leading zeros
+ k=minSize>k+1 ? minSize : k+1;
+ y=new Array(k);
+ kk=k<x.length ? k : x.length;
+ for (i=0;i<kk;i++)
+ y[i]=x[i];
+ for (;i<k;i++)
+ y[i]=0;
+ return y;
+}
+
+//is bigint x equal to integer y?
+//y must have less than bpe bits
+function equalsInt(x,y) {
+ var i;
+ if (x[0]!=y)
+ return 0;
+ for (i=1;i<x.length;i++)
+ if (x[i])
+ return 0;
+ return 1;
+}
+
+//are bigints x and y equal?
+//this works even if x and y are different lengths and have arbitrarily many leading zeros
+function equals(x,y) {
+ var i;
+ var k=x.length<y.length ? x.length : y.length;
+ for (i=0;i<k;i++)
+ if (x[i]!=y[i])
+ return 0;
+ if (x.length>y.length) {
+ for (;i<x.length;i++)
+ if (x[i])
+ return 0;
+ } else {
+ for (;i<y.length;i++)
+ if (y[i])
+ return 0;
+ }
+ return 1;
+}
+
+//is the bigInt x equal to zero?
+function isZero(x) {
+ var i;
+ for (i=0;i<x.length;i++)
+ if (x[i])
+ return 0;
+ return 1;
+}
+
+//convert a bigInt into a string in a given base, from base 2 up to base 95.
+//Base -1 prints the contents of the array representing the number.
+function bigInt2str(x,base) {
+ var i,t,s="";
+
+ if (s6.length!=x.length)
+ s6=dup(x);
+ else
+ copy_(s6,x);
+
+ if (base==-1) { //return the list of array contents
+ for (i=x.length-1;i>0;i--)
+ s+=x[i]+',';
+ s+=x[0];
+ }
+ else { //return it in the given base
+ while (!isZero(s6)) {
+ t=divInt_(s6,base); //t=s6 % base; s6=floor(s6/base);
+ s=digitsStr.substring(t,t+1)+s;
+ }
+ }
+ if (s.length==0)
+ s="0";
+ return s;
+}
+
+//returns a duplicate of bigInt x
+function dup(x) {
+ var i;
+ buff=new Array(x.length);
+ copy_(buff,x);
+ return buff;
+}
+
+//do x=y on bigInts x and y. x must be an array at least as big as y (not counting the leading zeros in y).
+function copy_(x,y) {
+ var i;
+ var k=x.length<y.length ? x.length : y.length;
+ for (i=0;i<k;i++)
+ x[i]=y[i];
+ for (i=k;i<x.length;i++)
+ x[i]=0;
+}
+
+//do x=y on bigInt x and integer y.
+function copyInt_(x,n) {
+ var i,c;
+ for (c=n,i=0;i<x.length;i++) {
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+}
+
+//do x=x+n where x is a bigInt and n is an integer.
+//x must be large enough to hold the result.
+function addInt_(x,n) {
+ var i,k,c,b;
+ x[0]+=n;
+ k=x.length;
+ c=0;
+ for (i=0;i<k;i++) {
+ c+=x[i];
+ b=0;
+ if (c<0) {
+ b=-(c>>bpe);
+ c+=b*radix;
+ }
+ x[i]=c & mask;
+ c=(c>>bpe)-b;
+ if (!c) return; //stop carrying as soon as the carry_ is zero
+ }
+}
+
+//right shift bigInt x by n bits. 0 <= n < bpe.
+function rightShift_(x,n) {
+ var i;
+ var k=Math.floor(n/bpe);
+ if (k) {
+ for (i=0;i<x.length-k;i++) //right shift x by k elements
+ x[i]=x[i+k];
+ for (;i<x.length;i++)
+ x[i]=0;
+ n%=bpe;
+ }
+ for (i=0;i<x.length-1;i++) {
+ x[i]=mask & ((x[i+1]<<(bpe-n)) | (x[i]>>n));
+ }
+ x[i]>>=n;
+}
+
+//do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement
+function halve_(x) {
+ var i;
+ for (i=0;i<x.length-1;i++) {
+ x[i]=mask & ((x[i+1]<<(bpe-1)) | (x[i]>>1));
+ }
+ x[i]=(x[i]>>1) | (x[i] & (radix>>1)); //most significant bit stays the same
+}
+
+//left shift bigInt x by n bits.
+function leftShift_(x,n) {
+ var i;
+ var k=Math.floor(n/bpe);
+ if (k) {
+ for (i=x.length; i>=k; i--) //left shift x by k elements
+ x[i]=x[i-k];
+ for (;i>=0;i--)
+ x[i]=0;
+ n%=bpe;
+ }
+ if (!n)
+ return;
+ for (i=x.length-1;i>0;i--) {
+ x[i]=mask & ((x[i]<<n) | (x[i-1]>>(bpe-n)));
+ }
+ x[i]=mask & (x[i]<<n);
+}
+
+//do x=x*n where x is a bigInt and n is an integer.
+//x must be large enough to hold the result.
+function multInt_(x,n) {
+ var i,k,c,b;
+ if (!n)
+ return;
+ k=x.length;
+ c=0;
+ for (i=0;i<k;i++) {
+ c+=x[i]*n;
+ b=0;
+ if (c<0) {
+ b=-(c>>bpe);
+ c+=b*radix;
+ }
+ x[i]=c & mask;
+ c=(c>>bpe)-b;
+ }
+}
+
+//do x=floor(x/n) for bigInt x and integer n, and return the remainder
+function divInt_(x,n) {
+ var i,r=0,s;
+ for (i=x.length-1;i>=0;i--) {
+ s=r*radix+x[i];
+ x[i]=Math.floor(s/n);
+ r=s%n;
+ }
+ return r;
+}
+
+//do the linear combination x=a*x+b*y for bigInts x and y, and integers a and b.
+//x must be large enough to hold the answer.
+function linComb_(x,y,a,b) {
+ var i,c,k,kk;
+ k=x.length<y.length ? x.length : y.length;
+ kk=x.length;
+ for (c=0,i=0;i<k;i++) {
+ c+=a*x[i]+b*y[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+ for (i=k;i<kk;i++) {
+ c+=a*x[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+}
+
+//do the linear combination x=a*x+b*(y<<(ys*bpe)) for bigInts x and y, and integers a, b and ys.
+//x must be large enough to hold the answer.
+function linCombShift_(x,y,b,ys) {
+ var i,c,k,kk;
+ k=x.length<ys+y.length ? x.length : ys+y.length;
+ kk=x.length;
+ for (c=0,i=ys;i<k;i++) {
+ c+=x[i]+b*y[i-ys];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+ for (i=k;c && i<kk;i++) {
+ c+=x[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+}
+
+//do x=x+(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
+//x must be large enough to hold the answer.
+function addShift_(x,y,ys) {
+ var i,c,k,kk;
+ k=x.length<ys+y.length ? x.length : ys+y.length;
+ kk=x.length;
+ for (c=0,i=ys;i<k;i++) {
+ c+=x[i]+y[i-ys];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+ for (i=k;c && i<kk;i++) {
+ c+=x[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+}
+
+//do x=x-(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
+//x must be large enough to hold the answer.
+function subShift_(x,y,ys) {
+ var i,c,k,kk;
+ k=x.length<ys+y.length ? x.length : ys+y.length;
+ kk=x.length;
+ for (c=0,i=ys;i<k;i++) {
+ c+=x[i]-y[i-ys];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+ for (i=k;c && i<kk;i++) {
+ c+=x[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+}
+
+//do x=x-y for bigInts x and y.
+//x must be large enough to hold the answer.
+//negative answers will be 2s complement
+function sub_(x,y) {
+ var i,c,k,kk;
+ k=x.length<y.length ? x.length : y.length;
+ for (c=0,i=0;i<k;i++) {
+ c+=x[i]-y[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+ for (i=k;c && i<x.length;i++) {
+ c+=x[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+}
+
+//do x=x+y for bigInts x and y.
+//x must be large enough to hold the answer.
+function add_(x,y) {
+ var i,c,k,kk;
+ k=x.length<y.length ? x.length : y.length;
+ for (c=0,i=0;i<k;i++) {
+ c+=x[i]+y[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+ for (i=k;c && i<x.length;i++) {
+ c+=x[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+}
+
+//do x=x*y for bigInts x and y. This is faster when y<x.
+function mult_(x,y) {
+ var i;
+ if (ss.length!=2*x.length)
+ ss=new Array(2*x.length);
+ copyInt_(ss,0);
+ for (i=0;i<y.length;i++)
+ if (y[i])
+ linCombShift_(ss,x,y[i],i); //ss=1*ss+y[i]*(x<<(i*bpe))
+ copy_(x,ss);
+}
+
+//do x=x mod n for bigInts x and n.
+function mod_(x,n) {
+ if (s4.length!=x.length)
+ s4=dup(x);
+ else
+ copy_(s4,x);
+ if (s5.length!=x.length)
+ s5=dup(x);
+ divide_(s4,n,s5,x); //x = remainder of s4 / n
+}
+
+//do x=x*y mod n for bigInts x,y,n.
+//for greater speed, let y<x.
+function multMod_(x,y,n) {
+ var i;
+ if (s0.length!=2*x.length)
+ s0=new Array(2*x.length);
+ copyInt_(s0,0);
+ for (i=0;i<y.length;i++)
+ if (y[i])
+ linCombShift_(s0,x,y[i],i); //s0=1*s0+y[i]*(x<<(i*bpe))
+ mod_(s0,n);
+ copy_(x,s0);
+}
+
+//do x=x*x mod n for bigInts x,n.
+function squareMod_(x,n) {
+ var i,j,d,c,kx,kn,k;
+ for (kx=x.length; kx>0 && !x[kx-1]; kx--); //ignore leading zeros in x
+ k=kx>n.length ? 2*kx : 2*n.length; //k=# elements in the product, which is twice the elements in the larger of x and n
+ if (s0.length!=k)
+ s0=new Array(k);
+ copyInt_(s0,0);
+ for (i=0;i<kx;i++) {
+ c=s0[2*i]+x[i]*x[i];
+ s0[2*i]=c & mask;
+ c>>=bpe;
+ for (j=i+1;j<kx;j++) {
+ c=s0[i+j]+2*x[i]*x[j]+c;
+ s0[i+j]=(c & mask);
+ c>>=bpe;
+ }
+ s0[i+kx]=c;
+ }
+ mod_(s0,n);
+ copy_(x,s0);
+}
+
+//return x with exactly k leading zero elements
+function trim(x,k) {
+ var i,y;
+ for (i=x.length; i>0 && !x[i-1]; i--);
+ y=new Array(i+k);
+ copy_(y,x);
+ return y;
+}
+
+//do x=x**y mod n, where x,y,n are bigInts and ** is exponentiation. 0**0=1.
+//this is faster when n is odd. x usually needs to have as many elements as n.
+function powMod_(x,y,n) {
+ var k1,k2,kn,np;
+ if(s7.length!=n.length)
+ s7=dup(n);
+
+ //for even modulus, use a simple square-and-multiply algorithm,
+ //rather than using the more complex Montgomery algorithm.
+ if ((n[0]&1)==0) {
+ copy_(s7,x);
+ copyInt_(x,1);
+ while(!equalsInt(y,0)) {
+ if (y[0]&1)
+ multMod_(x,s7,n);
+ divInt_(y,2);
+ squareMod_(s7,n);
+ }
+ return;
+ }
+
+ //calculate np from n for the Montgomery multiplications
+ copyInt_(s7,0);
+ for (kn=n.length;kn>0 && !n[kn-1];kn--);
+ np=radix-inverseModInt_(modInt(n,radix),radix);
+ s7[kn]=1;
+ multMod_(x ,s7,n); // x = x * 2**(kn*bp) mod n
+
+ if (s3.length!=x.length)
+ s3=dup(x);
+ else
+ copy_(s3,x);
+
+ for (k1=y.length-1;k1>0 & !y[k1]; k1--); //k1=first nonzero element of y
+ if (y[k1]==0) { //anything to the 0th power is 1
+ copyInt_(x,1);
+ return;
+ }
+ for (k2=1<<(bpe-1);k2 && !(y[k1] & k2); k2>>=1); //k2=position of first 1 bit in y[k1]
+ for (;;) {
+ if (!(k2>>=1)) { //look at next bit of y
+ k1--;
+ if (k1<0) {
+ mont_(x,one,n,np);
+ return;
+ }
+ k2=1<<(bpe-1);
+ }
+ mont_(x,x,n,np);
+
+ if (k2 & y[k1]) //if next bit is a 1
+ mont_(x,s3,n,np);
+ }
+}
+
+//do x=x*y*Ri mod n for bigInts x,y,n,
+// where Ri = 2**(-kn*bpe) mod n, and kn is the
+// number of elements in the n array, not
+// counting leading zeros.
+//x must be large enough to hold the answer.
+//It's OK if x and y are the same variable.
+//must have:
+// x,y < n
+// n is odd
+// np = -(n^(-1)) mod radix
+function mont_(x,y,n,np) {
+ var i,j,c,ui,t;
+ var kn=n.length;
+ var ky=y.length;
+
+ if (sa.length!=kn)
+ sa=new Array(kn);
+
+ for (;kn>0 && n[kn-1]==0;kn--); //ignore leading zeros of n
+ //this function sometimes gives wrong answers when the next line is uncommented
+ //for (;ky>0 && y[ky-1]==0;ky--); //ignore leading zeros of y
+
+ copyInt_(sa,0);
+
+ //the following loop consumes 95% of the runtime for randTruePrime_() and powMod_() for large keys
+ for (i=0; i<kn; i++) {
+ t=sa[0]+x[i]*y[0];
+ ui=((t & mask) * np) & mask; //the inner "& mask" is needed on Macintosh MSIE, but not windows MSIE
+ c=(t+ui*n[0]) >> bpe;
+ t=x[i];
+
+ //do sa=(sa+x[i]*y+ui*n)/b where b=2**bpe
+ for (j=1;j<ky;j++) {
+ c+=sa[j]+t*y[j]+ui*n[j];
+ sa[j-1]=c & mask;
+ c>>=bpe;
+ }
+ for (;j<kn;j++) {
+ c+=sa[j]+ui*n[j];
+ sa[j-1]=c & mask;
+ c>>=bpe;
+ }
+ sa[j-1]=c & mask;
+ }
+
+ if (!greater(n,sa))
+ sub_(sa,n);
+ copy_(x,sa);
+}
+
+
+
+
+//#############################################################################
+//#############################################################################
+//#############################################################################
+//#############################################################################
+//#############################################################################
+//#############################################################################
+//#############################################################################
+
+
+
+
+
+//#############################################################################
+
+Clipperz.Crypto.BigInt = function (aValue, aBase) {
+ var base;
+ var value;
+
+ if (typeof(aValue) == 'object') {
+ this._internalValue = aValue;
+ } else {
+ if (typeof(aValue) == 'undefined') {
+ value = "0";
+ } else {
+ value = aValue + "";
+ }
+
+ if (typeof(aBase) == 'undefined') {
+ base = 10;
+ } else {
+ base = aBase;
+ }
+
+ this._internalValue = str2bigInt(value, base, 1, 1);
+ }
+
+ return this;
+}
+
+//=============================================================================
+
+MochiKit.Base.update(Clipperz.Crypto.BigInt.prototype, {
+
+ 'clone': function() {
+ return new Clipperz.Crypto.BigInt(this.internalValue());
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'internalValue': function () {
+ return this._internalValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isBigInt': true,
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function(aBase) {
+ return this.asString(aBase);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'asString': function (aBase, minimumLength) {
+ var result;
+ var base;
+
+ if (typeof(aBase) == 'undefined') {
+ base = 10;
+ } else {
+ base = aBase;
+ }
+
+ result = bigInt2str(this.internalValue(), base).toLowerCase();
+
+ if ((typeof(minimumLength) != 'undefined') && (result.length < minimumLength)) {
+ var i, c;
+//MochiKit.Logging.logDebug(">>> FIXING BigInt.asString length issue")
+ c = (minimumLength - result.length);
+ for (i=0; i<c; i++) {
+ result = '0' + result;
+ }
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'asByteArray': function() {
+ return new Clipperz.ByteArray("0x" + this.asString(16), 16);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'equals': function (aValue) {
+ var result;
+
+ if (aValue.isBigInt) {
+ result = equals(this.internalValue(), aValue.internalValue());
+ } else if (typeof(aValue) == "number") {
+ result = equalsInt(this.internalValue(), aValue);
+ } else {
+ throw Clipperz.Crypt.BigInt.exception.UnknownType;
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'compare': function(aValue) {
+/*
+ var result;
+ var thisAsString;
+ var aValueAsString;
+
+ thisAsString = this.asString(10);
+ aValueAsString = aValue.asString(10);
+
+ result = MochiKit.Base.compare(thisAsString.length, aValueAsString.length);
+ if (result == 0) {
+ result = MochiKit.Base.compare(thisAsString, aValueAsString);
+ }
+
+ return result;
+*/
+ var result;
+
+ if (equals(this.internalValue(), aValue.internalValue())) {
+ result = 0;
+ } else if (greater(this.internalValue(), aValue.internalValue())) {
+ result = 1;
+ } else {
+ result = -1;
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'add': function (aValue) {
+ var result;
+
+ if (aValue.isBigInt) {
+ result = add(this.internalValue(), aValue.internalValue());
+ } else {
+ result = addInt(this.internalValue(), aValue);
+ }
+
+ return new Clipperz.Crypto.BigInt(result);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'subtract': function (aValue) {
+ var result;
+ var value;
+
+ if (aValue.isBigInt) {
+ value = aValue;
+ } else {
+ value = new Clipperz.Crypto.BigInt(aValue);
+ }
+
+ result = sub(this.internalValue(), value.internalValue());
+
+ return new Clipperz.Crypto.BigInt(result);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'multiply': function (aValue, aModule) {
+ var result;
+ var value;
+
+ if (aValue.isBigInt) {
+ value = aValue;
+ } else {
+ value = new Clipperz.Crypto.BigInt(aValue);
+ }
+
+ if (typeof(aModule) == 'undefined') {
+ result = mult(this.internalValue(), value.internalValue());
+ } else {
+ if (greater(this.internalValue(), value.internalValue())) {
+ result = multMod(this.internalValue(), value.internalValue(), aModule);
+ } else {
+ result = multMod(value.internalValue(), this.internalValue(), aModule);
+ }
+ }
+
+ return new Clipperz.Crypto.BigInt(result);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'module': function (aModule) {
+ var result;
+ var module;
+
+ if (aModule.isBigInt) {
+ module = aModule;
+ } else {
+ module = new Clipperz.Crypto.BigInt(aModule);
+ }
+
+ result = mod(this.internalValue(), module.internalValue());
+
+ return new Clipperz.Crypto.BigInt(result);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'powerModule': function(aValue, aModule) {
+ var result;
+ var value;
+ var module;
+
+ if (aValue.isBigInt) {
+ value = aValue;
+ } else {
+ value = new Clipperz.Crypto.BigInt(aValue);
+ }
+
+ if (aModule.isBigInt) {
+ module = aModule;
+ } else {
+ module = new Clipperz.Crypto.BigInt(aModule);
+ }
+
+ if (aValue == -1) {
+ result = inverseMod(this.internalValue(), module.internalValue());
+ } else {
+ result = powMod(this.internalValue(), value.internalValue(), module.internalValue());
+ }
+
+ return new Clipperz.Crypto.BigInt(result);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'xor': function(aValue) {
+ var result;
+ var thisByteArray;
+ var aValueByteArray;
+ var xorArray;
+
+ thisByteArray = new Clipperz.ByteArray("0x" + this.asString(16), 16);
+ aValueByteArray = new Clipperz.ByteArray("0x" + aValue.asString(16), 16);
+ xorArray = thisByteArray.xorMergeWithBlock(aValueByteArray, 'right');
+ result = new Clipperz.Crypto.BigInt(xorArray.toHexString(), 16);
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'shiftLeft': function(aNumberOfBitsToShift) {
+ var result;
+ var internalResult;
+ var wholeByteToShift;
+ var bitsLeftToShift;
+
+ wholeByteToShift = Math.floor(aNumberOfBitsToShift / 8);
+ bitsLeftToShift = aNumberOfBitsToShift % 8;
+
+ if (wholeByteToShift == 0) {
+ internalResult = this.internalValue();
+ } else {
+ var hexValue;
+ var i,c;
+
+ hexValue = this.asString(16);
+ c = wholeByteToShift;
+ for (i=0; i<c; i++) {
+ hexValue += "00";
+ }
+ internalResult = str2bigInt(hexValue, 16, 1, 1);
+ }
+
+ if (bitsLeftToShift > 0) {
+ leftShift_(internalResult, bitsLeftToShift);
+ }
+ result = new Clipperz.Crypto.BigInt(internalResult);
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'bitSize': function() {
+ return bitSize(this.internalValue());
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isBitSet': function(aBitPosition) {
+ var result;
+
+ if (this.asByteArray().bitAtIndex(aBitPosition) == 0) {
+ result = false;
+ } else {
+ result = true;
+ };
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
+//#############################################################################
+
+Clipperz.Crypto.BigInt.randomPrime = function(aBitSize) {
+ return new Clipperz.Crypto.BigInt(randTruePrime(aBitSize));
+}
+
+//#############################################################################
+//#############################################################################
+
+Clipperz.Crypto.BigInt.ZERO = new Clipperz.Crypto.BigInt(0);
+
+//#############################################################################
+
+Clipperz.Crypto.BigInt.equals = function(a, b) {
+ return a.equals(b);
+}
+
+Clipperz.Crypto.BigInt.add = function(a, b) {
+ return a.add(b);
+}
+
+Clipperz.Crypto.BigInt.subtract = function(a, b) {
+ return a.subtract(b);
+}
+
+Clipperz.Crypto.BigInt.multiply = function(a, b, module) {
+ return a.multiply(b, module);
+}
+
+Clipperz.Crypto.BigInt.module = function(a, module) {
+ return a.module(module);
+}
+
+Clipperz.Crypto.BigInt.powerModule = function(a, b, module) {
+ return a.powerModule(b, module);
+}
+
+Clipperz.Crypto.BigInt.exception = {
+ UnknownType: new MochiKit.Base.NamedError("Clipperz.Crypto.BigInt.exception.UnknownType")
+}
diff --git a/frontend/gamma/js/Clipperz/Crypto/BigInt_scoped.js b/frontend/gamma/js/Clipperz/Crypto/BigInt_scoped.js
new file mode 100644
index 0000000..e91e823
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/BigInt_scoped.js
@@ -0,0 +1,1649 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
+
+if (typeof(Leemon) == 'undefined') { Leemon = {}; }
+if (typeof(Baird.Crypto) == 'undefined') { Baird.Crypto = {}; }
+if (typeof(Baird.Crypto.BigInt) == 'undefined') { Baird.Crypto.BigInt = {}; }
+
+
+//#############################################################################
+// Downloaded on March 05, 2007 from http://www.leemon.com/crypto/BigInt.js
+//#############################################################################
+
+////////////////////////////////////////////////////////////////////////////////////////
+// Big Integer Library v. 5.0
+// Created 2000, last modified 2006
+// Leemon Baird
+// www.leemon.com
+//
+// This file is public domain. You can use it for any purpose without restriction.
+// I do not guarantee that it is correct, so use it at your own risk. If you use
+// it for something interesting, I'd appreciate hearing about it. If you find
+// any bugs or make any improvements, I'd appreciate hearing about those too.
+// It would also be nice if my name and address were left in the comments.
+// But none of that is required.
+//
+// This code defines a bigInt library for arbitrary-precision integers.
+// A bigInt is an array of integers storing the value in chunks of bpe bits,
+// little endian (buff[0] is the least significant word).
+// Negative bigInts are stored two's complement.
+// Some functions assume their parameters have at least one leading zero element.
+// Functions with an underscore at the end of the name have unpredictable behavior in case of overflow,
+// so the caller must make sure overflow won't happen.
+// For each function where a parameter is modified, that same
+// variable must not be used as another argument too.
+// So, you cannot square x by doing multMod_(x,x,n).
+// You must use squareMod_(x,n) instead, or do y=dup(x); multMod_(x,y,n).
+//
+// These functions are designed to avoid frequent dynamic memory allocation in the inner loop.
+// For most functions, if it needs a BigInt as a local variable it will actually use
+// a global, and will only allocate to it when it's not the right size. This ensures
+// that when a function is called repeatedly with same-sized parameters, it only allocates
+// memory on the first call.
+//
+// Note that for cryptographic purposes, the calls to Math.random() must
+// be replaced with calls to a better pseudorandom number generator.
+//
+// In the following, "bigInt" means a bigInt with at least one leading zero element,
+// and "integer" means a nonnegative integer less than radix. In some cases, integer
+// can be negative. Negative bigInts are 2s complement.
+//
+// The following functions do not modify their inputs, but dynamically allocate memory every time they are called:
+//
+// function bigInt2str(x,base) //convert a bigInt into a string in a given base, from base 2 up to base 95
+// function dup(x) //returns a copy of bigInt x
+// function findPrimes(n) //return array of all primes less than integer n
+// function int2bigInt(t,n,m) //convert integer t to a bigInt with at least n bits and m array elements
+// function str2bigInt(s,b,n,m) //convert string s in base b to a bigInt with at least n bits and m array elements
+// function trim(x,k) //return a copy of x with exactly k leading zero elements
+//
+// The following functions do not modify their inputs, so there is never a problem with the result being too big:
+//
+// function bitSize(x) //returns how many bits long the bigInt x is, not counting leading zeros
+// function equals(x,y) //is the bigInt x equal to the bigint y?
+// function equalsInt(x,y) //is bigint x equal to integer y?
+// function greater(x,y) //is x>y? (x and y are nonnegative bigInts)
+// function greaterShift(x,y,shift)//is (x <<(shift*bpe)) > y?
+// function isZero(x) //is the bigInt x equal to zero?
+// function millerRabin(x,b) //does one round of Miller-Rabin base integer b say that bigInt x is possibly prime (as opposed to definitely composite)?
+// function modInt(x,n) //return x mod n for bigInt x and integer n.
+// function negative(x) //is bigInt x negative?
+//
+// The following functions do not modify their inputs, but allocate memory and call functions with underscores
+//
+// function add(x,y) //return (x+y) for bigInts x and y.
+// function addInt(x,n) //return (x+n) where x is a bigInt and n is an integer.
+// function expand(x,n) //return a copy of x with at least n elements, adding leading zeros if needed
+// function inverseMod(x,n) //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null
+// function mod(x,n) //return a new bigInt equal to (x mod n) for bigInts x and n.
+// function mult(x,y) //return x*y for bigInts x and y. This is faster when y<x.
+// function multMod(x,y,n) //return (x*y mod n) for bigInts x,y,n. For greater speed, let y<x.
+// function powMod(x,y,n) //return (x**y mod n) where x,y,n are bigInts and ** is exponentiation. 0**0=1. Faster for odd n.
+// function randTruePrime(k) //return a new, random, k-bit, true prime using Maurer's algorithm.
+// function sub(x,y) //return (x-y) for bigInts x and y. Negative answers will be 2s complement
+//
+// The following functions write a bigInt result to one of the parameters, but
+// the result is never bigger than the original, so there can't be overflow problems:
+//
+// function divInt_(x,n) //do x=floor(x/n) for bigInt x and integer n, and return the remainder
+// function GCD_(x,y) //set x to the greatest common divisor of bigInts x and y, (y is destroyed).
+// function halve_(x) //do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement
+// function mod_(x,n) //do x=x mod n for bigInts x and n.
+// function rightShift_(x,n) //right shift bigInt x by n bits. 0 <= n < bpe.
+//
+// The following functions write a bigInt result to one of the parameters. The caller is responsible for
+// ensuring it is large enough to hold the result.
+//
+// function addInt_(x,n) //do x=x+n where x is a bigInt and n is an integer
+// function add_(x,y) //do x=x+y for bigInts x and y
+// function addShift_(x,y,ys) //do x=x+(y<<(ys*bpe))
+// function copy_(x,y) //do x=y on bigInts x and y
+// function copyInt_(x,n) //do x=n on bigInt x and integer n
+// function carry_(x) //do carries and borrows so each element of the bigInt x fits in bpe bits.
+// function divide_(x,y,q,r) //divide_ x by y giving quotient q and remainder r
+// function eGCD_(x,y,d,a,b) //sets a,b,d to positive big integers such that d = GCD_(x,y) = a*x-b*y
+// function inverseMod_(x,n) //do x=x**(-1) mod n, for bigInts x and n. Returns 1 (0) if inverse does (doesn't) exist
+// function inverseModInt_(x,n) //return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse
+// function leftShift_(x,n) //left shift bigInt x by n bits. n<bpe.
+// function linComb_(x,y,a,b) //do x=a*x+b*y for bigInts x and y and integers a and b
+// function linCombShift_(x,y,b,ys) //do x=x+b*(y<<(ys*bpe)) for bigInts x and y, and integers b and ys
+// function mont_(x,y,n,np) //Montgomery multiplication (see comments where the function is defined)
+// function mult_(x,y) //do x=x*y for bigInts x and y.
+// function multInt_(x,n) //do x=x*n where x is a bigInt and n is an integer.
+// function multMod_(x,y,n) //do x=x*y mod n for bigInts x,y,n.
+// function powMod_(x,y,n) //do x=x**y mod n, where x,y,n are bigInts (n is odd) and ** is exponentiation. 0**0=1.
+// function randBigInt_(b,n,s) //do b = an n-bit random BigInt. if s=1, then nth bit (most significant bit) is set to 1. n>=1.
+// function randTruePrime_(ans,k) //do ans = a random k-bit true random prime (not just probable prime) with 1 in the msb.
+// function squareMod_(x,n) //do x=x*x mod n for bigInts x,n
+// function sub_(x,y) //do x=x-y for bigInts x and y. Negative answers will be 2s complement.
+// function subShift_(x,y,ys) //do x=x-(y<<(ys*bpe)). Negative answers will be 2s complement.
+//
+// The following functions are based on algorithms from the _Handbook of Applied Cryptography_
+// powMod_() = algorithm 14.94, Montgomery exponentiation
+// eGCD_,inverseMod_() = algorithm 14.61, Binary extended GCD_
+// GCD_() = algorothm 14.57, Lehmer's algorithm
+// mont_() = algorithm 14.36, Montgomery multiplication
+// divide_() = algorithm 14.20 Multiple-precision division
+// squareMod_() = algorithm 14.16 Multiple-precision squaring
+// randTruePrime_() = algorithm 4.62, Maurer's algorithm
+// millerRabin() = algorithm 4.24, Miller-Rabin algorithm
+//
+// Profiling shows:
+// randTruePrime_() spends:
+// 10% of its time in calls to powMod_()
+// 85% of its time in calls to millerRabin()
+// millerRabin() spends:
+// 99% of its time in calls to powMod_() (always with a base of 2)
+// powMod_() spends:
+// 94% of its time in calls to mont_() (almost always with x==y)
+//
+// This suggests there are several ways to speed up this library slightly:
+// - convert powMod_ to use a Montgomery form of k-ary window (or maybe a Montgomery form of sliding window)
+// -- this should especially focus on being fast when raising 2 to a power mod n
+// - convert randTruePrime_() to use a minimum r of 1/3 instead of 1/2 with the appropriate change to the test
+// - tune the parameters in randTruePrime_(), including c, m, and recLimit
+// - speed up the single loop in mont_() that takes 95% of the runtime, perhaps by reducing checking
+// within the loop when all the parameters are the same length.
+//
+// There are several ideas that look like they wouldn't help much at all:
+// - replacing trial division in randTruePrime_() with a sieve (that speeds up something taking almost no time anyway)
+// - increase bpe from 15 to 30 (that would help if we had a 32*32->64 multiplier, but not with JavaScript's 32*32->32)
+// - speeding up mont_(x,y,n,np) when x==y by doing a non-modular, non-Montgomery square
+// followed by a Montgomery reduction. The intermediate answer will be twice as long as x, so that
+// method would be slower. This is unfortunate because the code currently spends almost all of its time
+// doing mont_(x,x,...), both for randTruePrime_() and powMod_(). A faster method for Montgomery squaring
+// would have a large impact on the speed of randTruePrime_() and powMod_(). HAC has a couple of poorly-worded
+// sentences that seem to imply it's faster to do a non-modular square followed by a single
+// Montgomery reduction, but that's obviously wrong.
+////////////////////////////////////////////////////////////////////////////////////////
+
+//
+// The whole library has been moved into the Baird.Crypto.BigInt scope by Giulio Cesare Solaroli <giulio.cesare@clipperz.com>
+//
+Baird.Crypto.BigInt.VERSION = "5.0";
+Baird.Crypto.BigInt.NAME = "Baird.Crypto.BigInt";
+
+MochiKit.Base.update(Baird.Crypto.BigInt, {
+ //globals
+ 'bpe': 0, //bits stored per array element
+ 'mask': 0, //AND this with an array element to chop it down to bpe bits
+ 'radix': Baird.Crypto.BigInt.mask + 1, //equals 2^bpe. A single 1 bit to the left of the last bit of mask.
+
+ //the digits for converting to different bases
+ 'digitsStr': '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_=!@#$%^&*()[]{}|;:,.<>/?`~ \\\'\"+-',
+
+//initialize the global variables
+for (bpe=0; (1<<(bpe+1)) > (1<<bpe); bpe++); //bpe=number of bits in the mantissa on this platform
+bpe>>=1; //bpe=number of bits in one element of the array representing the bigInt
+mask=(1<<bpe)-1; //AND the mask with an integer to get its bpe least significant bits
+radix=mask+1; //2^bpe. a single 1 bit to the left of the first bit of mask
+one=int2bigInt(1,1,1); //constant used in powMod_()
+
+//the following global variables are scratchpad memory to
+//reduce dynamic memory allocation in the inner loop
+t=new Array(0);
+ss=t; //used in mult_()
+s0=t; //used in multMod_(), squareMod_()
+s1=t; //used in powMod_(), multMod_(), squareMod_()
+s2=t; //used in powMod_(), multMod_()
+s3=t; //used in powMod_()
+s4=t; s5=t; //used in mod_()
+s6=t; //used in bigInt2str()
+s7=t; //used in powMod_()
+T=t; //used in GCD_()
+sa=t; //used in mont_()
+mr_x1=t; mr_r=t; mr_a=t; //used in millerRabin()
+eg_v=t; eg_u=t; eg_A=t; eg_B=t; eg_C=t; eg_D=t; //used in eGCD_(), inverseMod_()
+md_q1=t; md_q2=t; md_q3=t; md_r=t; md_r1=t; md_r2=t; md_tt=t; //used in mod_()
+
+primes=t; pows=t; s_i=t; s_i2=t; s_R=t; s_rm=t; s_q=t; s_n1=t;
+ s_a=t; s_r2=t; s_n=t; s_b=t; s_d=t; s_x1=t; s_x2=t, s_aa=t; //used in randTruePrime_()
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+ //return array of all primes less than integer n
+ 'findPrimes': function(n) {
+ var i,s,p,ans;
+ s=new Array(n);
+ for (i=0;i<n;i++)
+ s[i]=0;
+ s[0]=2;
+ p=0; //first p elements of s are primes, the rest are a sieve
+ for(;s[p]<n;) { //s[p] is the pth prime
+ for(i=s[p]*s[p]; i<n; i+=s[p]) //mark multiples of s[p]
+ s[i]=1;
+ p++;
+ s[p]=s[p-1]+1;
+ for(; s[p]<n && s[s[p]]; s[p]++); //find next prime (where s[p]==0)
+ }
+ ans=new Array(p);
+ for(i=0;i<p;i++)
+ ans[i]=s[i];
+ return ans;
+ },
+
+ //does a single round of Miller-Rabin base b consider x to be a possible prime?
+ //x is a bigInt, and b is an integer
+ 'millerRabin': function(x,b) {
+ var i,j,k,s;
+
+ if (mr_x1.length!=x.length) {
+ mr_x1=dup(x);
+ mr_r=dup(x);
+ mr_a=dup(x);
+ }
+
+ copyInt_(mr_a,b);
+ copy_(mr_r,x);
+ copy_(mr_x1,x);
+
+ addInt_(mr_r,-1);
+ addInt_(mr_x1,-1);
+
+ //s=the highest power of two that divides mr_r
+ k=0;
+ for (i=0;i<mr_r.length;i++)
+ for (j=1;j<mask;j<<=1)
+ if (x[i] & j) {
+ s=(k<mr_r.length+bpe ? k : 0);
+ i=mr_r.length;
+ j=mask;
+ } else
+ k++;
+
+ if (s)
+ rightShift_(mr_r,s);
+
+ powMod_(mr_a,mr_r,x);
+
+ if (!equalsInt(mr_a,1) && !equals(mr_a,mr_x1)) {
+ j=1;
+ while (j<=s-1 && !equals(mr_a,mr_x1)) {
+ squareMod_(mr_a,x);
+ if (equalsInt(mr_a,1)) {
+ return 0;
+ }
+ j++;
+ }
+ if (!equals(mr_a,mr_x1)) {
+ return 0;
+ }
+ }
+
+ return 1;
+ },
+
+ //returns how many bits long the bigInt is, not counting leading zeros.
+ 'bitSize': function(x) {
+ var j,z,w;
+ for (j=x.length-1; (x[j]==0) && (j>0); j--);
+ for (z=0,w=x[j]; w; (w>>=1),z++);
+ z+=bpe*j;
+ return z;
+ },
+
+ //return a copy of x with at least n elements, adding leading zeros if needed
+ 'expand': function(x,n) {
+ var ans=int2bigInt(0,(x.length>n ? x.length : n)*bpe,0);
+ copy_(ans,x);
+ return ans;
+ },
+
+ //return a k-bit true random prime using Maurer's algorithm.
+ 'randTruePrime': function(k) {
+ var ans=int2bigInt(0,k,0);
+ randTruePrime_(ans,k);
+ return trim(ans,1);
+ },
+
+ //return a new bigInt equal to (x mod n) for bigInts x and n.
+ 'mod': function(x,n) {
+ var ans=dup(x);
+ mod_(ans,n);
+ return trim(ans,1);
+ },
+
+ //return (x+n) where x is a bigInt and n is an integer.
+ 'addInt': function(x,n) {
+ var ans=expand(x,x.length+1);
+ addInt_(ans,n);
+ return trim(ans,1);
+ },
+
+ //return x*y for bigInts x and y. This is faster when y<x.
+ 'mult': function(x,y) {
+ var ans=expand(x,x.length+y.length);
+ mult_(ans,y);
+ return trim(ans,1);
+ },
+
+ //return (x**y mod n) where x,y,n are bigInts and ** is exponentiation. 0**0=1. Faster for odd n.
+ 'powMod': function(x,y,n) {
+ var ans=expand(x,n.length);
+ powMod_(ans,trim(y,2),trim(n,2),0); //this should work without the trim, but doesn't
+ return trim(ans,1);
+ },
+
+ //return (x-y) for bigInts x and y. Negative answers will be 2s complement
+ 'sub': function(x,y) {
+ var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1));
+ sub_(ans,y);
+ return trim(ans,1);
+ },
+
+ //return (x+y) for bigInts x and y.
+ 'add': function(x,y) {
+ var ans=expand(x,(x.length>y.length ? x.length+1 : y.length+1));
+ add_(ans,y);
+ return trim(ans,1);
+ },
+
+ //return (x**(-1) mod n) for bigInts x and n. If no inverse exists, it returns null
+ 'inverseMod': function(x,n) {
+ var ans=expand(x,n.length);
+ var s;
+ s=inverseMod_(ans,n);
+ return s ? trim(ans,1) : null;
+ },
+
+ //return (x*y mod n) for bigInts x,y,n. For greater speed, let y<x.
+ 'multMod': function(x,y,n) {
+ var ans=expand(x,n.length);
+ multMod_(ans,y,n);
+ return trim(ans,1);
+ },
+
+ //generate a k-bit true random prime using Maurer's algorithm,
+ //and put it into ans. The bigInt ans must be large enough to hold it.
+ 'randTruePrime_': function(ans,k) {
+ var c,m,pm,dd,j,r,B,divisible,z,zz,recSize;
+
+ if (primes.length==0)
+ primes=findPrimes(30000); //check for divisibility by primes <=30000
+
+ if (pows.length==0) {
+ pows=new Array(512);
+ for (j=0;j<512;j++) {
+ pows[j]=Math.pow(2,j/511.-1.);
+ }
+ }
+
+ //c and m should be tuned for a particular machine and value of k, to maximize speed
+ //this was: c=primes[primes.length-1]/k/k; //check using all the small primes. (c=0.1 in HAC)
+ c=0.1;
+ m=20; //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
+ recLimit=20; /*must be at least 2 (was 29)*/ //stop recursion when k <=recLimit
+
+ if (s_i2.length!=ans.length) {
+ s_i2=dup(ans);
+ s_R =dup(ans);
+ s_n1=dup(ans);
+ s_r2=dup(ans);
+ s_d =dup(ans);
+ s_x1=dup(ans);
+ s_x2=dup(ans);
+ s_b =dup(ans);
+ s_n =dup(ans);
+ s_i =dup(ans);
+ s_rm=dup(ans);
+ s_q =dup(ans);
+ s_a =dup(ans);
+ s_aa=dup(ans);
+ }
+
+ if (k <= recLimit) { //generate small random primes by trial division up to its square root
+ pm=(1<<((k+2)>>1))-1; //pm is binary number with all ones, just over sqrt(2^k)
+ copyInt_(ans,0);
+ for (dd=1;dd;) {
+ dd=0;
+ ans[0]= 1 | (1<<(k-1)) | Math.floor(Math.random()*(1<<k)); //random, k-bit, odd integer, with msb 1
+ for (j=1;(j<primes.length) && ((primes[j]&pm)==primes[j]);j++) { //trial division by all primes 3...sqrt(2^k)
+ if (0==(ans[0]%primes[j])) {
+ dd=1;
+ break;
+ }
+ }
+ }
+ carry_(ans);
+ return;
+ }
+
+ B=c*k*k; //try small primes up to B (or all the primes[] array if the largest is less than B).
+ if (k>2*m) //generate this k-bit number by first recursively generating a number that has between k/2 and k-m bits
+ for (r=1; k-k*r<=m; )
+ r=pows[Math.floor(Math.random()*512)]; //r=Math.pow(2,Math.random()-1);
+ else
+ r=.5;
+
+ //simulation suggests the more complex algorithm using r=.333 is only slightly faster.
+
+ recSize=Math.floor(r*k)+1;
+
+ randTruePrime_(s_q,recSize);
+ copyInt_(s_i2,0);
+ s_i2[Math.floor((k-2)/bpe)] |= (1<<((k-2)%bpe)); //s_i2=2^(k-2)
+ divide_(s_i2,s_q,s_i,s_rm); //s_i=floor((2^(k-1))/(2q))
+
+ z=bitSize(s_i);
+
+ for (;;) {
+ for (;;) { //generate z-bit numbers until one falls in the range [0,s_i-1]
+ randBigInt_(s_R,z,0);
+ if (greater(s_i,s_R))
+ break;
+ } //now s_R is in the range [0,s_i-1]
+ addInt_(s_R,1); //now s_R is in the range [1,s_i]
+ add_(s_R,s_i); //now s_R is in the range [s_i+1,2*s_i]
+
+ copy_(s_n,s_q);
+ mult_(s_n,s_R);
+ multInt_(s_n,2);
+ addInt_(s_n,1); //s_n=2*s_R*s_q+1
+
+ copy_(s_r2,s_R);
+ multInt_(s_r2,2); //s_r2=2*s_R
+
+ //check s_n for divisibility by small primes up to B
+ for (divisible=0,j=0; (j<primes.length) && (primes[j]<B); j++)
+ if (modInt(s_n,primes[j])==0) {
+ divisible=1;
+ break;
+ }
+
+ if (!divisible) //if it passes small primes check, then try a single Miller-Rabin base 2
+ if (!millerRabin(s_n,2)) //this line represents 75% of the total runtime for randTruePrime_
+ divisible=1;
+
+ if (!divisible) { //if it passes that test, continue checking s_n
+ addInt_(s_n,-3);
+ for (j=s_n.length-1;(s_n[j]==0) && (j>0); j--); //strip leading zeros
+ for (zz=0,w=s_n[j]; w; (w>>=1),zz++);
+ zz+=bpe*j; //zz=number of bits in s_n, ignoring leading zeros
+ for (;;) { //generate z-bit numbers until one falls in the range [0,s_n-1]
+ randBigInt_(s_a,zz,0);
+ if (greater(s_n,s_a))
+ break;
+ } //now s_a is in the range [0,s_n-1]
+ addInt_(s_n,3); //now s_a is in the range [0,s_n-4]
+ addInt_(s_a,2); //now s_a is in the range [2,s_n-2]
+ copy_(s_b,s_a);
+ copy_(s_n1,s_n);
+ addInt_(s_n1,-1);
+ powMod_(s_b,s_n1,s_n); //s_b=s_a^(s_n-1) modulo s_n
+ addInt_(s_b,-1);
+ if (isZero(s_b)) {
+ copy_(s_b,s_a);
+ powMod_(s_b,s_r2,s_n);
+ addInt_(s_b,-1);
+ copy_(s_aa,s_n);
+ copy_(s_d,s_b);
+ GCD_(s_d,s_n); //if s_b and s_n are relatively prime, then s_n is a prime
+ if (equalsInt(s_d,1)) {
+ copy_(ans,s_aa);
+ return; //if we've made it this far, then s_n is absolutely guaranteed to be prime
+ }
+ }
+ }
+ }
+ },
+
+ //set b to an n-bit random BigInt. If s=1, then nth bit (most significant bit) is set to 1.
+ //array b must be big enough to hold the result. Must have n>=1
+ 'randBigInt_': function(b,n,s) {
+ var i,a;
+ for (i=0;i<b.length;i++)
+ b[i]=0;
+ a=Math.floor((n-1)/bpe)+1; //# array elements to hold the BigInt
+ for (i=0;i<a;i++) {
+ b[i]=Math.floor(Math.random()*(1<<(bpe-1)));
+ }
+ b[a-1] &= (2<<((n-1)%bpe))-1;
+ if (s)
+ b[a-1] |= (1<<((n-1)%bpe));
+ },
+
+ //set x to the greatest common divisor of x and y.
+ //x,y are bigInts with the same number of elements. y is destroyed.
+ 'GCD_': function(x,y) {
+ var i,xp,yp,A,B,C,D,q,sing;
+ if (T.length!=x.length)
+ T=dup(x);
+
+ sing=1;
+ while (sing) { //while y has nonzero elements other than y[0]
+ sing=0;
+ for (i=1;i<y.length;i++) //check if y has nonzero elements other than 0
+ if (y[i]) {
+ sing=1;
+ break;
+ }
+ if (!sing) break; //quit when y all zero elements except possibly y[0]
+
+ for (i=x.length;!x[i] && i>=0;i--); //find most significant element of x
+ xp=x[i];
+ yp=y[i];
+ A=1; B=0; C=0; D=1;
+ while ((yp+C) && (yp+D)) {
+ q =Math.floor((xp+A)/(yp+C));
+ qp=Math.floor((xp+B)/(yp+D));
+ if (q!=qp)
+ break;
+ t= A-q*C; A=C; C=t; // do (A,B,xp, C,D,yp) = (C,D,yp, A,B,xp) - q*(0,0,0, C,D,yp)
+ t= B-q*D; B=D; D=t;
+ t=xp-q*yp; xp=yp; yp=t;
+ }
+ if (B) {
+ copy_(T,x);
+ linComb_(x,y,A,B); //x=A*x+B*y
+ linComb_(y,T,D,C); //y=D*y+C*T
+ } else {
+ mod_(x,y);
+ copy_(T,x);
+ copy_(x,y);
+ copy_(y,T);
+ }
+ }
+ if (y[0]==0)
+ return;
+ t=modInt(x,y[0]);
+ copyInt_(x,y[0]);
+ y[0]=t;
+ while (y[0]) {
+ x[0]%=y[0];
+ t=x[0]; x[0]=y[0]; y[0]=t;
+ }
+ },
+
+//do x=x**(-1) mod n, for bigInts x and n.
+//If no inverse exists, it sets x to zero and returns 0, else it returns 1.
+//The x array must be at least as large as the n array.
+function inverseMod_(x,n) {
+ var k=1+2*Math.max(x.length,n.length);
+
+ if(!(x[0]&1) && !(n[0]&1)) { //if both inputs are even, then inverse doesn't exist
+ copyInt_(x,0);
+ return 0;
+ }
+
+ if (eg_u.length!=k) {
+ eg_u=new Array(k);
+ eg_v=new Array(k);
+ eg_A=new Array(k);
+ eg_B=new Array(k);
+ eg_C=new Array(k);
+ eg_D=new Array(k);
+ }
+
+ copy_(eg_u,x);
+ copy_(eg_v,n);
+ copyInt_(eg_A,1);
+ copyInt_(eg_B,0);
+ copyInt_(eg_C,0);
+ copyInt_(eg_D,1);
+ for (;;) {
+ while(!(eg_u[0]&1)) { //while eg_u is even
+ halve_(eg_u);
+ if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if eg_A==eg_B==0 mod 2
+ halve_(eg_A);
+ halve_(eg_B);
+ } else {
+ add_(eg_A,n); halve_(eg_A);
+ sub_(eg_B,x); halve_(eg_B);
+ }
+ }
+
+ while (!(eg_v[0]&1)) { //while eg_v is even
+ halve_(eg_v);
+ if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if eg_C==eg_D==0 mod 2
+ halve_(eg_C);
+ halve_(eg_D);
+ } else {
+ add_(eg_C,n); halve_(eg_C);
+ sub_(eg_D,x); halve_(eg_D);
+ }
+ }
+
+ if (!greater(eg_v,eg_u)) { //eg_v <= eg_u
+ sub_(eg_u,eg_v);
+ sub_(eg_A,eg_C);
+ sub_(eg_B,eg_D);
+ } else { //eg_v > eg_u
+ sub_(eg_v,eg_u);
+ sub_(eg_C,eg_A);
+ sub_(eg_D,eg_B);
+ }
+
+ if (equalsInt(eg_u,0)) {
+ if (negative(eg_C)) //make sure answer is nonnegative
+ add_(eg_C,n);
+ copy_(x,eg_C);
+
+ if (!equalsInt(eg_v,1)) { //if GCD_(x,n)!=1, then there is no inverse
+ copyInt_(x,0);
+ return 0;
+ }
+ return 1;
+ }
+ }
+}
+
+//return x**(-1) mod n, for integers x and n. Return 0 if there is no inverse
+function inverseModInt_(x,n) {
+ var a=1,b=0,t;
+ for (;;) {
+ if (x==1) return a;
+ if (x==0) return 0;
+ b-=a*Math.floor(n/x);
+ n%=x;
+
+ if (n==1) return b; //to avoid negatives, change this b to n-b, and each -= to +=
+ if (n==0) return 0;
+ a-=b*Math.floor(x/n);
+ x%=n;
+ }
+}
+
+//Given positive bigInts x and y, change the bigints v, a, and b to positive bigInts such that:
+// v = GCD_(x,y) = a*x-b*y
+//The bigInts v, a, b, must have exactly as many elements as the larger of x and y.
+function eGCD_(x,y,v,a,b) {
+ var g=0;
+ var k=Math.max(x.length,y.length);
+ if (eg_u.length!=k) {
+ eg_u=new Array(k);
+ eg_A=new Array(k);
+ eg_B=new Array(k);
+ eg_C=new Array(k);
+ eg_D=new Array(k);
+ }
+ while(!(x[0]&1) && !(y[0]&1)) { //while x and y both even
+ halve_(x);
+ halve_(y);
+ g++;
+ }
+ copy_(eg_u,x);
+ copy_(v,y);
+ copyInt_(eg_A,1);
+ copyInt_(eg_B,0);
+ copyInt_(eg_C,0);
+ copyInt_(eg_D,1);
+ for (;;) {
+ while(!(eg_u[0]&1)) { //while u is even
+ halve_(eg_u);
+ if (!(eg_A[0]&1) && !(eg_B[0]&1)) { //if A==B==0 mod 2
+ halve_(eg_A);
+ halve_(eg_B);
+ } else {
+ add_(eg_A,y); halve_(eg_A);
+ sub_(eg_B,x); halve_(eg_B);
+ }
+ }
+
+ while (!(v[0]&1)) { //while v is even
+ halve_(v);
+ if (!(eg_C[0]&1) && !(eg_D[0]&1)) { //if C==D==0 mod 2
+ halve_(eg_C);
+ halve_(eg_D);
+ } else {
+ add_(eg_C,y); halve_(eg_C);
+ sub_(eg_D,x); halve_(eg_D);
+ }
+ }
+
+ if (!greater(v,eg_u)) { //v<=u
+ sub_(eg_u,v);
+ sub_(eg_A,eg_C);
+ sub_(eg_B,eg_D);
+ } else { //v>u
+ sub_(v,eg_u);
+ sub_(eg_C,eg_A);
+ sub_(eg_D,eg_B);
+ }
+ if (equalsInt(eg_u,0)) {
+ if (negative(eg_C)) { //make sure a (C)is nonnegative
+ add_(eg_C,y);
+ sub_(eg_D,x);
+ }
+ multInt_(eg_D,-1); ///make sure b (D) is nonnegative
+ copy_(a,eg_C);
+ copy_(b,eg_D);
+ leftShift_(v,g);
+ return;
+ }
+ }
+}
+
+
+//is bigInt x negative?
+function negative(x) {
+ return ((x[x.length-1]>>(bpe-1))&1);
+}
+
+
+//is (x << (shift*bpe)) > y?
+//x and y are nonnegative bigInts
+//shift is a nonnegative integer
+function greaterShift(x,y,shift) {
+ var kx=x.length, ky=y.length;
+ k=((kx+shift)<ky) ? (kx+shift) : ky;
+ for (i=ky-1-shift; i<kx && i>=0; i++)
+ if (x[i]>0)
+ return 1; //if there are nonzeros in x to the left of the first column of y, then x is bigger
+ for (i=kx-1+shift; i<ky; i++)
+ if (y[i]>0)
+ return 0; //if there are nonzeros in y to the left of the first column of x, then x is not bigger
+ for (i=k-1; i>=shift; i--)
+ if (x[i-shift]>y[i]) return 1;
+ else if (x[i-shift]<y[i]) return 0;
+ return 0;
+}
+
+//is x > y? (x and y both nonnegative)
+function greater(x,y) {
+ var i;
+ var k=(x.length<y.length) ? x.length : y.length;
+
+ for (i=x.length;i<y.length;i++)
+ if (y[i])
+ return 0; //y has more digits
+
+ for (i=y.length;i<x.length;i++)
+ if (x[i])
+ return 1; //x has more digits
+
+ for (i=k-1;i>=0;i--)
+ if (x[i]>y[i])
+ return 1;
+ else if (x[i]<y[i])
+ return 0;
+ return 0;
+}
+
+//divide_ x by y giving quotient q and remainder r. (q=floor(x/y), r=x mod y). All 4 are bigints.
+//x must have at least one leading zero element.
+//y must be nonzero.
+//q and r must be arrays that are exactly the same length as x.
+//the x array must have at least as many elements as y.
+function divide_(x,y,q,r) {
+ var kx, ky;
+ var i,j,y1,y2,c,a,b;
+ copy_(r,x);
+ for (ky=y.length;y[ky-1]==0;ky--); //kx,ky is number of elements in x,y, not including leading zeros
+ for (kx=r.length;r[kx-1]==0 && kx>ky;kx--);
+
+ //normalize: ensure the most significant element of y has its highest bit set
+ b=y[ky-1];
+ for (a=0; b; a++)
+ b>>=1;
+ a=bpe-a; //a is how many bits to shift so that the high order bit of y is leftmost in its array element
+ leftShift_(y,a); //multiply both by 1<<a now, then divide_ both by that at the end
+ leftShift_(r,a);
+
+ copyInt_(q,0); // q=0
+ while (!greaterShift(y,r,kx-ky)) { // while (leftShift_(y,kx-ky) <= r) {
+ subShift_(r,y,kx-ky); // r=r-leftShift_(y,kx-ky)
+ q[kx-ky]++; // q[kx-ky]++;
+ } // }
+
+ for (i=kx-1; i>=ky; i--) {
+ if (r[i]==y[ky-1])
+ q[i-ky]=mask;
+ else
+ q[i-ky]=Math.floor((r[i]*radix+r[i-1])/y[ky-1]);
+
+ //The following for(;;) loop is equivalent to the commented while loop,
+ //except that the uncommented version avoids overflow.
+ //The commented loop comes from HAC, which assumes r[-1]==y[-1]==0
+ // while (q[i-ky]*(y[ky-1]*radix+y[ky-2]) > r[i]*radix*radix+r[i-1]*radix+r[i-2])
+ // q[i-ky]--;
+ for (;;) {
+ y2=(ky>1 ? y[ky-2] : 0)*q[i-ky];
+ c=y2>>bpe;
+ y2=y2 & mask;
+ y1=c+q[i-ky]*y[ky-1];
+ c=y1>>bpe;
+ y1=y1 & mask;
+
+ if (c==r[i] ? y1==r[i-1] ? y2>(i>1 ? r[i-2] : 0) : y1>r[i-1] : c>r[i])
+ q[i-ky]--;
+ else
+ break;
+ }
+
+ linCombShift_(r,y,-q[i-ky],i-ky); //r=r-q[i-ky]*leftShift_(y,i-ky)
+ if (negative(r)) {
+ addShift_(r,y,i-ky); //r=r+leftShift_(y,i-ky)
+ q[i-ky]--;
+ }
+ }
+
+ rightShift_(y,a); //undo the normalization step
+ rightShift_(r,a); //undo the normalization step
+}
+
+//do carries and borrows so each element of the bigInt x fits in bpe bits.
+function carry_(x) {
+ var i,k,c,b;
+ k=x.length;
+ c=0;
+ for (i=0;i<k;i++) {
+ c+=x[i];
+ b=0;
+ if (c<0) {
+ b=-(c>>bpe);
+ c+=b*radix;
+ }
+ x[i]=c & mask;
+ c=(c>>bpe)-b;
+ }
+}
+
+//return x mod n for bigInt x and integer n.
+function modInt(x,n) {
+ var i,c=0;
+ for (i=x.length-1; i>=0; i--)
+ c=(c*radix+x[i])%n;
+ return c;
+}
+
+//convert the integer t into a bigInt with at least the given number of bits.
+//the returned array stores the bigInt in bpe-bit chunks, little endian (buff[0] is least significant word)
+//Pad the array with leading zeros so that it has at least minSize elements.
+//There will always be at least one leading 0 element.
+function int2bigInt(t,bits,minSize) {
+ var i,k;
+ k=Math.ceil(bits/bpe)+1;
+ k=minSize>k ? minSize : k;
+ buff=new Array(k);
+ copyInt_(buff,t);
+ return buff;
+}
+
+//return the bigInt given a string representation in a given base.
+//Pad the array with leading zeros so that it has at least minSize elements.
+//If base=-1, then it reads in a space-separated list of array elements in decimal.
+//The array will always have at least one leading zero, unless base=-1.
+function str2bigInt(s,base,minSize) {
+ var d, i, j, x, y, kk;
+ var k=s.length;
+ if (base==-1) { //comma-separated list of array elements in decimal
+ x=new Array(0);
+ for (;;) {
+ y=new Array(x.length+1);
+ for (i=0;i<x.length;i++)
+ y[i+1]=x[i];
+ y[0]=parseInt(s,10);
+ x=y;
+ d=s.indexOf(',',0);
+ if (d<1)
+ break;
+ s=s.substring(d+1);
+ if (s.length==0)
+ break;
+ }
+ if (x.length<minSize) {
+ y=new Array(minSize);
+ copy_(y,x);
+ return y;
+ }
+ return x;
+ }
+
+ x=int2bigInt(0,base*k,0);
+ for (i=0;i<k;i++) {
+ d=digitsStr.indexOf(s.substring(i,i+1),0);
+ if (base<=36 && d>=36) //convert lowercase to uppercase if base<=36
+ d-=26;
+ if (d<base && d>=0) { //ignore illegal characters
+ multInt_(x,base);
+ addInt_(x,d);
+ }
+ }
+
+ for (k=x.length;k>0 && !x[k-1];k--); //strip off leading zeros
+ k=minSize>k+1 ? minSize : k+1;
+ y=new Array(k);
+ kk=k<x.length ? k : x.length;
+ for (i=0;i<kk;i++)
+ y[i]=x[i];
+ for (;i<k;i++)
+ y[i]=0;
+ return y;
+}
+
+//is bigint x equal to integer y?
+//y must have less than bpe bits
+function equalsInt(x,y) {
+ var i;
+ if (x[0]!=y)
+ return 0;
+ for (i=1;i<x.length;i++)
+ if (x[i])
+ return 0;
+ return 1;
+}
+
+//are bigints x and y equal?
+//this works even if x and y are different lengths and have arbitrarily many leading zeros
+function equals(x,y) {
+ var i;
+ var k=x.length<y.length ? x.length : y.length;
+ for (i=0;i<k;i++)
+ if (x[i]!=y[i])
+ return 0;
+ if (x.length>y.length) {
+ for (;i<x.length;i++)
+ if (x[i])
+ return 0;
+ } else {
+ for (;i<y.length;i++)
+ if (y[i])
+ return 0;
+ }
+ return 1;
+}
+
+//is the bigInt x equal to zero?
+function isZero(x) {
+ var i;
+ for (i=0;i<x.length;i++)
+ if (x[i])
+ return 0;
+ return 1;
+}
+
+//convert a bigInt into a string in a given base, from base 2 up to base 95.
+//Base -1 prints the contents of the array representing the number.
+function bigInt2str(x,base) {
+ var i,t,s="";
+
+ if (s6.length!=x.length)
+ s6=dup(x);
+ else
+ copy_(s6,x);
+
+ if (base==-1) { //return the list of array contents
+ for (i=x.length-1;i>0;i--)
+ s+=x[i]+',';
+ s+=x[0];
+ }
+ else { //return it in the given base
+ while (!isZero(s6)) {
+ t=divInt_(s6,base); //t=s6 % base; s6=floor(s6/base);
+ s=digitsStr.substring(t,t+1)+s;
+ }
+ }
+ if (s.length==0)
+ s="0";
+ return s;
+}
+
+//returns a duplicate of bigInt x
+function dup(x) {
+ var i;
+ buff=new Array(x.length);
+ copy_(buff,x);
+ return buff;
+}
+
+//do x=y on bigInts x and y. x must be an array at least as big as y (not counting the leading zeros in y).
+function copy_(x,y) {
+ var i;
+ var k=x.length<y.length ? x.length : y.length;
+ for (i=0;i<k;i++)
+ x[i]=y[i];
+ for (i=k;i<x.length;i++)
+ x[i]=0;
+}
+
+//do x=y on bigInt x and integer y.
+function copyInt_(x,n) {
+ var i,c;
+ for (c=n,i=0;i<x.length;i++) {
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+}
+
+//do x=x+n where x is a bigInt and n is an integer.
+//x must be large enough to hold the result.
+function addInt_(x,n) {
+ var i,k,c,b;
+ x[0]+=n;
+ k=x.length;
+ c=0;
+ for (i=0;i<k;i++) {
+ c+=x[i];
+ b=0;
+ if (c<0) {
+ b=-(c>>bpe);
+ c+=b*radix;
+ }
+ x[i]=c & mask;
+ c=(c>>bpe)-b;
+ if (!c) return; //stop carrying as soon as the carry_ is zero
+ }
+}
+
+//right shift bigInt x by n bits. 0 <= n < bpe.
+function rightShift_(x,n) {
+ var i;
+ var k=Math.floor(n/bpe);
+ if (k) {
+ for (i=0;i<x.length-k;i++) //right shift x by k elements
+ x[i]=x[i+k];
+ for (;i<x.length;i++)
+ x[i]=0;
+ n%=bpe;
+ }
+ for (i=0;i<x.length-1;i++) {
+ x[i]=mask & ((x[i+1]<<(bpe-n)) | (x[i]>>n));
+ }
+ x[i]>>=n;
+}
+
+//do x=floor(|x|/2)*sgn(x) for bigInt x in 2's complement
+function halve_(x) {
+ var i;
+ for (i=0;i<x.length-1;i++) {
+ x[i]=mask & ((x[i+1]<<(bpe-1)) | (x[i]>>1));
+ }
+ x[i]=(x[i]>>1) | (x[i] & (radix>>1)); //most significant bit stays the same
+}
+
+//left shift bigInt x by n bits.
+function leftShift_(x,n) {
+ var i;
+ var k=Math.floor(n/bpe);
+ if (k) {
+ for (i=x.length; i>=k; i--) //left shift x by k elements
+ x[i]=x[i-k];
+ for (;i>=0;i--)
+ x[i]=0;
+ n%=bpe;
+ }
+ if (!n)
+ return;
+ for (i=x.length-1;i>0;i--) {
+ x[i]=mask & ((x[i]<<n) | (x[i-1]>>(bpe-n)));
+ }
+ x[i]=mask & (x[i]<<n);
+}
+
+//do x=x*n where x is a bigInt and n is an integer.
+//x must be large enough to hold the result.
+function multInt_(x,n) {
+ var i,k,c,b;
+ if (!n)
+ return;
+ k=x.length;
+ c=0;
+ for (i=0;i<k;i++) {
+ c+=x[i]*n;
+ b=0;
+ if (c<0) {
+ b=-(c>>bpe);
+ c+=b*radix;
+ }
+ x[i]=c & mask;
+ c=(c>>bpe)-b;
+ }
+}
+
+//do x=floor(x/n) for bigInt x and integer n, and return the remainder
+function divInt_(x,n) {
+ var i,r=0,s;
+ for (i=x.length-1;i>=0;i--) {
+ s=r*radix+x[i];
+ x[i]=Math.floor(s/n);
+ r=s%n;
+ }
+ return r;
+}
+
+//do the linear combination x=a*x+b*y for bigInts x and y, and integers a and b.
+//x must be large enough to hold the answer.
+function linComb_(x,y,a,b) {
+ var i,c,k,kk;
+ k=x.length<y.length ? x.length : y.length;
+ kk=x.length;
+ for (c=0,i=0;i<k;i++) {
+ c+=a*x[i]+b*y[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+ for (i=k;i<kk;i++) {
+ c+=a*x[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+}
+
+//do the linear combination x=a*x+b*(y<<(ys*bpe)) for bigInts x and y, and integers a, b and ys.
+//x must be large enough to hold the answer.
+function linCombShift_(x,y,b,ys) {
+ var i,c,k,kk;
+ k=x.length<ys+y.length ? x.length : ys+y.length;
+ kk=x.length;
+ for (c=0,i=ys;i<k;i++) {
+ c+=x[i]+b*y[i-ys];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+ for (i=k;c && i<kk;i++) {
+ c+=x[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+}
+
+//do x=x+(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
+//x must be large enough to hold the answer.
+function addShift_(x,y,ys) {
+ var i,c,k,kk;
+ k=x.length<ys+y.length ? x.length : ys+y.length;
+ kk=x.length;
+ for (c=0,i=ys;i<k;i++) {
+ c+=x[i]+y[i-ys];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+ for (i=k;c && i<kk;i++) {
+ c+=x[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+}
+
+//do x=x-(y<<(ys*bpe)) for bigInts x and y, and integers a,b and ys.
+//x must be large enough to hold the answer.
+function subShift_(x,y,ys) {
+ var i,c,k,kk;
+ k=x.length<ys+y.length ? x.length : ys+y.length;
+ kk=x.length;
+ for (c=0,i=ys;i<k;i++) {
+ c+=x[i]-y[i-ys];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+ for (i=k;c && i<kk;i++) {
+ c+=x[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+}
+
+//do x=x-y for bigInts x and y.
+//x must be large enough to hold the answer.
+//negative answers will be 2s complement
+function sub_(x,y) {
+ var i,c,k,kk;
+ k=x.length<y.length ? x.length : y.length;
+ for (c=0,i=0;i<k;i++) {
+ c+=x[i]-y[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+ for (i=k;c && i<x.length;i++) {
+ c+=x[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+}
+
+//do x=x+y for bigInts x and y.
+//x must be large enough to hold the answer.
+function add_(x,y) {
+ var i,c,k,kk;
+ k=x.length<y.length ? x.length : y.length;
+ for (c=0,i=0;i<k;i++) {
+ c+=x[i]+y[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+ for (i=k;c && i<x.length;i++) {
+ c+=x[i];
+ x[i]=c & mask;
+ c>>=bpe;
+ }
+}
+
+//do x=x*y for bigInts x and y. This is faster when y<x.
+function mult_(x,y) {
+ var i;
+ if (ss.length!=2*x.length)
+ ss=new Array(2*x.length);
+ copyInt_(ss,0);
+ for (i=0;i<y.length;i++)
+ if (y[i])
+ linCombShift_(ss,x,y[i],i); //ss=1*ss+y[i]*(x<<(i*bpe))
+ copy_(x,ss);
+}
+
+//do x=x mod n for bigInts x and n.
+function mod_(x,n) {
+ if (s4.length!=x.length)
+ s4=dup(x);
+ else
+ copy_(s4,x);
+ if (s5.length!=x.length)
+ s5=dup(x);
+ divide_(s4,n,s5,x); //x = remainder of s4 / n
+}
+
+//do x=x*y mod n for bigInts x,y,n.
+//for greater speed, let y<x.
+function multMod_(x,y,n) {
+ var i;
+ if (s0.length!=2*x.length)
+ s0=new Array(2*x.length);
+ copyInt_(s0,0);
+ for (i=0;i<y.length;i++)
+ if (y[i])
+ linCombShift_(s0,x,y[i],i); //s0=1*s0+y[i]*(x<<(i*bpe))
+ mod_(s0,n);
+ copy_(x,s0);
+}
+
+//do x=x*x mod n for bigInts x,n.
+function squareMod_(x,n) {
+ var i,j,d,c,kx,kn,k;
+ for (kx=x.length; kx>0 && !x[kx-1]; kx--); //ignore leading zeros in x
+ k=kx>n.length ? 2*kx : 2*n.length; //k=# elements in the product, which is twice the elements in the larger of x and n
+ if (s0.length!=k)
+ s0=new Array(k);
+ copyInt_(s0,0);
+ for (i=0;i<kx;i++) {
+ c=s0[2*i]+x[i]*x[i];
+ s0[2*i]=c & mask;
+ c>>=bpe;
+ for (j=i+1;j<kx;j++) {
+ c=s0[i+j]+2*x[i]*x[j]+c;
+ s0[i+j]=(c & mask);
+ c>>=bpe;
+ }
+ s0[i+kx]=c;
+ }
+ mod_(s0,n);
+ copy_(x,s0);
+}
+
+//return x with exactly k leading zero elements
+function trim(x,k) {
+ var i,y;
+ for (i=x.length; i>0 && !x[i-1]; i--);
+ y=new Array(i+k);
+ copy_(y,x);
+ return y;
+}
+
+//do x=x**y mod n, where x,y,n are bigInts and ** is exponentiation. 0**0=1.
+//this is faster when n is odd. x usually needs to have as many elements as n.
+function powMod_(x,y,n) {
+ var k1,k2,kn,np;
+ if(s7.length!=n.length)
+ s7=dup(n);
+
+ //for even modulus, use a simple square-and-multiply algorithm,
+ //rather than using the more complex Montgomery algorithm.
+ if ((n[0]&1)==0) {
+ copy_(s7,x);
+ copyInt_(x,1);
+ while(!equalsInt(y,0)) {
+ if (y[0]&1)
+ multMod_(x,s7,n);
+ divInt_(y,2);
+ squareMod_(s7,n);
+ }
+ return;
+ }
+
+ //calculate np from n for the Montgomery multiplications
+ copyInt_(s7,0);
+ for (kn=n.length;kn>0 && !n[kn-1];kn--);
+ np=radix-inverseModInt_(modInt(n,radix),radix);
+ s7[kn]=1;
+ multMod_(x ,s7,n); // x = x * 2**(kn*bp) mod n
+
+ if (s3.length!=x.length)
+ s3=dup(x);
+ else
+ copy_(s3,x);
+
+ for (k1=y.length-1;k1>0 & !y[k1]; k1--); //k1=first nonzero element of y
+ if (y[k1]==0) { //anything to the 0th power is 1
+ copyInt_(x,1);
+ return;
+ }
+ for (k2=1<<(bpe-1);k2 && !(y[k1] & k2); k2>>=1); //k2=position of first 1 bit in y[k1]
+ for (;;) {
+ if (!(k2>>=1)) { //look at next bit of y
+ k1--;
+ if (k1<0) {
+ mont_(x,one,n,np);
+ return;
+ }
+ k2=1<<(bpe-1);
+ }
+ mont_(x,x,n,np);
+
+ if (k2 & y[k1]) //if next bit is a 1
+ mont_(x,s3,n,np);
+ }
+}
+
+//do x=x*y*Ri mod n for bigInts x,y,n,
+// where Ri = 2**(-kn*bpe) mod n, and kn is the
+// number of elements in the n array, not
+// counting leading zeros.
+//x must be large enough to hold the answer.
+//It's OK if x and y are the same variable.
+//must have:
+// x,y < n
+// n is odd
+// np = -(n^(-1)) mod radix
+function mont_(x,y,n,np) {
+ var i,j,c,ui,t;
+ var kn=n.length;
+ var ky=y.length;
+
+ if (sa.length!=kn)
+ sa=new Array(kn);
+
+ for (;kn>0 && n[kn-1]==0;kn--); //ignore leading zeros of n
+ //this function sometimes gives wrong answers when the next line is uncommented
+ //for (;ky>0 && y[ky-1]==0;ky--); //ignore leading zeros of y
+
+ copyInt_(sa,0);
+
+ //the following loop consumes 95% of the runtime for randTruePrime_() and powMod_() for large keys
+ for (i=0; i<kn; i++) {
+ t=sa[0]+x[i]*y[0];
+ ui=((t & mask) * np) & mask; //the inner "& mask" is needed on Macintosh MSIE, but not windows MSIE
+ c=(t+ui*n[0]) >> bpe;
+ t=x[i];
+
+ //do sa=(sa+x[i]*y+ui*n)/b where b=2**bpe
+ for (j=1;j<ky;j++) {
+ c+=sa[j]+t*y[j]+ui*n[j];
+ sa[j-1]=c & mask;
+ c>>=bpe;
+ }
+ for (;j<kn;j++) {
+ c+=sa[j]+ui*n[j];
+ sa[j-1]=c & mask;
+ c>>=bpe;
+ }
+ sa[j-1]=c & mask;
+ }
+
+ if (!greater(n,sa))
+ sub_(sa,n);
+ copy_(x,sa);
+}
+
+
+
+
+//#############################################################################
+//#############################################################################
+//#############################################################################
+//#############################################################################
+//#############################################################################
+//#############################################################################
+//#############################################################################
+
+
+
+
+
+//#############################################################################
+
+Clipperz.Crypto.BigInt = function (aValue, aBase) {
+ var base;
+ var value;
+
+ if (typeof(aValue) == 'object') {
+ this._internalValue = aValue;
+ } else {
+ if (typeof(aValue) == 'undefined') {
+ value = "0";
+ } else {
+ value = aValue + "";
+ }
+
+ if (typeof(aBase) == 'undefined') {
+ base = 10;
+ } else {
+ base = aBase;
+ }
+
+ this._internalValue = str2bigInt(value, base, 1, 1);
+ }
+
+ return this;
+}
+
+//=============================================================================
+
+MochiKit.Base.update(Clipperz.Crypto.BigInt.prototype, {
+
+ //-------------------------------------------------------------------------
+
+ 'internalValue': function () {
+ return this._internalValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isBigInt': true,
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function(aBase) {
+ return this.asString(aBase);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'asString': function (aBase) {
+ var base;
+
+ if (typeof(aBase) == 'undefined') {
+ base = 10;
+ } else {
+ base = aBase;
+ }
+
+ return bigInt2str(this.internalValue(), base).toLowerCase();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'equals': function (aValue) {
+ var result;
+
+ if (aValue.isBigInt) {
+ result = equals(this.internalValue(), aValue.internalValue());
+ } else if (typeof(aValue) == "number") {
+ result = equalsInt(this.internalValue(), aValue);
+ } else {
+ throw Clipperz.Crypt.BigInt.exception.UnknownType;
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'add': function (aValue) {
+ var result;
+
+ if (aValue.isBigInt) {
+ result = add(this.internalValue(), aValue.internalValue());
+ } else {
+ result = addInt(this.internalValue(), aValue);
+ }
+
+ return new Clipperz.Crypto.BigInt(result);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'subtract': function (aValue) {
+ var result;
+ var value;
+
+ if (aValue.isBigInt) {
+ value = aValue;
+ } else {
+ value = new Clipperz.Crypto.BigInt(aValue);
+ }
+
+ result = sub(this.internalValue(), value.internalValue());
+
+ return new Clipperz.Crypto.BigInt(result);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'multiply': function (aValue, aModule) {
+ var result;
+ var value;
+
+ if (aValue.isBigInt) {
+ value = aValue;
+ } else {
+ value = new Clipperz.Crypto.BigInt(aValue);
+ }
+
+ if (typeof(aModule) == 'undefined') {
+ result = mult(this.internalValue(), value.internalValue());
+ } else {
+ result = multMod(this.internalValue(), value.internalValue(), aModule);
+ }
+
+ return new Clipperz.Crypto.BigInt(result);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'module': function (aModule) {
+ var result;
+ var module;
+
+ if (aModule.isBigInt) {
+ module = aModule;
+ } else {
+ module = new Clipperz.Crypto.BigInt(aModule);
+ }
+
+ result = mod(this.internalValue(), module.internalValue());
+
+ return new Clipperz.Crypto.BigInt(result);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'powerModule': function(aValue, aModule) {
+ var result;
+ var value;
+ var module;
+
+ if (aValue.isBigInt) {
+ value = aValue;
+ } else {
+ value = new Clipperz.Crypto.BigInt(aValue);
+ }
+
+ if (aModule.isBigInt) {
+ module = aModule;
+ } else {
+ module = new Clipperz.Crypto.BigInt(aModule);
+ }
+
+ if (aValue == -1) {
+ result = inverseMod(this.internalValue(), module.internalValue());
+ } else {
+ result = powMod(this.internalValue(), value.internalValue(), module.internalValue());
+ }
+
+ return new Clipperz.Crypto.BigInt(result);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'bitSize': function() {
+ return bitSize(this.internalValue());
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
+//#############################################################################
+
+Clipperz.Crypto.BigInt.randomPrime = function(aBitSize) {
+ return new Clipperz.Crypto.BigInt(randTruePrime(aBitSize));
+}
+
+//#############################################################################
+//#############################################################################
+//#############################################################################
+
+Clipperz.Crypto.BigInt.equals = function(a, b) {
+ return a.equals(b);
+}
+
+Clipperz.Crypto.BigInt.add = function(a, b) {
+ return a.add(b);
+}
+
+Clipperz.Crypto.BigInt.subtract = function(a, b) {
+ return a.subtract(b);
+}
+
+Clipperz.Crypto.BigInt.multiply = function(a, b, module) {
+ return a.multiply(b, module);
+}
+
+Clipperz.Crypto.BigInt.module = function(a, module) {
+ return a.module(module);
+}
+
+Clipperz.Crypto.BigInt.powerModule = function(a, b, module) {
+ return a.powerModule(b, module);
+}
+
+Clipperz.Crypto.BigInt.exception = {
+ UnknownType: new MochiKit.Base.NamedError("Clipperz.Crypto.BigInt.exception.UnknownType")
+}
diff --git a/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Curve.js b/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Curve.js
new file mode 100644
index 0000000..2033eb4
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Curve.js
@@ -0,0 +1,550 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
+// throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!";
+//}
+if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; }
+if (typeof(Clipperz.Crypto.ECC.BinaryField) == 'undefined') { Clipperz.Crypto.ECC.BinaryField = {}; }
+
+Clipperz.Crypto.ECC.BinaryField.Curve = function(args) {
+ args = args || {};
+
+ this._modulus = args.modulus;
+
+ this._a = args.a;
+ this._b = args.b;
+ this._G = args.G;
+ this._r = args.r;
+ this._h = args.h;
+
+ this._finiteField = null;
+
+ return this;
+}
+
+Clipperz.Crypto.ECC.BinaryField.Curve.prototype = MochiKit.Base.update(null, {
+
+ 'asString': function() {
+ return "Clipperz.Crypto.ECC.BinaryField.Curve";
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'modulus': function() {
+ return this._modulus;
+ },
+
+ 'a': function() {
+ return this._a;
+ },
+
+ 'b': function() {
+ return this._b;
+ },
+
+ 'G': function() {
+ return this._G;
+ },
+
+ 'r': function() {
+ return this._r;
+ },
+
+ 'h': function() {
+ return this._h;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'finiteField': function() {
+ if (this._finiteField == null) {
+ this._finiteField = new Clipperz.Crypto.ECC.BinaryField.FiniteField({modulus:this.modulus()})
+ }
+
+ return this._finiteField;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'negate': function(aPointA) {
+ var result;
+
+ result = new Clipperz.Crypto.ECC.Point({x:aPointA.x(), y:this.finiteField().add(aPointA.y(), aPointA.x())})
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'add': function(aPointA, aPointB) {
+ var result;
+
+//console.log(">>> ECC.BinaryField.Curve.add");
+ if (aPointA.isZero()) {
+//console.log("--- pointA == zero");
+ result = aPointB;
+ } else if (aPointB.isZero()) {
+//console.log("--- pointB == zero");
+ result = aPointA;
+ } else if ( (aPointA.x().compare(aPointB.x()) == 0) && ((aPointA.y().compare(aPointB.y()) != 0) || aPointB.x().isZero())) {
+//console.log("compare A.x - B.x: ", aPointA.x().compare(aPointB.x()));
+//console.log("compare A.y - B.y: ", (aPointA.y().compare(aPointB.y()) != 0));
+//console.log("compare B.x.isZero(): ", aPointB.x().isZero());
+
+//console.log("--- result = zero");
+ result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
+ } else {
+//console.log("--- result = ELSE");
+ var f2m;
+ var x, y;
+ var lambda;
+ var aX, aY, bX, bY;
+
+ aX = aPointA.x()._value;
+ aY = aPointA.y()._value;
+ bX = aPointB.x()._value;
+ bY = aPointB.y()._value;
+
+ f2m = this.finiteField();
+
+ if (aPointA.x().compare(aPointB.x()) != 0) {
+//console.log(" a.x != b.x");
+ lambda = f2m._fastMultiply(
+ f2m._add(aY, bY),
+ f2m._inverse(f2m._add(aX, bX))
+ );
+ x = f2m._add(this.a()._value, f2m._square(lambda));
+ f2m._overwriteAdd(x, lambda);
+ f2m._overwriteAdd(x, aX);
+ f2m._overwriteAdd(x, bX);
+ } else {
+//console.log(" a.x == b.x");
+ lambda = f2m._add(bX, f2m._fastMultiply(bY, f2m._inverse(bX)));
+//console.log(" lambda: " + lambda.asString(16));
+ x = f2m._add(this.a()._value, f2m._square(lambda));
+//console.log(" x (step 1): " + x.asString(16));
+ f2m._overwriteAdd(x, lambda);
+//console.log(" x (step 2): " + x.asString(16));
+ }
+
+ y = f2m._fastMultiply(f2m._add(bX, x), lambda);
+//console.log(" y (step 1): " + y.asString(16));
+ f2m._overwriteAdd(y, x);
+//console.log(" y (step 2): " + y.asString(16));
+ f2m._overwriteAdd(y, bY);
+//console.log(" y (step 3): " + y.asString(16));
+
+ result = new Clipperz.Crypto.ECC.BinaryField.Point({x:new Clipperz.Crypto.ECC.BinaryField.Value(x), y:new Clipperz.Crypto.ECC.BinaryField.Value(y)})
+ }
+//console.log("<<< ECC.BinaryField.Curve.add");
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'addTwice': function(aPointA) {
+ return this.add(aPointA, aPointA);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'overwriteAdd': function(aPointA, aPointB) {
+ if (aPointA.isZero()) {
+// result = aPointB;
+ aPointA._x._value = aPointB._x._value;
+ aPointA._y._value = aPointB._y._value;
+ } else if (aPointB.isZero()) {
+// result = aPointA;
+ } else if ( (aPointA.x().compare(aPointB.x()) == 0) && ((aPointA.y().compare(aPointB.y()) != 0) || aPointB.x().isZero())) {
+// result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
+ aPointA._x = Clipperz.Crypto.ECC.BinaryField.Value.O;
+ aPointA._y = Clipperz.Crypto.ECC.BinaryField.Value.O;
+ } else {
+ var f2m;
+ var x, y;
+ var lambda;
+ var aX, aY, bX, bY;
+
+ aX = aPointA.x()._value;
+ aY = aPointA.y()._value;
+ bX = aPointB.x()._value;
+ bY = aPointB.y()._value;
+
+ f2m = this.finiteField();
+
+ if (aPointA.x().compare(aPointB.x()) != 0) {
+//console.log(" a.x != b.x");
+ lambda = f2m._fastMultiply(
+ f2m._add(aY, bY),
+ f2m._inverse(f2m._add(aX, bX))
+ );
+ x = f2m._add(this.a()._value, f2m._square(lambda));
+ f2m._overwriteAdd(x, lambda);
+ f2m._overwriteAdd(x, aX);
+ f2m._overwriteAdd(x, bX);
+ } else {
+//console.log(" a.x == b.x");
+ lambda = f2m._add(bX, f2m._fastMultiply(bY, f2m._inverse(bX)));
+//console.log(" lambda: " + lambda.asString(16));
+ x = f2m._add(this.a()._value, f2m._square(lambda));
+//console.log(" x (step 1): " + x.asString(16));
+ f2m._overwriteAdd(x, lambda);
+//console.log(" x (step 2): " + x.asString(16));
+ }
+
+ y = f2m._fastMultiply(f2m._add(bX, x), lambda);
+//console.log(" y (step 1): " + y.asString(16));
+ f2m._overwriteAdd(y, x);
+//console.log(" y (step 2): " + y.asString(16));
+ f2m._overwriteAdd(y, bY);
+//console.log(" y (step 3): " + y.asString(16));
+
+// result = new Clipperz.Crypto.ECC.BinaryField.Point({x:new Clipperz.Crypto.ECC.BinaryField.Value(x), y:new Clipperz.Crypto.ECC.BinaryField.Value(y)})
+ aPointA._x._value = x;
+ aPointA._y._value = y;
+
+ }
+//console.log("<<< ECC.BinaryField.Curve.add");
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'multiply': function(aValue, aPoint) {
+ var result;
+
+//console.profile();
+ result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
+
+ if (aValue.isZero() == false) {
+ var k, Q;
+ var i;
+ var countIndex; countIndex = 0;
+
+ if (aValue.compare(Clipperz.Crypto.ECC.BinaryField.Value.O) > 0) {
+ k = aValue;
+ Q = aPoint;
+ } else {
+MochiKit.Logging.logError("The Clipperz.Crypto.ECC.BinaryFields.Value does not work with negative values!!!!");
+ k = aValue.negate();
+ Q = this.negate(aPoint);
+ }
+
+//console.log("k: " + k.toString(16));
+//console.log("k.bitSize: " + k.bitSize());
+ for (i=k.bitSize()-1; i>=0; i--) {
+ result = this.add(result, result);
+// this.overwriteAdd(result, result);
+ if (k.isBitSet(i)) {
+ result = this.add(result, Q);
+// this.overwriteAdd(result, Q);
+ }
+
+// if (countIndex==100) {console.log("multiply.break"); break;} else countIndex++;
+ }
+ }
+//console.profileEnd();
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'deferredMultiply': function(aValue, aPoint) {
+ var deferredResult;
+ var result;
+
+MochiKit.Logging.logDebug(">>> deferredMultiply - value: " + aValue + ", point: " + aPoint);
+//console.profile("ECC.Curve.multiply");
+ deferredResult = new MochiKit.Async.Deferred();
+//deferredResult.addCallback(function(res) {console.profile("ECC.Curve.deferredMultiply"); return res;} );
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 1: " + res); return res;});
+
+ result = new Clipperz.Crypto.ECC.BinaryField.Point({x:Clipperz.Crypto.ECC.BinaryField.Value.O, y:Clipperz.Crypto.ECC.BinaryField.Value.O});
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 2: " + res); return res;});
+
+ if (aValue.isZero() == false) {
+ var k, Q;
+ var i;
+ var countIndex; countIndex = 0;
+
+ if (aValue.compare(Clipperz.Crypto.ECC.BinaryField.Value.O) > 0) {
+ k = aValue;
+ Q = aPoint;
+ } else {
+MochiKit.Logging.logError("The Clipperz.Crypto.ECC.BinaryFields.Value does not work with negative values!!!!");
+ k = aValue.negate();
+ Q = this.negate(aPoint);
+ }
+
+//console.log("k: " + k.toString(16));
+//console.log("k.bitSize: " + k.bitSize());
+
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 3: " + res); return res;});
+ for (i=k.bitSize()-1; i>=0; i--) {
+//MochiKit.Logging.logDebug("====> " + i);
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 4 > i = " + i + ": " + res); return res;});
+ deferredResult.addMethod(this, "addTwice");
+//# result = this.add(result, result);
+// this.overwriteAdd(result, result);
+ if (k.isBitSet(i)) {
+ deferredResult.addMethod(this, "add", Q);
+//# result = this.add(result, Q);
+// this.overwriteAdd(result, Q);
+ }
+ if (i%20 == 0) {deferredResult.addCallback(MochiKit.Async.wait, 0.1);}
+
+// if (countIndex==100) {console.log("multiply.break"); break;} else countIndex++;
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 4 < i = " + i + ": " + res); return res;});
+ }
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 4: " + res); return res;});
+ }
+//#console.profileEnd();
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 5: " + res); return res;});
+//deferredResult.addBoth(function(res) {console.profileEnd(); return res;});
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("# 6: " + res); return res;});
+ deferredResult.callback(result);
+
+//# return result;
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+
+//#############################################################################
+
+Clipperz.Crypto.ECC.StandardCurves = {};
+
+MochiKit.Base.update(Clipperz.Crypto.ECC.StandardCurves, {
+/*
+ '_K571': null,
+ 'K571': function() {
+ if (Clipperz.Crypto.ECC.StandardCurves._K571 == null) {
+ Clipperz.Crypto.ECC.StandardCurves._K571 = new Clipperz.Crypto.ECC.BinaryField.Curve({
+ modulus: new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000425', 16),
+ a: new Clipperz.Crypto.ECC.BinaryField.Value('0', 16),
+ b: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
+ G: new Clipperz.Crypto.ECC.BinaryField.Point({
+ x: new Clipperz.Crypto.ECC.BinaryField.Value('026eb7a8 59923fbc 82189631 f8103fe4 ac9ca297 0012d5d4 60248048 01841ca4 43709584 93b205e6 47da304d b4ceb08c bbd1ba39 494776fb 988b4717 4dca88c7 e2945283 a01c8972', 16),
+ y: new Clipperz.Crypto.ECC.BinaryField.Value('0349dc80 7f4fbf37 4f4aeade 3bca9531 4dd58cec 9f307a54 ffc61efc 006d8a2c 9d4979c0 ac44aea7 4fbebbb9 f772aedc b620b01a 7ba7af1b 320430c8 591984f6 01cd4c14 3ef1c7a3', 16)
+ }),
+ r: new Clipperz.Crypto.ECC.BinaryField.Value('02000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 131850e1 f19a63e4 b391a8db 917f4138 b630d84b e5d63938 1e91deb4 5cfe778f 637c1001', 16),
+ h: new Clipperz.Crypto.ECC.BinaryField.Value('4', 16)
+ });
+ }
+
+ return Clipperz.Crypto.ECC.StandardCurves._K571;
+ },
+
+
+
+ '_K283': null,
+ 'K283': function() { // f(z) = z^283 + z^12 + z^7 + z^5 + 1
+ if (Clipperz.Crypto.ECC.StandardCurves._K283 == null) {
+ Clipperz.Crypto.ECC.StandardCurves._K283 = new Clipperz.Crypto.ECC.BinaryField.Curve({
+ modulus: new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
+ a: new Clipperz.Crypto.ECC.BinaryField.Value('0', 16),
+ b: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
+ G: new Clipperz.Crypto.ECC.BinaryField.Point({
+ x: new Clipperz.Crypto.ECC.BinaryField.Value('0503213f 78ca4488 3f1a3b81 62f188e5 53cd265f 23c1567a 16876913 b0c2ac24 58492836', 16),
+ y: new Clipperz.Crypto.ECC.BinaryField.Value('01ccda38 0f1c9e31 8d90f95d 07e5426f e87e45c0 e8184698 e4596236 4e341161 77dd2259', 16)
+ }),
+ r: new Clipperz.Crypto.ECC.BinaryField.Value('01ffffff ffffffff ffffffff ffffffff ffffe9ae 2ed07577 265dff7f 94451e06 1e163c61', 16),
+ h: new Clipperz.Crypto.ECC.BinaryField.Value('4', 16)
+ });
+ }
+
+ return Clipperz.Crypto.ECC.StandardCurves._K283;
+ },
+*/
+ //-----------------------------------------------------------------------------
+
+ '_B571': null,
+ 'B571': function() { // f(z) = z^571 + z^10 + z^5 + z^2 + 1
+ if (Clipperz.Crypto.ECC.StandardCurves._B571 == null) {
+ Clipperz.Crypto.ECC.StandardCurves._B571 = new Clipperz.Crypto.ECC.BinaryField.Curve({
+ modulus: new Clipperz.Crypto.ECC.BinaryField.Value('80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425', 16),
+ a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
+ b: new Clipperz.Crypto.ECC.BinaryField.Value('02f40e7e2221f295de297117b7f3d62f5c6a97ffcb8ceff1cd6ba8ce4a9a18ad84ffabbd8efa59332be7ad6756a66e294afd185a78ff12aa520e4de739baca0c7ffeff7f2955727a', 16),
+ G: new Clipperz.Crypto.ECC.BinaryField.Point({
+ x: new Clipperz.Crypto.ECC.BinaryField.Value('0303001d 34b85629 6c16c0d4 0d3cd775 0a93d1d2 955fa80a a5f40fc8 db7b2abd bde53950 f4c0d293 cdd711a3 5b67fb14 99ae6003 8614f139 4abfa3b4 c850d927 e1e7769c 8eec2d19', 16),
+ y: new Clipperz.Crypto.ECC.BinaryField.Value('037bf273 42da639b 6dccfffe b73d69d7 8c6c27a6 009cbbca 1980f853 3921e8a6 84423e43 bab08a57 6291af8f 461bb2a8 b3531d2f 0485c19b 16e2f151 6e23dd3c 1a4827af 1b8ac15b', 16)
+ }),
+ r: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff e661ce18 ff559873 08059b18 6823851e c7dd9ca1 161de93d 5174d66e 8382e9bb 2fe84e47', 16),
+ h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
+
+// S: new Clipperz.Crypto.ECC.BinaryField.Value('2aa058f73a0e33ab486b0f610410c53a7f132310', 10),
+// n: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16)
+ });
+
+ //-----------------------------------------------------------------------------
+ //
+ // Guide to Elliptic Curve Cryptography
+ // Darrel Hankerson, Alfred Menezes, Scott Vanstone
+ // - Pag: 56, Alorithm 2.45 (with a typo!!!)
+ //
+ //-----------------------------------------------------------------------------
+ //
+ // http://www.milw0rm.com/papers/136
+ //
+ // -------------------------------------------------------------------------
+ // Polynomial Reduction Algorithm Modulo f571
+ // -------------------------------------------------------------------------
+ //
+ // Input: Polynomial p(x) of degree 1140 or less, stored as
+ // an array of 2T machinewords.
+ // Output: p(x) mod f571(x)
+ //
+ // FOR i = T-1, ..., 0 DO
+ // SET X := P[i+T]
+ // P[i] := P[i] ^ (X<<5) ^ (X<<7) ^ (X<<10) ^ (X<<15)
+ // P[i+1] := P[i+1] ^ (X>>17) ^ (X>>22) ^ (X>>25) ^ (X>>27)
+ //
+ // SET X := P[T-1] >> 27
+ // P[0] := P[0] ^ X ^ (X<<2) ^ (X<<5) ^ (X<<10)
+ // P[T-1] := P[T-1] & 0x07ffffff
+ //
+ // RETURN P[T-1],...,P[0]
+ //
+ // -------------------------------------------------------------------------
+ //
+ Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().slowModule = Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module;
+ Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module = function(aValue) {
+ var result;
+
+ if (aValue.bitSize() > 1140) {
+ MochiKit.Logging.logWarning("ECC.StandarCurves.B571.finiteField().module: falling back to default implementation");
+ result = Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().slowModule(aValue);
+ } else {
+ var C, T;
+ var i;
+
+//console.log(">>> binaryField.finiteField.(improved)module");
+// C = aValue.value().slice(0);
+ C = aValue._value.slice(0);
+ for (i=35; i>=18; i--) {
+ T = C[i];
+ C[i-18] = (((C[i-18] ^ (T<<5) ^ (T<<7) ^ (T<<10) ^ (T<<15)) & 0xffffffff) >>> 0);
+ C[i-17] = ((C[i-17] ^ (T>>>27) ^ (T>>>25) ^ (T>>>22) ^ (T>>>17)) >>> 0);
+ }
+ T = (C[17] >>> 27);
+ C[0] = ((C[0] ^ T ^ ((T<<2) ^ (T<<5) ^ (T<<10)) & 0xffffffff) >>> 0);
+ C[17] = (C[17] & 0x07ffffff);
+
+ for(i=18; i<=35; i++) {
+ C[i] = 0;
+ }
+
+ result = new Clipperz.Crypto.ECC.BinaryField.Value(C);
+//console.log("<<< binaryField.finiteField.(improved)module");
+ }
+
+ return result;
+ };
+ }
+
+ return Clipperz.Crypto.ECC.StandardCurves._B571;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ '_B283': null,
+ 'B283': function() { // f(z) = z^283 + z^12 + z^7 + z^5 + 1
+ if (Clipperz.Crypto.ECC.StandardCurves._B283 == null) {
+ Clipperz.Crypto.ECC.StandardCurves._B283 = new Clipperz.Crypto.ECC.BinaryField.Curve({
+// modulus: new Clipperz.Crypto.ECC.BinaryField.Value('10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
+ modulus: new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
+ a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
+ b: new Clipperz.Crypto.ECC.BinaryField.Value('027b680a c8b8596d a5a4af8a 19a0303f ca97fd76 45309fa2 a581485a f6263e31 3b79a2f5', 16),
+ G: new Clipperz.Crypto.ECC.BinaryField.Point({
+ x: new Clipperz.Crypto.ECC.BinaryField.Value('05f93925 8db7dd90 e1934f8c 70b0dfec 2eed25b8 557eac9c 80e2e198 f8cdbecd 86b12053', 16),
+ y: new Clipperz.Crypto.ECC.BinaryField.Value('03676854 fe24141c b98fe6d4 b20d02b4 516ff702 350eddb0 826779c8 13f0df45 be8112f4', 16)
+ }),
+ r: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffff ffffffff ffffffff ffffffff ffffef90 399660fc 938a9016 5b042a7c efadb307', 16),
+ h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
+
+// S: new Clipperz.Crypto.ECC.BinaryField.Value('2aa058f73a0e33ab486b0f610410c53a7f132310', 10),
+// n: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16)
+ });
+
+ //-----------------------------------------------------------------------------
+ //
+ // Guide to Elliptic Curve Cryptography
+ // Darrel Hankerson, Alfred Menezes, Scott Vanstone
+ // - Pag: 56, Alorithm 2.43
+ //
+ //-----------------------------------------------------------------------------
+ Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().slowModule = Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().module;
+ Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().module = function(aValue) {
+ var result;
+
+ if (aValue.bitSize() > 564) {
+ MochiKit.Logging.logWarning("ECC.StandarCurves.B283.finiteField().module: falling back to default implementation");
+ result = Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().slowModule(aValue);
+ } else {
+ var C, T;
+ var i;
+
+//console.log(">>> binaryField.finiteField.(improved)module");
+ C = aValue._value.slice(0);
+ for (i=17; i>=9; i--) {
+ T = C[i];
+ C[i-9] = (((C[i-9] ^ (T<<5) ^ (T<<10) ^ (T<<12) ^ (T<<17)) & 0xffffffff) >>> 0);
+ C[i-8] = ((C[i-8] ^ (T>>>27) ^ (T>>>22) ^ (T>>>20) ^ (T>>>15)) >>> 0);
+ }
+ T = (C[8] >>> 27);
+ C[0] = ((C[0] ^ T ^ ((T<<5) ^ (T<<7) ^ (T<<12)) & 0xffffffff) >>> 0);
+ C[8] = (C[8] & 0x07ffffff);
+
+ for(i=9; i<=17; i++) {
+ C[i] = 0;
+ }
+
+ result = new Clipperz.Crypto.ECC.BinaryField.Value(C);
+//console.log("<<< binaryField.finiteField.(improved)module");
+ }
+
+ return result;
+ };
+ }
+
+ return Clipperz.Crypto.ECC.StandardCurves._B283;
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+//#############################################################################
+
diff --git a/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js b/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js
new file mode 100644
index 0000000..a649c9f
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js
@@ -0,0 +1,526 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
+// throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!";
+//}
+if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; }
+if (typeof(Clipperz.Crypto.ECC.BinaryField) == 'undefined') { Clipperz.Crypto.ECC.BinaryField = {}; }
+
+Clipperz.Crypto.ECC.BinaryField.FiniteField = function(args) {
+ args = args || {};
+ this._modulus = args.modulus;
+
+ return this;
+}
+
+Clipperz.Crypto.ECC.BinaryField.FiniteField.prototype = MochiKit.Base.update(null, {
+
+ 'asString': function() {
+ return "Clipperz.Crypto.ECC.BinaryField.FiniteField (" + this.modulus().asString() + ")";
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'modulus': function() {
+ return this._modulus;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ '_module': function(aValue) {
+ var result;
+ var modulusComparison;
+//console.log(">>> binaryField.finiteField.(standard)module");
+
+ modulusComparison = Clipperz.Crypto.ECC.BinaryField.Value._compare(aValue, this.modulus()._value);
+
+ if (modulusComparison < 0) {
+ result = aValue;
+ } else if (modulusComparison == 0) {
+ result = [0];
+ } else {
+ var modulusBitSize;
+ var resultBitSize;
+
+ result = aValue;
+
+ modulusBitSize = this.modulus().bitSize();
+ resultBitSize = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(result);
+ while (resultBitSize >= modulusBitSize) {
+ Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor(result, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(this.modulus()._value, resultBitSize - modulusBitSize));
+ resultBitSize = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(result);
+ }
+ }
+//console.log("<<< binaryField.finiteField.(standard)module");
+
+ return result;
+ },
+
+ 'module': function(aValue) {
+ return new Clipperz.Crypto.ECC.BinaryField.Value(this._module(aValue._value.slice(0)));
+ },
+
+ //-----------------------------------------------------------------------------
+
+ '_add': function(a, b) {
+ return Clipperz.Crypto.ECC.BinaryField.Value._xor(a, b);
+ },
+
+ '_overwriteAdd': function(a, b) {
+ Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor(a, b);
+ },
+
+ 'add': function(a, b) {
+ return new Clipperz.Crypto.ECC.BinaryField.Value(this._add(a._value, b._value));
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'negate': function(aValue) {
+ return aValue.clone();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ '_multiply': function(a, b) {
+ var result;
+ var valueToXor;
+ var i,c;
+
+ result = [0];
+ valueToXor = b;
+ c = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(a);
+ for (i=0; i<c; i++) {
+ if (Clipperz.Crypto.ECC.BinaryField.Value._isBitSet(a, i) === true) {
+ Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor(result, valueToXor);
+ }
+ valueToXor = Clipperz.Crypto.ECC.BinaryField.Value._overwriteShiftLeft(valueToXor, 1);
+ }
+ result = this._module(result);
+
+ return result;
+ },
+
+ 'multiply': function(a, b) {
+ return new Clipperz.Crypto.ECC.BinaryField.Value(this._multiply(a._value, b._value));
+ },
+
+ //-----------------------------------------------------------------------------
+
+ '_fastMultiply': function(a, b) {
+ var result;
+ var B;
+ var i,c;
+
+ result = [0];
+ B = b.slice(0); // Is this array copy avoidable?
+ c = 32;
+ for (i=0; i<c; i++) {
+ var ii, cc;
+
+ cc = a.length;
+ for (ii=0; ii<cc; ii++) {
+ if (((a[ii] >>> i) & 0x01) == 1) {
+ Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor(result, B, ii);
+ }
+ }
+
+ if (i < (c-1)) {
+ B = Clipperz.Crypto.ECC.BinaryField.Value._overwriteShiftLeft(B, 1);
+ }
+ }
+ result = this._module(result);
+
+ return result;
+ },
+
+ 'fastMultiply': function(a, b) {
+ return new Clipperz.Crypto.ECC.BinaryField.Value(this._fastMultiply(a._value, b._value));
+ },
+
+ //-----------------------------------------------------------------------------
+ //
+ // Guide to Elliptic Curve Cryptography
+ // Darrel Hankerson, Alfred Menezes, Scott Vanstone
+ // - Pag: 49, Alorithm 2.34
+ //
+ //-----------------------------------------------------------------------------
+
+ '_square': function(aValue) {
+ var result;
+ var value;
+ var c,i;
+ var precomputedValues;
+
+ value = aValue;
+ result = new Array(value.length * 2);
+ precomputedValues = Clipperz.Crypto.ECC.BinaryField.FiniteField.squarePrecomputedBytes;
+
+ c = value.length;
+ for (i=0; i<c; i++) {
+ result[i*2] = precomputedValues[(value[i] & 0x000000ff)];
+ result[i*2] |= ((precomputedValues[(value[i] & 0x0000ff00) >>> 8]) << 16);
+
+ result[i*2 + 1] = precomputedValues[(value[i] & 0x00ff0000) >>> 16];
+ result[i*2 + 1] |= ((precomputedValues[(value[i] & 0xff000000) >>> 24]) << 16);
+ }
+
+ return this._module(result);
+ },
+
+ 'square': function(aValue) {
+ return new Clipperz.Crypto.ECC.BinaryField.Value(this._square(aValue._value));
+ },
+
+ //-----------------------------------------------------------------------------
+
+ '_inverse': function(aValue) {
+ var result;
+ var b, c;
+ var u, v;
+
+// b = Clipperz.Crypto.ECC.BinaryField.Value.I._value;
+ b = [1];
+// c = Clipperz.Crypto.ECC.BinaryField.Value.O._value;
+ c = [0];
+ u = this._module(aValue);
+ v = this.modulus()._value.slice(0);
+
+ while (Clipperz.Crypto.ECC.BinaryField.Value._bitSize(u) > 1) {
+ var bitDifferenceSize;
+
+ bitDifferenceSize = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(u) - Clipperz.Crypto.ECC.BinaryField.Value._bitSize(v);
+ if (bitDifferenceSize < 0) {
+ var swap;
+
+ swap = u;
+ u = v;
+ v = swap;
+
+ swap = c;
+ c = b;
+ b = swap;
+
+ bitDifferenceSize = -bitDifferenceSize;
+ }
+
+ u = this._add(u, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(v, bitDifferenceSize));
+ b = this._add(b, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(c, bitDifferenceSize));
+// this._overwriteAdd(u, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(v, bitDifferenceSize));
+// this._overwriteAdd(b, Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(c, bitDifferenceSize));
+ }
+
+ result = this._module(b);
+
+ return result;
+ },
+
+ 'inverse': function(aValue) {
+ return new Clipperz.Crypto.ECC.BinaryField.Value(this._inverse(aValue._value));
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+
+Clipperz.Crypto.ECC.BinaryField.FiniteField.squarePrecomputedBytes = [
+ 0x0000, // 0 = 0000 0000 -> 0000 0000 0000 0000
+ 0x0001, // 1 = 0000 0001 -> 0000 0000 0000 0001
+ 0x0004, // 2 = 0000 0010 -> 0000 0000 0000 0100
+ 0x0005, // 3 = 0000 0011 -> 0000 0000 0000 0101
+ 0x0010, // 4 = 0000 0100 -> 0000 0000 0001 0000
+ 0x0011, // 5 = 0000 0101 -> 0000 0000 0001 0001
+ 0x0014, // 6 = 0000 0110 -> 0000 0000 0001 0100
+ 0x0015, // 7 = 0000 0111 -> 0000 0000 0001 0101
+ 0x0040, // 8 = 0000 1000 -> 0000 0000 0100 0000
+ 0x0041, // 9 = 0000 1001 -> 0000 0000 0100 0001
+ 0x0044, // 10 = 0000 1010 -> 0000 0000 0100 0100
+ 0x0045, // 11 = 0000 1011 -> 0000 0000 0100 0101
+ 0x0050, // 12 = 0000 1100 -> 0000 0000 0101 0000
+ 0x0051, // 13 = 0000 1101 -> 0000 0000 0101 0001
+ 0x0054, // 14 = 0000 1110 -> 0000 0000 0101 0100
+ 0x0055, // 15 = 0000 1111 -> 0000 0000 0101 0101
+
+ 0x0100, // 16 = 0001 0000 -> 0000 0001 0000 0000
+ 0x0101, // 17 = 0001 0001 -> 0000 0001 0000 0001
+ 0x0104, // 18 = 0001 0010 -> 0000 0001 0000 0100
+ 0x0105, // 19 = 0001 0011 -> 0000 0001 0000 0101
+ 0x0110, // 20 = 0001 0100 -> 0000 0001 0001 0000
+ 0x0111, // 21 = 0001 0101 -> 0000 0001 0001 0001
+ 0x0114, // 22 = 0001 0110 -> 0000 0001 0001 0100
+ 0x0115, // 23 = 0001 0111 -> 0000 0001 0001 0101
+ 0x0140, // 24 = 0001 1000 -> 0000 0001 0100 0000
+ 0x0141, // 25 = 0001 1001 -> 0000 0001 0100 0001
+ 0x0144, // 26 = 0001 1010 -> 0000 0001 0100 0100
+ 0x0145, // 27 = 0001 1011 -> 0000 0001 0100 0101
+ 0x0150, // 28 = 0001 1100 -> 0000 0001 0101 0000
+ 0x0151, // 28 = 0001 1101 -> 0000 0001 0101 0001
+ 0x0154, // 30 = 0001 1110 -> 0000 0001 0101 0100
+ 0x0155, // 31 = 0001 1111 -> 0000 0001 0101 0101
+
+ 0x0400, // 32 = 0010 0000 -> 0000 0100 0000 0000
+ 0x0401, // 33 = 0010 0001 -> 0000 0100 0000 0001
+ 0x0404, // 34 = 0010 0010 -> 0000 0100 0000 0100
+ 0x0405, // 35 = 0010 0011 -> 0000 0100 0000 0101
+ 0x0410, // 36 = 0010 0100 -> 0000 0100 0001 0000
+ 0x0411, // 37 = 0010 0101 -> 0000 0100 0001 0001
+ 0x0414, // 38 = 0010 0110 -> 0000 0100 0001 0100
+ 0x0415, // 39 = 0010 0111 -> 0000 0100 0001 0101
+ 0x0440, // 40 = 0010 1000 -> 0000 0100 0100 0000
+ 0x0441, // 41 = 0010 1001 -> 0000 0100 0100 0001
+ 0x0444, // 42 = 0010 1010 -> 0000 0100 0100 0100
+ 0x0445, // 43 = 0010 1011 -> 0000 0100 0100 0101
+ 0x0450, // 44 = 0010 1100 -> 0000 0100 0101 0000
+ 0x0451, // 45 = 0010 1101 -> 0000 0100 0101 0001
+ 0x0454, // 46 = 0010 1110 -> 0000 0100 0101 0100
+ 0x0455, // 47 = 0010 1111 -> 0000 0100 0101 0101
+
+ 0x0500, // 48 = 0011 0000 -> 0000 0101 0000 0000
+ 0x0501, // 49 = 0011 0001 -> 0000 0101 0000 0001
+ 0x0504, // 50 = 0011 0010 -> 0000 0101 0000 0100
+ 0x0505, // 51 = 0011 0011 -> 0000 0101 0000 0101
+ 0x0510, // 52 = 0011 0100 -> 0000 0101 0001 0000
+ 0x0511, // 53 = 0011 0101 -> 0000 0101 0001 0001
+ 0x0514, // 54 = 0011 0110 -> 0000 0101 0001 0100
+ 0x0515, // 55 = 0011 0111 -> 0000 0101 0001 0101
+ 0x0540, // 56 = 0011 1000 -> 0000 0101 0100 0000
+ 0x0541, // 57 = 0011 1001 -> 0000 0101 0100 0001
+ 0x0544, // 58 = 0011 1010 -> 0000 0101 0100 0100
+ 0x0545, // 59 = 0011 1011 -> 0000 0101 0100 0101
+ 0x0550, // 60 = 0011 1100 -> 0000 0101 0101 0000
+ 0x0551, // 61 = 0011 1101 -> 0000 0101 0101 0001
+ 0x0554, // 62 = 0011 1110 -> 0000 0101 0101 0100
+ 0x0555, // 63 = 0011 1111 -> 0000 0101 0101 0101
+
+ 0x1000, // 64 = 0100 0000 -> 0001 0000 0000 0000
+ 0x1001, // 65 = 0100 0001 -> 0001 0000 0000 0001
+ 0x1004, // 66 = 0100 0010 -> 0001 0000 0000 0100
+ 0x1005, // 67 = 0100 0011 -> 0001 0000 0000 0101
+ 0x1010, // 68 = 0100 0100 -> 0001 0000 0001 0000
+ 0x1011, // 69 = 0100 0101 -> 0001 0000 0001 0001
+ 0x1014, // 70 = 0100 0110 -> 0001 0000 0001 0100
+ 0x1015, // 71 = 0100 0111 -> 0001 0000 0001 0101
+ 0x1040, // 72 = 0100 1000 -> 0001 0000 0100 0000
+ 0x1041, // 73 = 0100 1001 -> 0001 0000 0100 0001
+ 0x1044, // 74 = 0100 1010 -> 0001 0000 0100 0100
+ 0x1045, // 75 = 0100 1011 -> 0001 0000 0100 0101
+ 0x1050, // 76 = 0100 1100 -> 0001 0000 0101 0000
+ 0x1051, // 77 = 0100 1101 -> 0001 0000 0101 0001
+ 0x1054, // 78 = 0100 1110 -> 0001 0000 0101 0100
+ 0x1055, // 79 = 0100 1111 -> 0001 0000 0101 0101
+
+ 0x1100, // 80 = 0101 0000 -> 0001 0001 0000 0000
+ 0x1101, // 81 = 0101 0001 -> 0001 0001 0000 0001
+ 0x1104, // 82 = 0101 0010 -> 0001 0001 0000 0100
+ 0x1105, // 83 = 0101 0011 -> 0001 0001 0000 0101
+ 0x1110, // 84 = 0101 0100 -> 0001 0001 0001 0000
+ 0x1111, // 85 = 0101 0101 -> 0001 0001 0001 0001
+ 0x1114, // 86 = 0101 0110 -> 0001 0001 0001 0100
+ 0x1115, // 87 = 0101 0111 -> 0001 0001 0001 0101
+ 0x1140, // 88 = 0101 1000 -> 0001 0001 0100 0000
+ 0x1141, // 89 = 0101 1001 -> 0001 0001 0100 0001
+ 0x1144, // 90 = 0101 1010 -> 0001 0001 0100 0100
+ 0x1145, // 91 = 0101 1011 -> 0001 0001 0100 0101
+ 0x1150, // 92 = 0101 1100 -> 0001 0001 0101 0000
+ 0x1151, // 93 = 0101 1101 -> 0001 0001 0101 0001
+ 0x1154, // 94 = 0101 1110 -> 0001 0001 0101 0100
+ 0x1155, // 95 = 0101 1111 -> 0001 0001 0101 0101
+
+ 0x1400, // 96 = 0110 0000 -> 0001 0100 0000 0000
+ 0x1401, // 97 = 0110 0001 -> 0001 0100 0000 0001
+ 0x1404, // 98 = 0110 0010 -> 0001 0100 0000 0100
+ 0x1405, // 99 = 0110 0011 -> 0001 0100 0000 0101
+ 0x1410, // 100 = 0110 0100 -> 0001 0100 0001 0000
+ 0x1411, // 101 = 0110 0101 -> 0001 0100 0001 0001
+ 0x1414, // 102 = 0110 0110 -> 0001 0100 0001 0100
+ 0x1415, // 103 = 0110 0111 -> 0001 0100 0001 0101
+ 0x1440, // 104 = 0110 1000 -> 0001 0100 0100 0000
+ 0x1441, // 105 = 0110 1001 -> 0001 0100 0100 0001
+ 0x1444, // 106 = 0110 1010 -> 0001 0100 0100 0100
+ 0x1445, // 107 = 0110 1011 -> 0001 0100 0100 0101
+ 0x1450, // 108 = 0110 1100 -> 0001 0100 0101 0000
+ 0x1451, // 109 = 0110 1101 -> 0001 0100 0101 0001
+ 0x1454, // 110 = 0110 1110 -> 0001 0100 0101 0100
+ 0x1455, // 111 = 0110 1111 -> 0001 0100 0101 0101
+
+ 0x1500, // 112 = 0111 0000 -> 0001 0101 0000 0000
+ 0x1501, // 113 = 0111 0001 -> 0001 0101 0000 0001
+ 0x1504, // 114 = 0111 0010 -> 0001 0101 0000 0100
+ 0x1505, // 115 = 0111 0011 -> 0001 0101 0000 0101
+ 0x1510, // 116 = 0111 0100 -> 0001 0101 0001 0000
+ 0x1511, // 117 = 0111 0101 -> 0001 0101 0001 0001
+ 0x1514, // 118 = 0111 0110 -> 0001 0101 0001 0100
+ 0x1515, // 119 = 0111 0111 -> 0001 0101 0001 0101
+ 0x1540, // 120 = 0111 1000 -> 0001 0101 0100 0000
+ 0x1541, // 121 = 0111 1001 -> 0001 0101 0100 0001
+ 0x1544, // 122 = 0111 1010 -> 0001 0101 0100 0100
+ 0x1545, // 123 = 0111 1011 -> 0001 0101 0100 0101
+ 0x1550, // 124 = 0111 1100 -> 0001 0101 0101 0000
+ 0x1551, // 125 = 0111 1101 -> 0001 0101 0101 0001
+ 0x1554, // 126 = 0111 1110 -> 0001 0101 0101 0100
+ 0x1555, // 127 = 0111 1111 -> 0001 0101 0101 0101
+
+ 0x4000, // 128 = 1000 0000 -> 0100 0000 0000 0000
+ 0x4001, // 129 = 1000 0001 -> 0100 0000 0000 0001
+ 0x4004, // 130 = 1000 0010 -> 0100 0000 0000 0100
+ 0x4005, // 131 = 1000 0011 -> 0100 0000 0000 0101
+ 0x4010, // 132 = 1000 0100 -> 0100 0000 0001 0000
+ 0x4011, // 133 = 1000 0101 -> 0100 0000 0001 0001
+ 0x4014, // 134 = 1000 0110 -> 0100 0000 0001 0100
+ 0x4015, // 135 = 1000 0111 -> 0100 0000 0001 0101
+ 0x4040, // 136 = 1000 1000 -> 0100 0000 0100 0000
+ 0x4041, // 137 = 1000 1001 -> 0100 0000 0100 0001
+ 0x4044, // 138 = 1000 1010 -> 0100 0000 0100 0100
+ 0x4045, // 139 = 1000 1011 -> 0100 0000 0100 0101
+ 0x4050, // 140 = 1000 1100 -> 0100 0000 0101 0000
+ 0x4051, // 141 = 1000 1101 -> 0100 0000 0101 0001
+ 0x4054, // 142 = 1000 1110 -> 0100 0000 0101 0100
+ 0x4055, // 143 = 1000 1111 -> 0100 0000 0101 0101
+
+ 0x4100, // 144 = 1001 0000 -> 0100 0001 0000 0000
+ 0x4101, // 145 = 1001 0001 -> 0100 0001 0000 0001
+ 0x4104, // 146 = 1001 0010 -> 0100 0001 0000 0100
+ 0x4105, // 147 = 1001 0011 -> 0100 0001 0000 0101
+ 0x4110, // 148 = 1001 0100 -> 0100 0001 0001 0000
+ 0x4111, // 149 = 1001 0101 -> 0100 0001 0001 0001
+ 0x4114, // 150 = 1001 0110 -> 0100 0001 0001 0100
+ 0x4115, // 151 = 1001 0111 -> 0100 0001 0001 0101
+ 0x4140, // 152 = 1001 1000 -> 0100 0001 0100 0000
+ 0x4141, // 153 = 1001 1001 -> 0100 0001 0100 0001
+ 0x4144, // 154 = 1001 1010 -> 0100 0001 0100 0100
+ 0x4145, // 155 = 1001 1011 -> 0100 0001 0100 0101
+ 0x4150, // 156 = 1001 1100 -> 0100 0001 0101 0000
+ 0x4151, // 157 = 1001 1101 -> 0100 0001 0101 0001
+ 0x4154, // 158 = 1001 1110 -> 0100 0001 0101 0100
+ 0x4155, // 159 = 1001 1111 -> 0100 0001 0101 0101
+
+ 0x4400, // 160 = 1010 0000 -> 0100 0100 0000 0000
+ 0x4401, // 161 = 1010 0001 -> 0100 0100 0000 0001
+ 0x4404, // 162 = 1010 0010 -> 0100 0100 0000 0100
+ 0x4405, // 163 = 1010 0011 -> 0100 0100 0000 0101
+ 0x4410, // 164 = 1010 0100 -> 0100 0100 0001 0000
+ 0x4411, // 165 = 1010 0101 -> 0100 0100 0001 0001
+ 0x4414, // 166 = 1010 0110 -> 0100 0100 0001 0100
+ 0x4415, // 167 = 1010 0111 -> 0100 0100 0001 0101
+ 0x4440, // 168 = 1010 1000 -> 0100 0100 0100 0000
+ 0x4441, // 169 = 1010 1001 -> 0100 0100 0100 0001
+ 0x4444, // 170 = 1010 1010 -> 0100 0100 0100 0100
+ 0x4445, // 171 = 1010 1011 -> 0100 0100 0100 0101
+ 0x4450, // 172 = 1010 1100 -> 0100 0100 0101 0000
+ 0x4451, // 173 = 1010 1101 -> 0100 0100 0101 0001
+ 0x4454, // 174 = 1010 1110 -> 0100 0100 0101 0100
+ 0x4455, // 175 = 1010 1111 -> 0100 0100 0101 0101
+
+ 0x4500, // 176 = 1011 0000 -> 0100 0101 0000 0000
+ 0x4501, // 177 = 1011 0001 -> 0100 0101 0000 0001
+ 0x4504, // 178 = 1011 0010 -> 0100 0101 0000 0100
+ 0x4505, // 179 = 1011 0011 -> 0100 0101 0000 0101
+ 0x4510, // 180 = 1011 0100 -> 0100 0101 0001 0000
+ 0x4511, // 181 = 1011 0101 -> 0100 0101 0001 0001
+ 0x4514, // 182 = 1011 0110 -> 0100 0101 0001 0100
+ 0x4515, // 183 = 1011 0111 -> 0100 0101 0001 0101
+ 0x4540, // 184 = 1011 1000 -> 0100 0101 0100 0000
+ 0x4541, // 185 = 1011 1001 -> 0100 0101 0100 0001
+ 0x4544, // 186 = 1011 1010 -> 0100 0101 0100 0100
+ 0x4545, // 187 = 1011 1011 -> 0100 0101 0100 0101
+ 0x4550, // 188 = 1011 1100 -> 0100 0101 0101 0000
+ 0x4551, // 189 = 1011 1101 -> 0100 0101 0101 0001
+ 0x4554, // 190 = 1011 1110 -> 0100 0101 0101 0100
+ 0x4555, // 191 = 1011 1111 -> 0100 0101 0101 0101
+
+ 0x5000, // 192 = 1100 0000 -> 0101 0000 0000 0000
+ 0x5001, // 193 = 1100 0001 -> 0101 0000 0000 0001
+ 0x5004, // 194 = 1100 0010 -> 0101 0000 0000 0100
+ 0x5005, // 195 = 1100 0011 -> 0101 0000 0000 0101
+ 0x5010, // 196 = 1100 0100 -> 0101 0000 0001 0000
+ 0x5011, // 197 = 1100 0101 -> 0101 0000 0001 0001
+ 0x5014, // 198 = 1100 0110 -> 0101 0000 0001 0100
+ 0x5015, // 199 = 1100 0111 -> 0101 0000 0001 0101
+ 0x5040, // 200 = 1100 1000 -> 0101 0000 0100 0000
+ 0x5041, // 201 = 1100 1001 -> 0101 0000 0100 0001
+ 0x5044, // 202 = 1100 1010 -> 0101 0000 0100 0100
+ 0x5045, // 203 = 1100 1011 -> 0101 0000 0100 0101
+ 0x5050, // 204 = 1100 1100 -> 0101 0000 0101 0000
+ 0x5051, // 205 = 1100 1101 -> 0101 0000 0101 0001
+ 0x5054, // 206 = 1100 1110 -> 0101 0000 0101 0100
+ 0x5055, // 207 = 1100 1111 -> 0101 0000 0101 0101
+
+ 0x5100, // 208 = 1101 0000 -> 0101 0001 0000 0000
+ 0x5101, // 209 = 1101 0001 -> 0101 0001 0000 0001
+ 0x5104, // 210 = 1101 0010 -> 0101 0001 0000 0100
+ 0x5105, // 211 = 1101 0011 -> 0101 0001 0000 0101
+ 0x5110, // 212 = 1101 0100 -> 0101 0001 0001 0000
+ 0x5111, // 213 = 1101 0101 -> 0101 0001 0001 0001
+ 0x5114, // 214 = 1101 0110 -> 0101 0001 0001 0100
+ 0x5115, // 215 = 1101 0111 -> 0101 0001 0001 0101
+ 0x5140, // 216 = 1101 1000 -> 0101 0001 0100 0000
+ 0x5141, // 217 = 1101 1001 -> 0101 0001 0100 0001
+ 0x5144, // 218 = 1101 1010 -> 0101 0001 0100 0100
+ 0x5145, // 219 = 1101 1011 -> 0101 0001 0100 0101
+ 0x5150, // 220 = 1101 1100 -> 0101 0001 0101 0000
+ 0x5151, // 221 = 1101 1101 -> 0101 0001 0101 0001
+ 0x5154, // 222 = 1101 1110 -> 0101 0001 0101 0100
+ 0x5155, // 223 = 1101 1111 -> 0101 0001 0101 0101
+
+ 0x5400, // 224 = 1110 0000 -> 0101 0100 0000 0000
+ 0x5401, // 225 = 1110 0001 -> 0101 0100 0000 0001
+ 0x5404, // 226 = 1110 0010 -> 0101 0100 0000 0100
+ 0x5405, // 227 = 1110 0011 -> 0101 0100 0000 0101
+ 0x5410, // 228 = 1110 0100 -> 0101 0100 0001 0000
+ 0x5411, // 229 = 1110 0101 -> 0101 0100 0001 0001
+ 0x5414, // 230 = 1110 0110 -> 0101 0100 0001 0100
+ 0x5415, // 231 = 1110 0111 -> 0101 0100 0001 0101
+ 0x5440, // 232 = 1110 1000 -> 0101 0100 0100 0000
+ 0x5441, // 233 = 1110 1001 -> 0101 0100 0100 0001
+ 0x5444, // 234 = 1110 1010 -> 0101 0100 0100 0100
+ 0x5445, // 235 = 1110 1011 -> 0101 0100 0100 0101
+ 0x5450, // 236 = 1110 1100 -> 0101 0100 0101 0000
+ 0x5451, // 237 = 1110 1101 -> 0101 0100 0101 0001
+ 0x5454, // 238 = 1110 1110 -> 0101 0100 0101 0100
+ 0x5455, // 239 = 1110 1111 -> 0101 0100 0101 0101
+
+ 0x5500, // 240 = 1111 0000 -> 0101 0101 0000 0000
+ 0x5501, // 241 = 1111 0001 -> 0101 0101 0000 0001
+ 0x5504, // 242 = 1111 0010 -> 0101 0101 0000 0100
+ 0x5505, // 243 = 1111 0011 -> 0101 0101 0000 0101
+ 0x5510, // 244 = 1111 0100 -> 0101 0101 0001 0000
+ 0x5511, // 245 = 1111 0101 -> 0101 0101 0001 0001
+ 0x5514, // 246 = 1111 0110 -> 0101 0101 0001 0100
+ 0x5515, // 247 = 1111 0111 -> 0101 0101 0001 0101
+ 0x5540, // 248 = 1111 1000 -> 0101 0101 0100 0000
+ 0x5541, // 249 = 1111 1001 -> 0101 0101 0100 0001
+ 0x5544, // 250 = 1111 1010 -> 0101 0101 0100 0100
+ 0x5545, // 251 = 1111 1011 -> 0101 0101 0100 0101
+ 0x5550, // 252 = 1111 1100 -> 0101 0101 0101 0000
+ 0x5551, // 253 = 1111 1101 -> 0101 0101 0101 0001
+ 0x5554, // 254 = 1111 1110 -> 0101 0101 0101 0100
+ 0x5555 // 255 = 1111 1111 -> 0101 0101 0101 0101
+
+]
diff --git a/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Point.js b/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Point.js
new file mode 100644
index 0000000..b7a5537
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Point.js
@@ -0,0 +1,67 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
+// throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!";
+//}
+if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; }
+if (typeof(Clipperz.Crypto.ECC.BinaryField) == 'undefined') { Clipperz.Crypto.ECC.BinaryField = {}; }
+
+Clipperz.Crypto.ECC.BinaryField.Point = function(args) {
+ args = args || {};
+ this._x = args.x;
+ this._y = args.y;
+
+ return this;
+}
+
+Clipperz.Crypto.ECC.BinaryField.Point.prototype = MochiKit.Base.update(null, {
+
+ 'asString': function() {
+ return "Clipperz.Crypto.ECC.BinaryField.Point (" + this.x() + ", " + this.y() + ")";
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'x': function() {
+ return this._x;
+ },
+
+ 'y': function() {
+ return this._y;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'isZero': function() {
+ return (this.x().isZero() && this.y().isZero())
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Value.js b/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Value.js
new file mode 100644
index 0000000..5a430d1
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/ECC/BinaryField/Value.js
@@ -0,0 +1,386 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
+// throw "Clipperz.Crypto.ECC depends on Clipperz.ByteArray!";
+//}
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
+if (typeof(Clipperz.Crypto.ECC) == 'undefined') { Clipperz.Crypto.ECC = {}; }
+if (typeof(Clipperz.Crypto.ECC.BinaryField) == 'undefined') { Clipperz.Crypto.ECC.BinaryField = {}; }
+
+Clipperz.Crypto.ECC.BinaryField.Value = function(aValue, aBase, aBitSize) {
+ if (aValue.constructor == String) {
+ var value;
+ var stringLength;
+ var numberOfWords;
+ var i,c;
+
+ if (aBase != 16) {
+ throw Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedBase;
+ }
+
+ value = aValue.replace(/ /g, '');
+ stringLength = value.length;
+ numberOfWords = Math.ceil(stringLength / 8);
+ this._value = new Array(numberOfWords);
+
+ c = numberOfWords;
+ for (i=0; i<c; i++) {
+ var word;
+
+ if (i < (c-1)) {
+ word = parseInt(value.substr(stringLength-((i+1)*8), 8), 16);
+ } else {
+ word = parseInt(value.substr(0, stringLength-(i*8)), 16);
+ }
+
+ this._value[i] = word;
+ }
+ } else if (aValue.constructor == Array) {
+ var itemsToCopy;
+
+ itemsToCopy = aValue.length;
+ while (aValue[itemsToCopy - 1] == 0) {
+ itemsToCopy --;
+ }
+
+ this._value = aValue.slice(0, itemsToCopy);
+ } else if (aValue.constructor == Number) {
+ this._value = [aValue];
+ } else {
+// throw Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedConstructorValueType;
+ }
+
+ this._bitSize == aBitSize || null;
+
+ return this;
+}
+
+Clipperz.Crypto.ECC.BinaryField.Value.prototype = MochiKit.Base.update(null, {
+
+ 'value': function() {
+ return this._value;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'wordSize': function() {
+ return this._value.length
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'clone': function() {
+ return new Clipperz.Crypto.ECC.BinaryField.Value(this._value.slice(0), null, this._bitSize);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'isZero': function() {
+ return (this.compare(Clipperz.Crypto.ECC.BinaryField.Value.O) == 0);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'asString': function(aBase) {
+ var result;
+ var i,c;
+
+ if (aBase != 16) {
+ throw Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedBase;
+ }
+
+ result = "";
+ c = this.wordSize();
+ for (i=0; i<c; i++) {
+ var wordAsString;
+
+// wordAsString = ("00000000" + this.value()[i].toString(16));
+ wordAsString = ("00000000" + this._value[i].toString(16));
+ wordAsString = wordAsString.substring(wordAsString.length - 8);
+ result = wordAsString + result;
+ }
+
+ result = result.replace(/^(00)*/, "");
+
+ if (result == "") {
+ result = "0";
+ }
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'shiftLeft': function(aNumberOfBitsToShift) {
+ // this method seems like it is never called. :-(
+ return new Clipperz.Crypto.ECC.BinaryField.Value(Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft(this._value, aNumberOfBitsToShift));
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'bitSize': function() {
+ if (this._bitSize == null) {
+ this._bitSize = Clipperz.Crypto.ECC.BinaryField.Value._bitSize(this._value);
+ }
+
+ return this._bitSize;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'isBitSet': function(aBitPosition) {
+ return Clipperz.Crypto.ECC.BinaryField.Value._isBitSet(this._value, aBitPosition);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'xor': function(aValue) {
+ return new Clipperz.Crypto.ECC.BinaryField.Value(Clipperz.Crypto.ECC.BinaryField.Value._xor(this._value, aValue._value));
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'compare': function(aValue) {
+ return Clipperz.Crypto.ECC.BinaryField.Value._compare(this._value, aValue._value);
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+Clipperz.Crypto.ECC.BinaryField.Value.O = new Clipperz.Crypto.ECC.BinaryField.Value('0', 16);
+Clipperz.Crypto.ECC.BinaryField.Value.I = new Clipperz.Crypto.ECC.BinaryField.Value('1', 16);
+
+Clipperz.Crypto.ECC.BinaryField.Value._xor = function(a, b, aFirstItemOffset) {
+ var result;
+ var resultSize;
+ var i,c;
+ var firstItemOffset;
+
+ firstItemOffset = aFirstItemOffset || 0;
+ resultSize = Math.max((a.length - firstItemOffset), b.length) + firstItemOffset;
+
+ result = new Array(resultSize);
+
+ c = firstItemOffset;
+ for (i=0; i<c; i++) {
+ result[i] = a[i];
+ }
+
+ c = resultSize;
+ for (i=firstItemOffset; i<c; i++) {
+ result[i] = (((a[i] || 0) ^ (b[i - firstItemOffset] || 0)) >>> 0);
+ }
+
+ return result;
+};
+
+Clipperz.Crypto.ECC.BinaryField.Value._overwriteXor = function(a, b, aFirstItemOffset) {
+ var i,c;
+ var firstItemOffset;
+
+ firstItemOffset = aFirstItemOffset || 0;
+
+ c = Math.max((a.length - firstItemOffset), b.length) + firstItemOffset;
+ for (i=firstItemOffset; i<c; i++) {
+ a[i] = (((a[i] || 0) ^ (b[i - firstItemOffset] || 0)) >>> 0);
+ }
+};
+
+Clipperz.Crypto.ECC.BinaryField.Value._shiftLeft = function(aWordArray, aNumberOfBitsToShift) {
+ var numberOfWordsToShift;
+ var numberOfBitsToShift;
+ var result;
+ var overflowValue;
+ var nextOverflowValue;
+ var i,c;
+
+ numberOfWordsToShift = Math.floor(aNumberOfBitsToShift / 32);
+ numberOfBitsToShift = aNumberOfBitsToShift % 32;
+
+ result = new Array(aWordArray.length + numberOfWordsToShift);
+
+ c = numberOfWordsToShift;
+ for (i=0; i<c; i++) {
+ result[i] = 0;
+ }
+
+ overflowValue = 0;
+ nextOverflowValue = 0;
+
+ c = aWordArray.length;
+ for (i=0; i<c; i++) {
+ var value;
+ var resultWord;
+
+// value = this.value()[i];
+ value = aWordArray[i];
+
+ if (numberOfBitsToShift > 0) {
+ nextOverflowValue = (value >>> (32 - numberOfBitsToShift));
+ value = value & (0xffffffff >>> numberOfBitsToShift);
+ resultWord = (((value << numberOfBitsToShift) | overflowValue) >>> 0);
+ } else {
+ resultWord = value;
+ }
+
+ result[i+numberOfWordsToShift] = resultWord;
+ overflowValue = nextOverflowValue;
+ }
+
+ if (overflowValue != 0) {
+ result[aWordArray.length + numberOfWordsToShift] = overflowValue;
+ }
+
+ return result;
+};
+
+Clipperz.Crypto.ECC.BinaryField.Value._overwriteShiftLeft = function(aWordArray, aNumberOfBitsToShift) {
+ var numberOfWordsToShift;
+ var numberOfBitsToShift;
+ var result;
+ var overflowValue;
+ var i,c;
+
+ numberOfWordsToShift = Math.floor(aNumberOfBitsToShift / 32);
+ numberOfBitsToShift = aNumberOfBitsToShift % 32;
+
+ result = new Array(aWordArray.length + numberOfWordsToShift);
+
+ c = numberOfWordsToShift;
+ for (i=0; i<c; i++) {
+ result[i] = 0;
+ }
+
+ overflowValue = 0;
+ nextOverflowValue = 0;
+
+ c = aWordArray.length;
+ for (i=0; i<c; i++) {
+ var value;
+ var resultWord;
+
+// value = this.value()[i];
+ value = aWordArray[i];
+
+ if (numberOfBitsToShift > 0) {
+ var nextOverflowValue;
+
+ nextOverflowValue = (value >>> (32 - numberOfBitsToShift));
+ value = value & (0xffffffff >>> numberOfBitsToShift);
+ resultWord = (((value << numberOfBitsToShift) | overflowValue) >>> 0);
+ } else {
+ resultWord = value;
+ }
+
+ result[i+numberOfWordsToShift] = resultWord;
+ overflowValue = nextOverflowValue;
+ }
+
+ if (overflowValue != 0) {
+ result[aWordArray.length + numberOfWordsToShift] = overflowValue;
+ }
+
+ return result;
+};
+
+Clipperz.Crypto.ECC.BinaryField.Value._bitSize = function(aWordArray) {
+ var result;
+ var notNullElements;
+ var mostValuableWord;
+ var matchingBitsInMostImportantWord;
+ var mask;
+ var i,c;
+
+ notNullElements = aWordArray.length;
+
+ if ((aWordArray.length == 1) && (aWordArray[0] == 0)) {
+ result = 0;
+ } else {
+ notNullElements --;
+ while((notNullElements > 0) && (aWordArray[notNullElements] == 0)) {
+ notNullElements --;
+ }
+
+ result = notNullElements * 32;
+ mostValuableWord = aWordArray[notNullElements];
+
+ matchingBits = 32;
+ mask = 0x80000000;
+
+ while ((matchingBits > 0) && ((mostValuableWord & mask) == 0)) {
+ matchingBits --;
+ mask >>>= 1;
+ }
+
+ result += matchingBits;
+ }
+
+ return result;
+};
+
+Clipperz.Crypto.ECC.BinaryField.Value._isBitSet = function(aWordArray, aBitPosition) {
+ var result;
+ var byteIndex;
+ var bitIndexInSelectedByte;
+
+ byteIndex = Math.floor(aBitPosition / 32);
+ bitIndexInSelectedByte = aBitPosition % 32;
+
+ if (byteIndex <= aWordArray.length) {
+ result = ((aWordArray[byteIndex] & (1 << bitIndexInSelectedByte)) != 0);
+ } else {
+ result = false;
+ }
+
+ return result;
+};
+
+Clipperz.Crypto.ECC.BinaryField.Value._compare = function(a,b) {
+ var result;
+ var i,c;
+
+ result = MochiKit.Base.compare(a.length, b.length);
+
+ c = a.length;
+ for (i=0; (i<c) && (result==0); i++) {
+//console.log("compare[" + c + " - " + i + " - 1] " + this.value()[c-i-1] + ", " + aValue.value()[c-i-1]);
+// result = MochiKit.Base.compare(this.value()[c-i-1], aValue.value()[c-i-1]);
+ result = MochiKit.Base.compare(a[c-i-1], b[c-i-1]);
+ }
+
+ return result;
+};
+
+
+Clipperz.Crypto.ECC.BinaryField.Value['exception']= {
+ 'UnsupportedBase': new MochiKit.Base.NamedError("Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedBase"),
+ 'UnsupportedConstructorValueType': new MochiKit.Base.NamedError("Clipperz.Crypto.ECC.BinaryField.Value.exception.UnsupportedConstructorValueType")
+};
diff --git a/frontend/gamma/js/Clipperz/Crypto/ECC/StandardCurves.js b/frontend/gamma/js/Clipperz/Crypto/ECC/StandardCurves.js
new file mode 100644
index 0000000..ae2b8fb
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/ECC/StandardCurves.js
@@ -0,0 +1,239 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//try { if (typeof(Clipperz.Crypto.ECC.BinaryField.Curve) == 'undefined') { throw ""; }} catch (e) {
+// throw "Clipperz.Crypto.ECC depends on Clipperz.Crypto.ECC.BinaryField.Curve!";
+//}
+//try { if (typeof(Clipperz.Crypto.ECC.Koblitz.Curve) == 'undefined') { throw ""; }} catch (e) {
+// throw "Clipperz.Crypto.ECC depends on Clipperz.Crypto.ECC.Koblitz.Curve!";
+//}
+
+Clipperz.Crypto.ECC.StandardCurves = {};
+
+MochiKit.Base.update(Clipperz.Crypto.ECC.StandardCurves, {
+
+ //==============================================================================
+
+ '_K571': null,
+ 'K571': function() { // f(z) = z^571 + z^10 + z^5 + z^2 + 1
+ if ((Clipperz.Crypto.ECC.StandardCurves._K571 == null) && (typeof(Clipperz.Crypto.ECC.Koblitz.Curve) != 'undefined')) {
+ Clipperz.Crypto.ECC.StandardCurves._K571 = new Clipperz.Crypto.ECC.Koblitz.Curve({
+ modulus: new Clipperz.Crypto.ECC.Koblitz.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000425', 16),
+ a: new Clipperz.Crypto.ECC.Koblitz.Value('0', 16),
+ b: new Clipperz.Crypto.ECC.Koblitz.Value('1', 16),
+ G: new Clipperz.Crypto.ECC.Koblitz.Point({
+ x: new Clipperz.Crypto.ECC.Koblitz.Value('026eb7a8 59923fbc 82189631 f8103fe4 ac9ca297 0012d5d4 60248048 01841ca4 43709584 93b205e6 47da304d b4ceb08c bbd1ba39 494776fb 988b4717 4dca88c7 e2945283 a01c8972', 16),
+ y: new Clipperz.Crypto.ECC.Koblitz.Value('0349dc80 7f4fbf37 4f4aeade 3bca9531 4dd58cec 9f307a54 ffc61efc 006d8a2c 9d4979c0 ac44aea7 4fbebbb9 f772aedc b620b01a 7ba7af1b 320430c8 591984f6 01cd4c14 3ef1c7a3', 16)
+ }),
+ r: new Clipperz.Crypto.ECC.Koblitz.Value('02000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 131850e1 f19a63e4 b391a8db 917f4138 b630d84b e5d63938 1e91deb4 5cfe778f 637c1001', 16),
+ h: new Clipperz.Crypto.ECC.Koblitz.Value('4', 16),
+ primeFactor: new Clipperz.Crypto.ECC.Koblitz.Value('02000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 131850e1 f19a63e4 b391a8db 917f4138 b630d84b e5d63938 1e91deb4 5cfe778f 637c1001', 16)
+ });
+ }
+
+ return Clipperz.Crypto.ECC.StandardCurves._K571;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ '_K283': null,
+ 'K283': function() { // f(z) = z^283 + z^12 + z^7 + z^5 + 1
+ if ((Clipperz.Crypto.ECC.StandardCurves._K283 == null) && (typeof(Clipperz.Crypto.ECC.Koblitz.Curve) != 'undefined')) {
+ Clipperz.Crypto.ECC.StandardCurves._K283 = new Clipperz.Crypto.ECC.Koblitz.Curve({
+ modulus: new Clipperz.Crypto.ECC.Koblitz.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
+ a: new Clipperz.Crypto.ECC.Koblitz.Value('0', 16),
+ b: new Clipperz.Crypto.ECC.Koblitz.Value('1', 16),
+ G: new Clipperz.Crypto.ECC.Koblitz.Point({
+ x: new Clipperz.Crypto.ECC.Koblitz.Value('0503213f 78ca4488 3f1a3b81 62f188e5 53cd265f 23c1567a 16876913 b0c2ac24 58492836', 16),
+ y: new Clipperz.Crypto.ECC.Koblitz.Value('01ccda38 0f1c9e31 8d90f95d 07e5426f e87e45c0 e8184698 e4596236 4e341161 77dd2259', 16)
+ }),
+ r: new Clipperz.Crypto.ECC.Koblitz.Value('01ffffff ffffffff ffffffff ffffffff ffffe9ae 2ed07577 265dff7f 94451e06 1e163c61', 16),
+ h: new Clipperz.Crypto.ECC.Koblitz.Value('4', 16),
+ primeFactor: new Clipperz.Crypto.ECC.Koblitz.Value('01ffffff ffffffff ffffffff ffffffff ffffe9ae 2ed07577 265dff7f 94451e06 1e163c61', 16)
+ });
+ }
+
+ return Clipperz.Crypto.ECC.StandardCurves._K283;
+ },
+
+ //==============================================================================
+
+ '_B571': null,
+ 'B571': function() { // f(z) = z^571 + z^10 + z^5 + z^2 + 1
+ if ((Clipperz.Crypto.ECC.StandardCurves._B571 == null) && (typeof(Clipperz.Crypto.ECC.BinaryField.Curve) != 'undefined')) {
+ Clipperz.Crypto.ECC.StandardCurves._B571 = new Clipperz.Crypto.ECC.BinaryField.Curve({
+ modulus: new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000425', 16),
+ a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
+ b: new Clipperz.Crypto.ECC.BinaryField.Value('02f40e7e 2221f295 de297117 b7f3d62f 5c6a97ff cb8ceff1 cd6ba8ce 4a9a18ad 84ffabbd 8efa5933 2be7ad67 56a66e29 4afd185a 78ff12aa 520e4de7 39baca0c 7ffeff7f 2955727a', 16),
+ G: new Clipperz.Crypto.ECC.BinaryField.Point({
+ x: new Clipperz.Crypto.ECC.BinaryField.Value('0303001d 34b85629 6c16c0d4 0d3cd775 0a93d1d2 955fa80a a5f40fc8 db7b2abd bde53950 f4c0d293 cdd711a3 5b67fb14 99ae6003 8614f139 4abfa3b4 c850d927 e1e7769c 8eec2d19', 16),
+ y: new Clipperz.Crypto.ECC.BinaryField.Value('037bf273 42da639b 6dccfffe b73d69d7 8c6c27a6 009cbbca 1980f853 3921e8a6 84423e43 bab08a57 6291af8f 461bb2a8 b3531d2f 0485c19b 16e2f151 6e23dd3c 1a4827af 1b8ac15b', 16)
+ }),
+ r: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff e661ce18 ff559873 08059b18 6823851e c7dd9ca1 161de93d 5174d66e 8382e9bb 2fe84e47', 16),
+ h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
+
+// S: new Clipperz.Crypto.ECC.BinaryField.Value('2aa058f73a0e33ab486b0f610410c53a7f132310', 10),
+// n: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe661ce18ff55987308059b186823851ec7dd9ca1161de93d5174d66e8382e9bb2fe84e47', 16)
+ });
+
+ //-----------------------------------------------------------------------------
+ //
+ // Guide to Elliptic Curve Cryptography
+ // Darrel Hankerson, Alfred Menezes, Scott Vanstone
+ // - Pag: 56, Alorithm 2.45 (with a typo!!!)
+ //
+ //-----------------------------------------------------------------------------
+ //
+ // http://www.milw0rm.com/papers/136
+ //
+ // -------------------------------------------------------------------------
+ // Polynomial Reduction Algorithm Modulo f571
+ // -------------------------------------------------------------------------
+ //
+ // Input: Polynomial p(x) of degree 1140 or less, stored as
+ // an array of 2T machinewords.
+ // Output: p(x) mod f571(x)
+ //
+ // FOR i = T-1, ..., 0 DO
+ // SET X := P[i+T]
+ // P[i] := P[i] ^ (X<<5) ^ (X<<7) ^ (X<<10) ^ (X<<15)
+ // P[i+1] := P[i+1] ^ (X>>17) ^ (X>>22) ^ (X>>25) ^ (X>>27)
+ //
+ // SET X := P[T-1] >> 27
+ // P[0] := P[0] ^ X ^ (X<<2) ^ (X<<5) ^ (X<<10)
+ // P[T-1] := P[T-1] & 0x07ffffff
+ //
+ // RETURN P[T-1],...,P[0]
+ //
+ // -------------------------------------------------------------------------
+ //
+ Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().slowModule = Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module;
+ Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().module = function(aValue) {
+ var result;
+
+ if (aValue.bitSize() > 1140) {
+ MochiKit.Logging.logWarning("ECC.StandarCurves.B571.finiteField().module: falling back to default implementation");
+ result = Clipperz.Crypto.ECC.StandardCurves._B571.finiteField().slowModule(aValue);
+ } else {
+ var C, T;
+ var i;
+
+//console.log(">>> binaryField.finiteField.(improved)module");
+// C = aValue.value().slice(0);
+ C = aValue._value.slice(0);
+ for (i=35; i>=18; i--) {
+ T = C[i];
+ C[i-18] = (((C[i-18] ^ (T<<5) ^ (T<<7) ^ (T<<10) ^ (T<<15)) & 0xffffffff) >>> 0);
+ C[i-17] = ((C[i-17] ^ (T>>>27) ^ (T>>>25) ^ (T>>>22) ^ (T>>>17)) >>> 0);
+ }
+ T = (C[17] >>> 27);
+ C[0] = ((C[0] ^ T ^ ((T<<2) ^ (T<<5) ^ (T<<10)) & 0xffffffff) >>> 0);
+ C[17] = (C[17] & 0x07ffffff);
+
+ for(i=18; i<=35; i++) {
+ C[i] = 0;
+ }
+
+ result = new Clipperz.Crypto.ECC.BinaryField.Value(C);
+//console.log("<<< binaryField.finiteField.(improved)module");
+ }
+
+ return result;
+ };
+ }
+
+ return Clipperz.Crypto.ECC.StandardCurves._B571;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ '_B283': null,
+ 'B283': function() { // f(z) = z^283 + z^12 + z^7 + z^5 + 1
+ if ((Clipperz.Crypto.ECC.StandardCurves._B283 == null) && (typeof(Clipperz.Crypto.ECC.BinaryField.Curve) != 'undefined')) {
+ Clipperz.Crypto.ECC.StandardCurves._B283 = new Clipperz.Crypto.ECC.BinaryField.Curve({
+ modulus: new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16),
+ a: new Clipperz.Crypto.ECC.BinaryField.Value('1', 16),
+ b: new Clipperz.Crypto.ECC.BinaryField.Value('027b680a c8b8596d a5a4af8a 19a0303f ca97fd76 45309fa2 a581485a f6263e31 3b79a2f5', 16),
+ G: new Clipperz.Crypto.ECC.BinaryField.Point({
+ x: new Clipperz.Crypto.ECC.BinaryField.Value('05f93925 8db7dd90 e1934f8c 70b0dfec 2eed25b8 557eac9c 80e2e198 f8cdbecd 86b12053', 16),
+ y: new Clipperz.Crypto.ECC.BinaryField.Value('03676854 fe24141c b98fe6d4 b20d02b4 516ff702 350eddb0 826779c8 13f0df45 be8112f4', 16)
+ }),
+ r: new Clipperz.Crypto.ECC.BinaryField.Value('03ffffff ffffffff ffffffff ffffffff ffffef90 399660fc 938a9016 5b042a7c efadb307', 16),
+ h: new Clipperz.Crypto.ECC.BinaryField.Value('2', 16)
+ });
+
+ //-----------------------------------------------------------------------------
+ //
+ // Guide to Elliptic Curve Cryptography
+ // Darrel Hankerson, Alfred Menezes, Scott Vanstone
+ // - Pag: 56, Alorithm 2.43
+ //
+ //-----------------------------------------------------------------------------
+ Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().slowModule = Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().module;
+ Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().module = function(aValue) {
+ var result;
+
+ if (aValue.bitSize() > 564) {
+ MochiKit.Logging.logWarning("ECC.StandarCurves.B283.finiteField().module: falling back to default implementation");
+ result = Clipperz.Crypto.ECC.StandardCurves._B283.finiteField().slowModule(aValue);
+ } else {
+ var C, T;
+ var i;
+
+//console.log(">>> binaryField.finiteField.(improved)module");
+ C = aValue._value.slice(0);
+ for (i=17; i>=9; i--) {
+ T = C[i];
+ C[i-9] = (((C[i-9] ^ (T<<5) ^ (T<<10) ^ (T<<12) ^ (T<<17)) & 0xffffffff) >>> 0);
+ C[i-8] = ((C[i-8] ^ (T>>>27) ^ (T>>>22) ^ (T>>>20) ^ (T>>>15)) >>> 0);
+ }
+ T = (C[8] >>> 27);
+ C[0] = ((C[0] ^ T ^ ((T<<5) ^ (T<<7) ^ (T<<12)) & 0xffffffff) >>> 0);
+ C[8] = (C[8] & 0x07ffffff);
+
+ for(i=9; i<=17; i++) {
+ C[i] = 0;
+ }
+
+ result = new Clipperz.Crypto.ECC.BinaryField.Value(C);
+//console.log("<<< binaryField.finiteField.(improved)module");
+ }
+
+ return result;
+ };
+ }
+
+ return Clipperz.Crypto.ECC.StandardCurves._B283;
+ },
+
+ //==============================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
+
diff --git a/frontend/gamma/js/Clipperz/Crypto/PRNG.js b/frontend/gamma/js/Clipperz/Crypto/PRNG.js
new file mode 100644
index 0000000..266b909
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/PRNG.js
@@ -0,0 +1,855 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
+}
+
+try { if (typeof(Clipperz.Crypto.SHA) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.SHA!";
+}
+
+try { if (typeof(Clipperz.Crypto.AES) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.Crypto.PRNG depends on Clipperz.Crypto.AES!";
+}
+
+if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { Clipperz.Crypto.PRNG = {}; }
+
+//#############################################################################
+
+Clipperz.Crypto.PRNG.EntropyAccumulator = function(args) {
+ args = args || {};
+// MochiKit.Base.bindMethods(this);
+
+ this._stack = new Clipperz.ByteArray();
+ this._maxStackLengthBeforeHashing = args.maxStackLengthBeforeHashing || 256;
+ return this;
+}
+
+Clipperz.Crypto.PRNG.EntropyAccumulator.prototype = MochiKit.Base.update(null, {
+
+ 'toString': function() {
+ return "Clipperz.Crypto.PRNG.EntropyAccumulator";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'stack': function() {
+ return this._stack;
+ },
+
+ 'setStack': function(aValue) {
+ this._stack = aValue;
+ },
+
+ 'resetStack': function() {
+ this.stack().reset();
+ },
+
+ 'maxStackLengthBeforeHashing': function() {
+ return this._maxStackLengthBeforeHashing;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addRandomByte': function(aValue) {
+ this.stack().appendByte(aValue);
+
+ if (this.stack().length() > this.maxStackLengthBeforeHashing()) {
+ this.setStack(Clipperz.Crypto.SHA.sha_d256(this.stack()));
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+//#############################################################################
+
+Clipperz.Crypto.PRNG.RandomnessSource = function(args) {
+ args = args || {};
+ MochiKit.Base.bindMethods(this);
+
+ this._generator = args.generator || null;
+ this._sourceId = args.sourceId || null;
+ this._boostMode = args.boostMode || false;
+
+ this._nextPoolIndex = 0;
+
+ return this;
+}
+
+Clipperz.Crypto.PRNG.RandomnessSource.prototype = MochiKit.Base.update(null, {
+
+ 'generator': function() {
+ return this._generator;
+ },
+
+ 'setGenerator': function(aValue) {
+ this._generator = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'boostMode': function() {
+ return this._boostMode;
+ },
+
+ 'setBoostMode': function(aValue) {
+ this._boostMode = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'sourceId': function() {
+ return this._sourceId;
+ },
+
+ 'setSourceId': function(aValue) {
+ this._sourceId = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'nextPoolIndex': function() {
+ return this._nextPoolIndex;
+ },
+
+ 'incrementNextPoolIndex': function() {
+ this._nextPoolIndex = ((this._nextPoolIndex + 1) % this.generator().numberOfEntropyAccumulators());
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateGeneratorWithValue': function(aRandomValue) {
+ if (this.generator() != null) {
+ this.generator().addRandomByte(this.sourceId(), this.nextPoolIndex(), aRandomValue);
+ this.incrementNextPoolIndex();
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+//#############################################################################
+
+Clipperz.Crypto.PRNG.TimeRandomnessSource = function(args) {
+ args = args || {};
+// MochiKit.Base.bindMethods(this);
+
+ this._intervalTime = args.intervalTime || 1000;
+
+ Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
+
+ this.collectEntropy();
+ return this;
+}
+
+Clipperz.Crypto.PRNG.TimeRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
+
+ 'intervalTime': function() {
+ return this._intervalTime;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'collectEntropy': function() {
+ var now;
+ var entropyByte;
+ var intervalTime;
+ now = new Date();
+ entropyByte = (now.getTime() & 0xff);
+
+ intervalTime = this.intervalTime();
+ if (this.boostMode() == true) {
+ intervalTime = intervalTime / 9;
+ }
+
+ this.updateGeneratorWithValue(entropyByte);
+ setTimeout(this.collectEntropy, intervalTime);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'numberOfRandomBits': function() {
+ return 5;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'pollingFrequency': function() {
+ return 10;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+//*****************************************************************************
+
+Clipperz.Crypto.PRNG.MouseRandomnessSource = function(args) {
+ args = args || {};
+
+ Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
+
+ this._numberOfBitsToCollectAtEachEvent = 4;
+ this._randomBitsCollector = 0;
+ this._numberOfRandomBitsCollected = 0;
+
+ MochiKit.Signal.connect(document, 'onmousemove', this, 'collectEntropy');
+
+ return this;
+}
+
+Clipperz.Crypto.PRNG.MouseRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
+
+ //-------------------------------------------------------------------------
+
+ 'numberOfBitsToCollectAtEachEvent': function() {
+ return this._numberOfBitsToCollectAtEachEvent;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'randomBitsCollector': function() {
+ return this._randomBitsCollector;
+ },
+
+ 'setRandomBitsCollector': function(aValue) {
+ this._randomBitsCollector = aValue;
+ },
+
+ 'appendRandomBitsToRandomBitsCollector': function(aValue) {
+ var collectedBits;
+ var numberOfRandomBitsCollected;
+
+ numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
+ collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
+ this.setRandomBitsCollector(collectetBits);
+ numberOfRandomBitsCollected += this.numberOfBitsToCollectAtEachEvent();
+
+ if (numberOfRandomBitsCollected == 8) {
+ this.updateGeneratorWithValue(collectetBits);
+ numberOfRandomBitsCollected = 0;
+ this.setRandomBitsCollector(0);
+ }
+
+ this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'numberOfRandomBitsCollected': function() {
+ return this._numberOfRandomBitsCollected;
+ },
+
+ 'setNumberOfRandomBitsCollected': function(aValue) {
+ this._numberOfRandomBitsCollected = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'collectEntropy': function(anEvent) {
+ var mouseLocation;
+ var randomBit;
+ var mask;
+
+ mask = 0xffffffff >>> (32 - this.numberOfBitsToCollectAtEachEvent());
+
+ mouseLocation = anEvent.mouse().client;
+ randomBit = ((mouseLocation.x ^ mouseLocation.y) & mask);
+ this.appendRandomBitsToRandomBitsCollector(randomBit)
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'numberOfRandomBits': function() {
+ return 1;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'pollingFrequency': function() {
+ return 10;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+//*****************************************************************************
+
+Clipperz.Crypto.PRNG.KeyboardRandomnessSource = function(args) {
+ args = args || {};
+ Clipperz.Crypto.PRNG.RandomnessSource.call(this, args);
+
+ this._randomBitsCollector = 0;
+ this._numberOfRandomBitsCollected = 0;
+
+ MochiKit.Signal.connect(document, 'onkeypress', this, 'collectEntropy');
+
+ return this;
+}
+
+Clipperz.Crypto.PRNG.KeyboardRandomnessSource.prototype = MochiKit.Base.update(new Clipperz.Crypto.PRNG.RandomnessSource, {
+
+ //-------------------------------------------------------------------------
+
+ 'randomBitsCollector': function() {
+ return this._randomBitsCollector;
+ },
+
+ 'setRandomBitsCollector': function(aValue) {
+ this._randomBitsCollector = aValue;
+ },
+
+ 'appendRandomBitToRandomBitsCollector': function(aValue) {
+ var collectedBits;
+ var numberOfRandomBitsCollected;
+
+ numberOfRandomBitsCollected = this.numberOfRandomBitsCollected();
+ collectetBits = this.randomBitsCollector() | (aValue << numberOfRandomBitsCollected);
+ this.setRandomBitsCollector(collectetBits);
+ numberOfRandomBitsCollected ++;
+
+ if (numberOfRandomBitsCollected == 8) {
+ this.updateGeneratorWithValue(collectetBits);
+ numberOfRandomBitsCollected = 0;
+ this.setRandomBitsCollector(0);
+ }
+
+ this.setNumberOfRandomBitsCollected(numberOfRandomBitsCollected)
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'numberOfRandomBitsCollected': function() {
+ return this._numberOfRandomBitsCollected;
+ },
+
+ 'setNumberOfRandomBitsCollected': function(aValue) {
+ this._numberOfRandomBitsCollected = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'collectEntropy': function(anEvent) {
+/*
+ var mouseLocation;
+ var randomBit;
+
+ mouseLocation = anEvent.mouse().client;
+
+ randomBit = ((mouseLocation.x ^ mouseLocation.y) & 0x1);
+ this.appendRandomBitToRandomBitsCollector(randomBit);
+*/
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'numberOfRandomBits': function() {
+ return 1;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'pollingFrequency': function() {
+ return 10;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+//#############################################################################
+
+Clipperz.Crypto.PRNG.Fortuna = function(args) {
+ var i,c;
+
+ args = args || {};
+
+ this._key = args.seed || null;
+ if (this._key == null) {
+ this._counter = 0;
+ this._key = new Clipperz.ByteArray();
+ } else {
+ this._counter = 1;
+ }
+
+ this._aesKey = null;
+
+ this._firstPoolReseedLevel = args.firstPoolReseedLevel || 32 || 64;
+ this._numberOfEntropyAccumulators = args.numberOfEntropyAccumulators || 32;
+
+ this._accumulators = [];
+ c = this.numberOfEntropyAccumulators();
+ for (i=0; i<c; i++) {
+ this._accumulators.push(new Clipperz.Crypto.PRNG.EntropyAccumulator());
+ }
+
+ this._randomnessSources = [];
+ this._reseedCounter = 0;
+
+ return this;
+}
+
+Clipperz.Crypto.PRNG.Fortuna.prototype = MochiKit.Base.update(null, {
+
+ 'toString': function() {
+ return "Clipperz.Crypto.PRNG.Fortuna";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'key': function() {
+ return this._key;
+ },
+
+ 'setKey': function(aValue) {
+ this._key = aValue;
+ this._aesKey = null;
+ },
+
+ 'aesKey': function() {
+ if (this._aesKey == null) {
+ this._aesKey = new Clipperz.Crypto.AES.Key({key:this.key()});
+ }
+
+ return this._aesKey;
+ },
+
+ 'accumulators': function() {
+ return this._accumulators;
+ },
+
+ 'firstPoolReseedLevel': function() {
+ return this._firstPoolReseedLevel;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'reseedCounter': function() {
+ return this._reseedCounter;
+ },
+
+ 'incrementReseedCounter': function() {
+ this._reseedCounter = this._reseedCounter +1;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'reseed': function() {
+ var newKeySeed;
+ var reseedCounter;
+ var reseedCounterMask;
+ var i, c;
+
+ newKeySeed = this.key();
+ this.incrementReseedCounter();
+ reseedCounter = this.reseedCounter();
+
+ c = this.numberOfEntropyAccumulators();
+ reseedCounterMask = 0xffffffff >>> (32 - c);
+ for (i=0; i<c; i++) {
+ if ((i == 0) || ((reseedCounter & (reseedCounterMask >>> (c - i))) == 0)) {
+ newKeySeed.appendBlock(this.accumulators()[i].stack());
+ this.accumulators()[i].resetStack();
+ }
+ }
+
+ if (reseedCounter == 1) {
+ c = this.randomnessSources().length;
+ for (i=0; i<c; i++) {
+ this.randomnessSources()[i].setBoostMode(false);
+ }
+ }
+
+ this.setKey(Clipperz.Crypto.SHA.sha_d256(newKeySeed));
+ if (reseedCounter == 1) {
+//MochiKit.Logging.logDebug("### PRNG.readyToGenerateRandomBytes");
+Clipperz.log("### PRNG.readyToGenerateRandomBytes");
+ MochiKit.Signal.signal(this, 'readyToGenerateRandomBytes');
+ }
+ MochiKit.Signal.signal(this, 'reseeded');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isReadyToGenerateRandomValues': function() {
+ return this.reseedCounter() != 0;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'entropyLevel': function() {
+ return this.accumulators()[0].stack().length() + (this.reseedCounter() * this.firstPoolReseedLevel());
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'counter': function() {
+ return this._counter;
+ },
+
+ 'incrementCounter': function() {
+ this._counter += 1;
+ },
+
+ 'counterBlock': function() {
+ var result;
+
+ result = new Clipperz.ByteArray().appendWords(this.counter(), 0, 0, 0);
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getRandomBlock': function() {
+ var result;
+
+ result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(this.aesKey(), this.counterBlock().arrayValues()));
+ this.incrementCounter();
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getRandomBytes': function(aSize) {
+ var result;
+
+ if (this.isReadyToGenerateRandomValues()) {
+ var i,c;
+ var newKey;
+
+ result = new Clipperz.ByteArray();
+
+ c = Math.ceil(aSize / (128 / 8));
+ for (i=0; i<c; i++) {
+ result.appendBlock(this.getRandomBlock());
+ }
+
+ if (result.length() != aSize) {
+ result = result.split(0, aSize);
+ }
+
+ newKey = this.getRandomBlock().appendBlock(this.getRandomBlock());
+ this.setKey(newKey);
+ } else {
+MochiKit.Logging.logWarning("Fortuna generator has not enough entropy, yet!");
+ throw Clipperz.Crypto.PRNG.exception.NotEnoughEntropy;
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addRandomByte': function(aSourceId, aPoolId, aRandomValue) {
+ var selectedAccumulator;
+
+ selectedAccumulator = this.accumulators()[aPoolId];
+ selectedAccumulator.addRandomByte(aRandomValue);
+
+ if (aPoolId == 0) {
+ MochiKit.Signal.signal(this, 'addedRandomByte')
+ if (selectedAccumulator.stack().length() > this.firstPoolReseedLevel()) {
+ this.reseed();
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'numberOfEntropyAccumulators': function() {
+ return this._numberOfEntropyAccumulators;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'randomnessSources': function() {
+ return this._randomnessSources;
+ },
+
+ 'addRandomnessSource': function(aRandomnessSource) {
+ aRandomnessSource.setGenerator(this);
+ aRandomnessSource.setSourceId(this.randomnessSources().length);
+ this.randomnessSources().push(aRandomnessSource);
+
+ if (this.isReadyToGenerateRandomValues() == false) {
+ aRandomnessSource.setBoostMode(true);
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredEntropyCollection': function(aValue) {
+ var result;
+
+//MochiKit.Logging.logDebug(">>> PRNG.deferredEntropyCollection");
+
+ if (this.isReadyToGenerateRandomValues()) {
+//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 1");
+ result = aValue;
+ } else {
+//MochiKit.Logging.logDebug("--- PRNG.deferredEntropyCollection - 2");
+ var deferredResult;
+
+// Clipperz.NotificationCenter.notify(this, 'updatedProgressState', 'collectingEntropy', true);
+
+ deferredResult = new Clipperz.Async.Deferred("PRNG.deferredEntropyCollection");
+// deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.1 - PRNG.deferredEntropyCollection - 1: " + res); return res;});
+ deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Async.succeed, aValue));
+// deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("1.2.2 - PRNG.deferredEntropyCollection - 2: " + res); return res;});
+ MochiKit.Signal.connect(this,
+ 'readyToGenerateRandomBytes',
+ deferredResult,
+ 'callback');
+
+ result = deferredResult;
+ }
+//MochiKit.Logging.logDebug("<<< PRNG.deferredEntropyCollection - result: " + result);
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'fastEntropyAccumulationForTestingPurpose': function() {
+ while (! this.isReadyToGenerateRandomValues()) {
+ this.addRandomByte(Math.floor(Math.random() * 32), Math.floor(Math.random() * 32), Math.floor(Math.random() * 256));
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'dump': function(appendToDoc) {
+ var tbl;
+ var i,c;
+
+ tbl = document.createElement("table");
+ tbl.border = 0;
+ with (tbl.style) {
+ border = "1px solid lightgrey";
+ fontFamily = 'Helvetica, Arial, sans-serif';
+ fontSize = '8pt';
+ //borderCollapse = "collapse";
+ }
+ var hdr = tbl.createTHead();
+ var hdrtr = hdr.insertRow(0);
+ // document.createElement("tr");
+ {
+ var ntd;
+
+ ntd = hdrtr.insertCell(0);
+ ntd.style.borderBottom = "1px solid lightgrey";
+ ntd.style.borderRight = "1px solid lightgrey";
+ ntd.appendChild(document.createTextNode("#"));
+
+ ntd = hdrtr.insertCell(1);
+ ntd.style.borderBottom = "1px solid lightgrey";
+ ntd.style.borderRight = "1px solid lightgrey";
+ ntd.appendChild(document.createTextNode("s"));
+
+ ntd = hdrtr.insertCell(2);
+ ntd.colSpan = this.firstPoolReseedLevel();
+ ntd.style.borderBottom = "1px solid lightgrey";
+ ntd.style.borderRight = "1px solid lightgrey";
+ ntd.appendChild(document.createTextNode("base values"));
+
+ ntd = hdrtr.insertCell(3);
+ ntd.colSpan = 20;
+ ntd.style.borderBottom = "1px solid lightgrey";
+ ntd.appendChild(document.createTextNode("extra values"));
+
+ }
+
+ c = this.accumulators().length;
+ for (i=0; i<c ; i++) {
+ var currentAccumulator;
+ var bdytr;
+ var bdytd;
+ var ii, cc;
+
+ currentAccumulator = this.accumulators()[i]
+
+ bdytr = tbl.insertRow(true);
+
+ bdytd = bdytr.insertCell(0);
+ bdytd.style.borderRight = "1px solid lightgrey";
+ bdytd.style.color = "lightgrey";
+ bdytd.appendChild(document.createTextNode("" + i));
+
+ bdytd = bdytr.insertCell(1);
+ bdytd.style.borderRight = "1px solid lightgrey";
+ bdytd.style.color = "gray";
+ bdytd.appendChild(document.createTextNode("" + currentAccumulator.stack().length()));
+
+
+ cc = Math.max(currentAccumulator.stack().length(), this.firstPoolReseedLevel());
+ for (ii=0; ii<cc; ii++) {
+ var cellText;
+
+ bdytd = bdytr.insertCell(ii + 2);
+
+ if (ii < currentAccumulator.stack().length()) {
+ cellText = Clipperz.ByteArray.byteToHex(currentAccumulator.stack().byteAtIndex(ii));
+ } else {
+ cellText = "_";
+ }
+
+ if (ii == (this.firstPoolReseedLevel() - 1)) {
+ bdytd.style.borderRight = "1px solid lightgrey";
+ }
+
+ bdytd.appendChild(document.createTextNode(cellText));
+ }
+
+ }
+
+
+ if (appendToDoc) {
+ var ne = document.createElement("div");
+ ne.id = "entropyGeneratorStatus";
+ with (ne.style) {
+ fontFamily = "Courier New, monospace";
+ fontSize = "12px";
+ lineHeight = "16px";
+ borderTop = "1px solid black";
+ padding = "10px";
+ }
+ if (document.getElementById(ne.id)) {
+ MochiKit.DOM.swapDOM(ne.id, ne);
+ } else {
+ document.body.appendChild(ne);
+ }
+ ne.appendChild(tbl);
+ }
+
+ return tbl;
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+//#############################################################################
+
+Clipperz.Crypto.PRNG.Random = function(args) {
+ args = args || {};
+// MochiKit.Base.bindMethods(this);
+
+ return this;
+}
+
+Clipperz.Crypto.PRNG.Random.prototype = MochiKit.Base.update(null, {
+
+ 'toString': function() {
+ return "Clipperz.Crypto.PRNG.Random";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getRandomBytes': function(aSize) {
+//Clipperz.Profile.start("Clipperz.Crypto.PRNG.Random.getRandomBytes");
+ var result;
+ var i,c;
+
+ result = new Clipperz.ByteArray()
+ c = aSize || 1;
+ for (i=0; i<c; i++) {
+ result.appendByte((Math.random()*255) & 0xff);
+ }
+
+//Clipperz.Profile.stop("Clipperz.Crypto.PRNG.Random.getRandomBytes");
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+//#############################################################################
+
+_clipperz_crypt_prng_defaultPRNG = null;
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator = function() {
+ if (_clipperz_crypt_prng_defaultPRNG == null) {
+ _clipperz_crypt_prng_defaultPRNG = new Clipperz.Crypto.PRNG.Fortuna();
+
+ //.............................................................
+ //
+ // TimeRandomnessSource
+ //
+ //.............................................................
+ {
+ var newRandomnessSource;
+
+ newRandomnessSource = new Clipperz.Crypto.PRNG.TimeRandomnessSource({intervalTime:111});
+ _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
+ }
+
+ //.............................................................
+ //
+ // MouseRandomnessSource
+ //
+ //.............................................................
+ {
+ var newRandomnessSource;
+
+ newRandomnessSource = new Clipperz.Crypto.PRNG.MouseRandomnessSource();
+ _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
+ }
+
+ //.............................................................
+ //
+ // KeyboardRandomnessSource
+ //
+ //.............................................................
+ {
+ var newRandomnessSource;
+
+ newRandomnessSource = new Clipperz.Crypto.PRNG.KeyboardRandomnessSource();
+ _clipperz_crypt_prng_defaultPRNG.addRandomnessSource(newRandomnessSource);
+ }
+
+ }
+
+ return _clipperz_crypt_prng_defaultPRNG;
+};
+
+//#############################################################################
+
+Clipperz.Crypto.PRNG.exception = {
+ NotEnoughEntropy: new MochiKit.Base.NamedError("Clipperz.Crypto.PRNG.exception.NotEnoughEntropy")
+};
+
+
+MochiKit.DOM.addLoadEvent(Clipperz.Crypto.PRNG.defaultRandomGenerator);
diff --git a/frontend/gamma/js/Clipperz/Crypto/RSA.js b/frontend/gamma/js/Clipperz/Crypto/RSA.js
new file mode 100644
index 0000000..4dad8f7
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/RSA.js
@@ -0,0 +1,151 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.Crypto.RSA depends on Clipperz.Crypto.BigInt!";
+}
+
+if (typeof(Clipperz.Crypto.RSA) == 'undefined') { Clipperz.Crypto.RSA = {}; }
+
+Clipperz.Crypto.RSA.VERSION = "0.1";
+Clipperz.Crypto.RSA.NAME = "Clipperz.RSA";
+
+//#############################################################################
+
+MochiKit.Base.update(Clipperz.Crypto.RSA, {
+
+ //-------------------------------------------------------------------------
+
+ 'publicKeyWithValues': function (e, d, n) {
+ var result;
+
+ result = {};
+
+ if (e.isBigInt) {
+ result.e = e;
+ } else {
+ result.e = new Clipperz.Crypto.BigInt(e, 16);
+ }
+
+ if (d.isBigInt) {
+ result.d = d;
+ } else {
+ result.d = new Clipperz.Crypto.BigInt(d, 16);
+ }
+
+ if (n.isBigInt) {
+ result.n = n;
+ } else {
+ result.n = new Clipperz.Crypto.BigInt(n, 16);
+ }
+
+ return result;
+ },
+
+ 'privateKeyWithValues': function(e, d, n) {
+ return Clipperz.Crypto.RSA.publicKeyWithValues(e, d, n);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'encryptUsingPublicKey': function (aKey, aMessage) {
+ var messageValue;
+ var result;
+
+ messageValue = new Clipperz.Crypto.BigInt(aMessage, 16);
+ result = messageValue.powerModule(aKey.e, aKey.n);
+
+ return result.asString(16);
+ },
+
+ //.............................................................................
+
+ 'decryptUsingPublicKey': function (aKey, aMessage) {
+ return Clipperz.Crypto.RSA.encryptUsingPublicKey(aKey, aMessage);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'encryptUsingPrivateKey': function (aKey, aMessage) {
+ var messageValue;
+ var result;
+
+ messageValue = new Clipperz.Crypto.BigInt(aMessage, 16);
+ result = messageValue.powerModule(aKey.d, aKey.n);
+
+ return result.asString(16);
+ },
+
+ //.............................................................................
+
+ 'decryptUsingPrivateKey': function (aKey, aMessage) {
+ return Clipperz.Crypto.RSA.encryptUsingPrivateKey(aKey, aMessage);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'generatePublicKey': function(aNumberOfBits) {
+ var result;
+ var e;
+ var d;
+ var n;
+
+ e = new Clipperz.Crypto.BigInt("10001", 16);
+
+ {
+ var p, q;
+ var phi;
+
+ do {
+ p = Clipperz.Crypto.BigInt.randomPrime(aNumberOfBits);
+ } while (p.module(e).equals(1));
+
+ do {
+ q = Clipperz.Crypto.BigInt.randomPrime(aNumberOfBits);
+ } while ((q.equals(p)) || (q.module(e).equals(1)));
+
+ n = p.multiply(q);
+ phi = (p.subtract(1).multiply(q.subtract(1)));
+ d = e.powerModule(-1, phi);
+ }
+
+ result = Clipperz.Crypto.RSA.publicKeyWithValues(e, d, n);
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+
+ //-------------------------------------------------------------------------
+
+});
+
+//#############################################################################
+
diff --git a/frontend/gamma/js/Clipperz/Crypto/SHA.js b/frontend/gamma/js/Clipperz/Crypto/SHA.js
new file mode 100644
index 0000000..3cf8559
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/SHA.js
@@ -0,0 +1,301 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
+}
+
+if (typeof(Clipperz.Crypto) == 'undefined') { Clipperz.Crypto = {}; }
+if (typeof(Clipperz.Crypto.SHA) == 'undefined') { Clipperz.Crypto.SHA = {}; }
+
+Clipperz.Crypto.SHA.VERSION = "0.3";
+Clipperz.Crypto.SHA.NAME = "Clipperz.Crypto.SHA";
+
+MochiKit.Base.update(Clipperz.Crypto.SHA, {
+
+ '__repr__': function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+ },
+
+ 'toString': function () {
+ return this.__repr__();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'rotateRight': function(aValue, aNumberOfBits) {
+//Clipperz.Profile.start("Clipperz.Crypto.SHA.rotateRight");
+ var result;
+
+ result = (aValue >>> aNumberOfBits) | (aValue << (32 - aNumberOfBits));
+
+//Clipperz.Profile.stop("Clipperz.Crypto.SHA.rotateRight");
+ return result;
+ },
+
+ 'shiftRight': function(aValue, aNumberOfBits) {
+//Clipperz.Profile.start("Clipperz.Crypto.SHA.shiftRight");
+ var result;
+
+ result = aValue >>> aNumberOfBits;
+
+//Clipperz.Profile.stop("Clipperz.Crypto.SHA.shiftRight");
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'safeAdd': function() {
+//Clipperz.Profile.start("Clipperz.Crypto.SHA.safeAdd");
+ var result;
+ var i, c;
+
+ result = arguments[0];
+ c = arguments.length;
+ for (i=1; i<c; i++) {
+ var lowerBytesSum;
+
+ lowerBytesSum = (result & 0xffff) + (arguments[i] & 0xffff);
+ result = (((result >> 16) + (arguments[i] >> 16) + (lowerBytesSum >> 16)) << 16) | (lowerBytesSum & 0xffff);
+ }
+
+//Clipperz.Profile.stop("Clipperz.Crypto.SHA.safeAdd");
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'sha256_array': function(aValue) {
+//Clipperz.Profile.start("Clipperz.Crypto.SHA.sha256_array");
+ var result;
+ var message;
+ var h0, h1, h2, h3, h4, h5, h6, h7;
+ var k;
+ var messageLength;
+ var messageLengthInBits;
+ var _i, _c;
+ var charBits;
+ var rotateRight;
+ var shiftRight;
+ var safeAdd;
+ var bytesPerBlock;
+ var currentMessageIndex;
+
+ bytesPerBlock = 512/8;
+ rotateRight = Clipperz.Crypto.SHA.rotateRight;
+ shiftRight = Clipperz.Crypto.SHA.shiftRight;
+ safeAdd = Clipperz.Crypto.SHA.safeAdd;
+
+ charBits = 8;
+
+ h0 = 0x6a09e667;
+ h1 = 0xbb67ae85;
+ h2 = 0x3c6ef372;
+ h3 = 0xa54ff53a;
+ h4 = 0x510e527f;
+ h5 = 0x9b05688c;
+ h6 = 0x1f83d9ab;
+ h7 = 0x5be0cd19;
+
+ k = [ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2];
+
+ message = aValue;
+ messageLength = message.length;
+
+ //Pre-processing:
+ message.push(0x80); // append a single "1" bit to message
+
+ _c = (512 - (((messageLength + 1) * charBits) % 512) - 64) / charBits;
+ if (_c < 0) {
+ _c = _c + (512 / charBits);
+ }
+
+ for (_i=0; _i<_c; _i++) {
+ message.push(0x00); // append "0" bits until message length ≡ 448 ≡ -64 (mod 512)
+ }
+
+ messageLengthInBits = messageLength * charBits;
+ message.push(0x00); // the 4 most high byte are alway 0 as message length is represented with a 32bit value;
+ message.push(0x00);
+ message.push(0x00);
+ message.push(0x00);
+ message.push((messageLengthInBits >> 24) & 0xff);
+ message.push((messageLengthInBits >> 16) & 0xff);
+ message.push((messageLengthInBits >> 8) & 0xff);
+ message.push( messageLengthInBits & 0xff);
+
+ currentMessageIndex = 0;
+ while(currentMessageIndex < message.length) {
+ var w;
+ var a, b, c, d, e, f, g, h;
+
+ w = Array(64);
+
+ _c = 16;
+ for (_i=0; _i<_c; _i++) {
+ var _j;
+
+ _j = currentMessageIndex + _i*4;
+ w[_i] = (message[_j] << 24) | (message[_j + 1] << 16) | (message[_j + 2] << 8) | (message[_j + 3] << 0);
+ }
+
+ _c = 64;
+ for (_i=16; _i<_c; _i++) {
+ var s0, s1;
+
+ s0 = (rotateRight(w[_i-15], 7)) ^ (rotateRight(w[_i-15], 18)) ^ (shiftRight(w[_i-15], 3));
+ s1 = (rotateRight(w[_i-2], 17)) ^ (rotateRight(w[_i-2], 19)) ^ (shiftRight(w[_i-2], 10));
+ w[_i] = safeAdd(w[_i-16], s0, w[_i-7], s1);
+ }
+
+ a=h0; b=h1; c=h2; d=h3; e=h4; f=h5; g=h6; h=h7;
+
+ _c = 64;
+ for (_i=0; _i<_c; _i++) {
+ var s0, s1, ch, maj, t1, t2;
+
+ s0 = (rotateRight(a, 2)) ^ (rotateRight(a, 13)) ^ (rotateRight(a, 22));
+ maj = (a & b) ^ (a & c) ^ (b & c);
+ t2 = safeAdd(s0, maj);
+ s1 = (rotateRight(e, 6)) ^ (rotateRight(e, 11)) ^ (rotateRight(e, 25));
+ ch = (e & f) ^ ((~e) & g);
+ t1 = safeAdd(h, s1, ch, k[_i], w[_i]);
+
+ h = g;
+ g = f;
+ f = e;
+ e = safeAdd(d, t1);
+ d = c;
+ c = b;
+ b = a;
+ a = safeAdd(t1, t2);
+ }
+
+ h0 = safeAdd(h0, a);
+ h1 = safeAdd(h1, b);
+ h2 = safeAdd(h2, c);
+ h3 = safeAdd(h3, d);
+ h4 = safeAdd(h4, e);
+ h5 = safeAdd(h5, f);
+ h6 = safeAdd(h6, g);
+ h7 = safeAdd(h7, h);
+
+ currentMessageIndex += bytesPerBlock;
+ }
+
+ result = new Array(256/8);
+ result[0] = (h0 >> 24) & 0xff;
+ result[1] = (h0 >> 16) & 0xff;
+ result[2] = (h0 >> 8) & 0xff;
+ result[3] = h0 & 0xff;
+
+ result[4] = (h1 >> 24) & 0xff;
+ result[5] = (h1 >> 16) & 0xff;
+ result[6] = (h1 >> 8) & 0xff;
+ result[7] = h1 & 0xff;
+
+ result[8] = (h2 >> 24) & 0xff;
+ result[9] = (h2 >> 16) & 0xff;
+ result[10] = (h2 >> 8) & 0xff;
+ result[11] = h2 & 0xff;
+
+ result[12] = (h3 >> 24) & 0xff;
+ result[13] = (h3 >> 16) & 0xff;
+ result[14] = (h3 >> 8) & 0xff;
+ result[15] = h3 & 0xff;
+
+ result[16] = (h4 >> 24) & 0xff;
+ result[17] = (h4 >> 16) & 0xff;
+ result[18] = (h4 >> 8) & 0xff;
+ result[19] = h4 & 0xff;
+
+ result[20] = (h5 >> 24) & 0xff;
+ result[21] = (h5 >> 16) & 0xff;
+ result[22] = (h5 >> 8) & 0xff;
+ result[23] = h5 & 0xff;
+
+ result[24] = (h6 >> 24) & 0xff;
+ result[25] = (h6 >> 16) & 0xff;
+ result[26] = (h6 >> 8) & 0xff;
+ result[27] = h6 & 0xff;
+
+ result[28] = (h7 >> 24) & 0xff;
+ result[29] = (h7 >> 16) & 0xff;
+ result[30] = (h7 >> 8) & 0xff;
+ result[31] = h7 & 0xff;
+
+//Clipperz.Profile.stop("Clipperz.Crypto.SHA.sha256_array");
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'sha256': function(aValue) {
+//Clipperz.Profile.start("Clipperz.Crypto.SHA.sha256");
+ var result;
+ var resultArray;
+ var valueArray;
+
+ valueArray = aValue.arrayValues();
+ resultArray = Clipperz.Crypto.SHA.sha256_array(valueArray);
+
+ result = new Clipperz.ByteArray(resultArray);
+
+//Clipperz.Profile.stop("Clipperz.Crypto.SHA.sha256");
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'sha_d256': function(aValue) {
+//Clipperz.Profile.start("Clipperz.Crypto.SHA.sha_d256");
+ var result;
+ var resultArray;
+ var valueArray;
+
+ valueArray = aValue.arrayValues();
+ resultArray = Clipperz.Crypto.SHA.sha256_array(valueArray);
+ resultArray = Clipperz.Crypto.SHA.sha256_array(resultArray);
+
+ result = new Clipperz.ByteArray(resultArray);
+
+//Clipperz.Profile.stop("Clipperz.Crypto.SHA.sha256");
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
diff --git a/frontend/gamma/js/Clipperz/Crypto/SRP.js b/frontend/gamma/js/Clipperz/Crypto/SRP.js
new file mode 100644
index 0000000..0eef6ec
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Crypto/SRP.js
@@ -0,0 +1,331 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try { if (typeof(Clipperz.ByteArray) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.Crypto.PRNG depends on Clipperz.ByteArray!";
+}
+
+try { if (typeof(Clipperz.Crypto.BigInt) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.BigInt!";
+}
+
+try { if (typeof(Clipperz.Crypto.PRNG) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.Crypto.SRP depends on Clipperz.Crypto.PRNG!";
+}
+
+if (typeof(Clipperz.Crypto.SRP) == 'undefined') { Clipperz.Crypto.SRP = {}; }
+
+Clipperz.Crypto.SRP.VERSION = "0.1";
+Clipperz.Crypto.SRP.NAME = "Clipperz.Crypto.SRP";
+
+//#############################################################################
+
+MochiKit.Base.update(Clipperz.Crypto.SRP, {
+
+ '_n': null,
+ '_g': null,
+ //-------------------------------------------------------------------------
+
+ 'n': function() {
+ if (Clipperz.Crypto.SRP._n == null) {
+ Clipperz.Crypto.SRP._n = new Clipperz.Crypto.BigInt("115b8b692e0e045692cf280b436735c77a5a9e8a9e7ed56c965f87db5b2a2ece3", 16);
+ }
+
+ return Clipperz.Crypto.SRP._n;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'g': function() {
+ if (Clipperz.Crypto.SRP._g == null) {
+ Clipperz.Crypto.SRP._g = new Clipperz.Crypto.BigInt(2); // eventually 5 (as suggested on the Diffi-Helmann documentation)
+ }
+
+ return Clipperz.Crypto.SRP._g;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'exception': {
+ 'InvalidValue': new MochiKit.Base.NamedError("Clipperz.Crypto.SRP.exception.InvalidValue")
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
+//#############################################################################
+//
+// S R P C o n n e c t i o n version 1.0
+//
+//=============================================================================
+Clipperz.Crypto.SRP.Connection = function (args) {
+ args = args || {};
+
+ this._C = args.C;
+ this._P = args.P;
+ this.hash = args.hash;
+
+ this._a = null;
+ this._A = null;
+
+ this._s = null;
+ this._B = null;
+
+ this._x = null;
+
+ this._u = null;
+ this._K = null;
+ this._M1 = null;
+ this._M2 = null;
+
+ this._sessionKey = null;
+
+ return this;
+}
+
+Clipperz.Crypto.SRP.Connection.prototype = MochiKit.Base.update(null, {
+
+ 'toString': function () {
+ return "Clipperz.Crypto.SRP.Connection (username: " + this.username() + "). Status: " + this.statusDescription();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'C': function () {
+ return this._C;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'P': function () {
+ return this._P;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'a': function () {
+ if (this._a == null) {
+ this._a = new Clipperz.Crypto.BigInt(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2), 16);
+// this._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10);
+//MochiKit.Logging.logDebug("SRP a: " + this._a);
+ }
+
+ return this._a;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'A': function () {
+ if (this._A == null) {
+ // Warning: this value should be strictly greater than zero: how should we perform this check?
+ this._A = Clipperz.Crypto.SRP.g().powerModule(this.a(), Clipperz.Crypto.SRP.n());
+
+ if (this._A.equals(0)) {
+MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'A' to 0.");
+ throw Clipperz.Crypto.SRP.exception.InvalidValue;
+ }
+//MochiKit.Logging.logDebug("SRP A: " + this._A);
+ }
+
+ return this._A;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 's': function () {
+ return this._s;
+//MochiKit.Logging.logDebug("SRP s: " + this._S);
+ },
+
+ 'set_s': function(aValue) {
+ this._s = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'B': function () {
+ return this._B;
+ },
+
+ 'set_B': function(aValue) {
+ // Warning: this value should be strictly greater than zero: how should we perform this check?
+ if (! aValue.equals(0)) {
+ this._B = aValue;
+//MochiKit.Logging.logDebug("SRP B: " + this._B);
+ } else {
+MochiKit.Logging.logError("Clipperz.Crypto.SRP.Connection: trying to set 'B' to 0.");
+ throw Clipperz.Crypto.SRP.exception.InvalidValue;
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'x': function () {
+ if (this._x == null) {
+ this._x = new Clipperz.Crypto.BigInt(this.stringHash(this.s().asString(16, 64) + this.P()), 16);
+//MochiKit.Logging.logDebug("SRP x: " + this._x);
+ }
+
+ return this._x;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'u': function () {
+ if (this._u == null) {
+ this._u = new Clipperz.Crypto.BigInt(this.stringHash(this.B().asString()), 16);
+//MochiKit.Logging.logDebug("SRP u: " + this._u);
+ }
+
+ return this._u;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'S': function () {
+ if (this._S == null) {
+ var bigint;
+ var srp;
+
+ bigint = Clipperz.Crypto.BigInt;
+ srp = Clipperz.Crypto.SRP;
+
+ this._S = bigint.powerModule(
+ bigint.subtract(this.B(), bigint.powerModule(srp.g(), this.x(), srp.n())),
+ bigint.add(this.a(), bigint.multiply(this.u(), this.x())),
+ srp.n()
+ )
+//MochiKit.Logging.logDebug("SRP S: " + this._S);
+ }
+
+ return this._S;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'K': function () {
+ if (this._K == null) {
+ this._K = this.stringHash(this.S().asString());
+//MochiKit.Logging.logDebug("SRP K: " + this._K);
+ }
+
+ return this._K;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'M1': function () {
+ if (this._M1 == null) {
+ this._M1 = this.stringHash(this.A().asString(10) + this.B().asString(10) + this.K());
+//MochiKit.Logging.logDebug("SRP M1: " + this._M1);
+ }
+
+ return this._M1;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'M2': function () {
+ if (this._M2 == null) {
+ this._M2 = this.stringHash(this.A().asString(10) + this.M1() + this.K());
+//MochiKit.Logging.logDebug("SRP M2: " + this._M2);
+ }
+
+ return this._M2;
+ },
+
+ //=========================================================================
+
+ 'serverSideCredentialsWithSalt': function(aSalt) {
+ var result;
+ var s, x, v;
+
+ s = aSalt;
+ x = this.stringHash(s + this.P());
+ v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n());
+
+ result = {};
+ result['C'] = this.C();
+ result['s'] = s;
+ result['v'] = v.asString(16);
+
+ return result;
+ },
+
+ 'serverSideCredentials': function() {
+ var result;
+ var s;
+
+ s = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
+
+ result = this.serverSideCredentialsWithSalt(s);
+
+ return result;
+ },
+
+ //=========================================================================
+/*
+ 'computeServerSide_S': function(b) {
+ var result;
+ var v;
+ var bigint;
+ var srp;
+
+ bigint = Clipperz.Crypto.BigInt;
+ srp = Clipperz.Crypto.SRP;
+
+ v = new Clipperz.Crypto.BigInt(srpConnection.serverSideCredentialsWithSalt(this.s().asString(16, 64)).v, 16);
+// _S = (this.A().multiply(this.v().modPow(this.u(), this.n()))).modPow(this.b(), this.n());
+ result = bigint.powerModule(
+ bigint.multiply(
+ this.A(),
+ bigint.powerModule(v, this.u(), srp.n())
+ ), new Clipperz.Crypto.BigInt(b, 10), srp.n()
+ );
+
+ return result;
+ },
+*/
+ //=========================================================================
+
+ 'stringHash': function(aValue) {
+ var result;
+
+ result = this.hash(new Clipperz.ByteArray(aValue)).toHexString().substring(2);
+
+ return result;
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+
+});
+
+//#############################################################################
diff --git a/frontend/gamma/js/Clipperz/DOM.js b/frontend/gamma/js/Clipperz/DOM.js
new file mode 100644
index 0000000..40720d8
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/DOM.js
@@ -0,0 +1,139 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.DOM) == 'undefined') { Clipperz.DOM = {}; }
+
+Clipperz.DOM.VERSION = "0.1";
+Clipperz.DOM.NAME = "Clipperz.DOM";
+
+MochiKit.Base.update(Clipperz.DOM, {
+
+ //-------------------------------------------------------------------------
+
+ '__repr__': function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return this.__repr__();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'selectOptionMatchingValue': function (aSelectElement, aValue, shouldUseCaseInsensitiveTest) {
+ var selectedOptionIndex;
+ var i, c;
+
+ selectedOptionIndex = -1;
+
+ c = aSelectElement.options.length;
+ for (i=0; (i<c) && (selectedOptionIndex == -1); i++) {
+ if (shouldUseCaseInsensitiveTest == true) {
+ if (aSelectElement.options[i].value.toLowerCase() == aValue.toLowerCase()) {
+ selectedOptionIndex = i;
+ }
+ } else {
+ if (aSelectElement.options[i].value == aValue) {
+ selectedOptionIndex = i;
+ }
+ }
+ }
+
+ if (selectedOptionIndex != -1) {
+ aSelectElement.selectedIndex = selectedOptionIndex;
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setFormContents': function(aNode, someValues) {
+ var node;
+ var values;
+ var i, c;
+
+ values = {};
+ c = someValues[0].length;
+ for (i=0; i<c; i++) {
+ values[someValues[0][i]] = someValues[1][i];
+ }
+
+// var m = MochiKit.Base;
+// var self = MochiKit.DOM;
+ if (typeof(aNode) == "undefined" || aNode === null) {
+ node = MochiKit.DOM._document.body;
+ } else {
+ node = MochiKit.DOM.getElement(aNode);
+ }
+
+ MochiKit.Base.nodeWalk(node, function(aNode) {
+ var result;
+ var name;
+
+ result = null;
+ name = aNode.name;
+ if (MochiKit.Base.isNotEmpty(name) && (typeof(values[name]) != 'undefined')) {
+ var tagName;
+
+ tagName = aNode.tagName.toUpperCase();
+ if (tagName === "INPUT" && (aNode.type == "radio" || aNode.type == "checkbox")) {
+ aNode.checked = values[name];
+ } else if (tagName === "SELECT") {
+ if (aNode.type == "select-one") {
+ Clipperz.DOM.selectOptionMatchingValue(aNode, values[name]);
+ } else { // aNode.type == "select-multiple"
+MochiKit.Logging.logWarning("### unhandled Select.type = 'select-multiple' condition");
+ }
+ } else if (tagName === "FORM" || tagName === "P" || tagName === "SPAN" || tagName === "DIV") {
+ result = aNode.childNodes;
+ } else {
+ aNode.value = values[name]
+ }
+ } else {
+ result = aNode.childNodes;
+ }
+
+ return result;
+ });
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'get': MochiKit.DOM.getElement,
+
+ //-------------------------------------------------------------------------
+
+ 'Helper': Clipperz.YUI.DomHelper,
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
diff --git a/frontend/gamma/js/Clipperz/Date.js b/frontend/gamma/js/Clipperz/Date.js
new file mode 100644
index 0000000..4103b88
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Date.js
@@ -0,0 +1,305 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.Date) == 'undefined') { Clipperz.Date = {}; }
+
+Clipperz.Date.VERSION = "0.1";
+Clipperz.Date.NAME = "Clipperz.Date";
+
+MochiKit.Base.update(Clipperz.Date, {
+
+ //-------------------------------------------------------------------------
+
+ '__repr__': function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return this.__repr__();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'daysInMonth': [31,28,31,30,31,30,31,31,30,31,30,31],
+
+ //-------------------------------------------------------------------------
+
+ 'englishOrdinalDaySuffixForDate': function(aDate) {
+ var result;
+
+ switch (aDate.getDate()) {
+ case 1:
+ case 21:
+ case 31:
+ result = "st";
+ break;
+ case 2:
+ case 22:
+ result = "nd";
+ break;
+ case 3:
+ case 23:
+ result = "rd";
+ break;
+ default:
+ result = "th";
+ break;
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isLeapYear': function(aDate) {
+ var year;
+ var result;
+
+ year = aDate.getFullYear();
+ result = ((year & 0x03) == 0 && (year % 100 || (year % 400 == 0 && year)));
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getDaysInMonth': function(aDate) {
+ var result;
+
+ if (aDate.getMonth() == 1) {
+ Clipperz.Date.isLeapYear(aDate)
+ result += Clipperz.Date.isLeapYear(aDate) ? 29 : 28;
+ } else {
+ result = Clipperz.Date.daysInMonth[aDate.getMonth()];
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getTimezone': function(aDate) {
+ var result;
+
+ result = aDate.toString();
+ result = result.replace(/([A-Z]{3}) [0-9]{4}/, '$1');
+ result = result.replace(/^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, "$1$2$3");
+
+ return result;
+ },
+
+ 'getGMTOffset': function(aDate) {
+ return (aDate.getTimezoneOffset() > 0 ? "-" : "+") + MochiKit.Format.numberFormatter('00')(Math.floor(this.getTimezoneOffset() / 60))
+ + MochiKit.Format.numberFormatter('00')(this.getTimezoneOffset() % 60);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'dayOfYear': function(aDate) {
+ var result;
+ var i,c;
+
+ result = 0;
+ c = aDate.getMonth();
+ for (i=0; i<c; i++) {
+ if (i == 1) {
+ result += Clipperz.Date.isLeapYear(aDate) ? 29 : 28;
+ } else {
+ result += Clipperz.Date.daysInMonth[i];
+ }
+ }
+ return num + this.getDate() - 1;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getPHPLikeFormatCode': function(aCharacter) {
+ var result;
+
+ switch (aCharacter) {
+ case "d":
+ result = " + MochiKit.Format.numberFormatter('00')(aDate.getDate())";
+ break;
+ case "D":
+ result = " + aLocale['shortDays'][aDate.getDay()]";
+ break;
+ case "j":
+ result = " + aDate.getDate()";
+ break;
+ case "l":
+ result = " + aLocale['days'][aDate.getDay()]";
+ break;
+ case "S":
+ result = " + Clipperz.Date.englishOrdinalDaySuffixForDate(aDate)";
+ break;
+ case "w":
+ result = " + aDate.getDay()";
+ break;
+ case "z":
+ result = " + aDate.getDayOfYear()";
+ break;
+ case "W":
+ result = " + aDate.getWeekOfYear()";
+ break;
+ case "F":
+ result = " + aLocale['months'][aDate.getMonth()]";
+ break;
+ case "m":
+ result = " + MochiKit.Format.numberFormatter('00')(aDate.getMonth() + 1)";
+ break;
+ case "M":
+ result = " + aLocale['shortMonths'][aDate.getMonth()]";
+ break;
+ case "n":
+ result = " + (aDate.getMonth() + 1)";
+ break;
+ case "t":
+ result = " + Clipperz.Date.getDaysInMonth(aDate)";
+ break;
+ case "L":
+ result = " + (Clipperz.Date.isLeapYear(aDate) ? 1 : 0)";
+ break;
+ case "Y":
+ result = " + aDate.getFullYear()";
+ break;
+ case "y":
+ result = " + ('' + aDate.getFullYear()).substring(2, 4)";
+ break;
+ case "a":
+ result = " + (aDate.getHours() < 12 ? aLocale['amDesignation'] : aLocale['pmDesignation'])";
+ break;
+ case "A":
+ result = " + (aDate.getHours() < 12 ? aLocale['amDesignation'].toUpperCase() : aLocale['pmDesignation'].toUpperCase())";
+ break;
+ case "g":
+ result = " + ((aDate.getHours() %12) ? aDate.getHours() % 12 : 12)";
+ break;
+ case "G":
+ result = " + aDate.getHours()";
+ break;
+ case "h":
+ result = " + MochiKit.Format.numberFormatter('00')((aDate.getHours() %12) ? aDate.getHours() % 12 : 12)";
+ break;
+ case "H":
+ result = " + MochiKit.Format.numberFormatter('00')(aDate.getHours())";
+ break;
+ case "i":
+ result = " + MochiKit.Format.numberFormatter('00')(aDate.getMinutes())";
+ break;
+ case "s":
+ result = " + MochiKit.Format.numberFormatter('00')(aDate.getSeconds())";
+ break;
+ case "O":
+ result = " + aDate.getGMTOffset()";
+ break;
+ case "T":
+ result = " + Clipperz.Date.getTimezone(aDate)";
+ break;
+ case "Z":
+ result = " + ( + aDate.getTimezoneOffset() * -60)";
+ break;
+ default:
+ result = " + '" + aCharacter + "'";
+ break;
+ };
+
+ return result;
+ },
+
+ //=========================================================================
+
+ 'formatDateWithPHPLikeTemplateAndLocale': function(aDate, aFormat, aLocale) {
+ var result;
+ var formatterCode;
+ var formatter;
+ var i,c;
+
+//MochiKit.Logging.logDebug(">>> Clipperz.Date.formatDateWithPHPLikeTemplateAndLocale");
+ formatterCode = "Clipperz.Date.__scratchFormatter = function(aDate, aLocale){return ''";
+
+ c = aFormat.length;
+ i = 0;
+
+ while (i<c) {
+ var character;
+
+ character = aFormat.charAt(i);
+ if (character == "\\") {
+ i++;
+ character = aFormat.charAt(i);
+ formatterCode += " + '" + character + "'"
+ } else {
+ formatterCode += Clipperz.Date.getPHPLikeFormatCode(character);
+ }
+
+ i++;
+ }
+
+ formatterCode += ";}";
+//MochiKit.Logging.logDebug("--- Clipperz.Date.formatDateWithPHPLikeTemplateAndLocale - formatterCode: " + formatterCode);
+ eval(formatterCode);
+
+ result = Clipperz.Date.__scratchFormatter.call(this, aDate, aLocale);
+ delete Clipperz.Date.__scratchFormatter;
+//MochiKit.Logging.logDebug("<<< Clipperz.Date.formatDateWithPHPLikeTemplateAndLocale");
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'parseDateWithPHPLikeTemplateAndLocale': function(aString, aFormat, aLocale) {
+ return new Date();
+ },
+
+ //=========================================================================
+
+ 'formatDateWithUTCFormatAndLocale': function(aDate, aLocale) {
+// return Clipperz.Date.formatWithJavaLikeTemplateAndLocale(aDate, "EEE, dd MMMM yyyy HH:mm:ss zzz", aLocale);
+ return aDate.toString();
+ },
+
+ 'parseDateWithUTCFormatAndLocale': function(aValue, aLocale) {
+ return new Date(Date.parse(aValue));
+ },
+
+ //=========================================================================
+
+ 'exception': {
+// 'AbstractMethod': new MochiKit.Base.NamedError("Clipperz.Base.exception.AbstractMethod"),
+// 'UnknownType': new MochiKit.Base.NamedError("Clipperz.Base.exception.UnknownType")
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
diff --git a/frontend/gamma/js/Clipperz/KeePassExportProcessor.js b/frontend/gamma/js/Clipperz/KeePassExportProcessor.js
new file mode 100644
index 0000000..06ab5a8
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/KeePassExportProcessor.js
@@ -0,0 +1,196 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+
+
+Clipperz.KeePassExportProcessor = function(args) {
+ args = args || {};
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.KeePassExportProcessor.prototype = MochiKit.Base.update(null, {
+
+ //-------------------------------------------------------------------------
+
+ 'deferredParse_core': function(aContext) {
+ var deferredResult;
+
+ if (aContext.line == "") {
+ deferredResult = MochiKit.Async.succeed(aContext.result);
+ } else {
+ var record;
+
+ record = this.parseRecord(aContext);
+ if (record != null) {
+ aContext.result.push(record);
+ }
+
+ aContext.line = aContext.line.replace(/^\n*/g, "").replace(/\n$/g, "");
+
+ deferredResult = new Clipperz.Async.Deferred("KeePassExportProcessor.deferredParse_core");
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'importProcessorProgressUpdate', {status:'processing', size:aContext.size, progress:(aContext.size - aContext.line.length)});
+ deferredResult.addCallback(MochiKit.Async.wait, 0.2);
+ deferredResult.addMethod(this, 'deferredParse_core');
+ deferredResult.callback(aContext);
+ }
+
+ return deferredResult;
+ },
+
+ //.........................................................................
+
+ 'deferredParse': function(aValue) {
+ var deferredResult;
+ var lines;
+ var context;
+
+ lines = aValue.replace(/\r?\n/g, "\n");
+ context = {
+ line: lines,
+ size: lines.length,
+ result: []
+ }
+
+ deferredResult = new Clipperz.Async.Deferred("KeePassExportProcessor.deferredResult");
+ deferredResult.addMethod(this, 'deferredParse_core');
+ deferredResult.callback(context);
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'parseRecord': function(aContext) {
+ var result;
+ var recordLabelRegexp;
+ var fieldLabelRegexp;
+ var fieldValueRegexp;
+ var fullLineRegexp;
+/*
+[Record name]
+Group Tree:
+UserName:
+URL:
+Password:
+Notes: test
+UUID: 525f62430079bae48b79ed2961924b05
+Icon: 0
+Creation Time: 2007-06-26 17:56:03
+Last Access: 2007-10-25 16:23:51
+Last Modification: 2007-10-25 16:23:51
+Expires: 2999-12-28 23:59:59
+
+[Record name] ==> Title
+Group: General ==> Group
+Group Tree: ==> Group Tree
+UserName: ==> UserName
+URL: ==> URL
+Password: ==> Password
+Notes: test ==> Notes
+UUID: 525f62430079bae48b79ed2961924b05 ==> UUID
+Icon: 0 ==> Icon
+Creation Time: 2007-06-26 17:56:03 ==> Creation Time
+Last Access: 2007-10-25 16:23:51 ==> Last Access
+Last Modification: 2007-10-25 16:23:51 ==> Last Modification
+Expires: 2999-12-28 23:59:59 ==> Expires
+Attachment Description: ==> Attachment Description
+Attachment: ==> Attachment
+*/
+// recordLabelRegexp = new RegExp("(^\\[(.*)\\]\\n|^Title:\s*(.*)\\n)");
+ recordLabelRegexp = new RegExp("^\\[(.*)\\]\\n|^Title:\s*(.*)\\n");
+ fieldLabelRegexp = new RegExp("^\s?(Group|Group Tree|Username|UserName|User Name|Url|URL|Password|Notes|Comment|UUID|Icon|Creation Time|Last Access|Last Modification|Expires|Attachment Description|Attachment|Valid until): ");
+ fieldValueRegexp = new RegExp("(.*)(\\n|$)");
+ fullLineRegexp = new RegExp("^(.*\\n)");
+
+ if (recordLabelRegexp.test(aContext.line) == true) {
+ var line;
+
+ line = aContext.line;
+
+ result = {};
+ result['Title'] = line.match(recordLabelRegexp)[1];
+ line = line.replace(/^.*\n/, "");
+ while (fieldLabelRegexp.test(line) == true) {
+ var fieldName;
+ var fieldValue;
+
+ fieldName = RegExp.$1;
+ line = RegExp.rightContext;
+
+ fieldValue = line.match(fieldValueRegexp)[1];
+ line = RegExp.rightContext;
+
+ if (fieldName == 'Notes') {
+ var isMultiline;
+
+ isMultiline = false;
+
+ if ((line != "") && (fieldLabelRegexp.test(line) == false) && (recordLabelRegexp.test(line) == false)) {
+ fieldValue += '\n';
+ }
+
+ while ((line != "") && (fieldLabelRegexp.test(line) == false) && (recordLabelRegexp.test(line) == false)) {
+ var newLineValue;
+
+ newLineValue = line.match(fullLineRegexp)[1];
+ if (newLineValue != "\n") {
+ isMultiline = true;
+ }
+ fieldValue += newLineValue;
+ line = RegExp.rightContext;
+ }
+
+ if (isMultiline) {
+ fieldValue = fieldValue.replace(/\n$/g, "");
+ } else {
+ fieldValue = fieldValue.replace(/\n\n$/g, "");
+ }
+
+ line = line.replace(/^\n/, '');
+ }
+
+ result[fieldName] = fieldValue;
+ }
+ } else {
+ result = null;
+ }
+
+ aContext.line = line;
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+
diff --git a/frontend/gamma/js/Clipperz/KeyValueObjectStore.js b/frontend/gamma/js/Clipperz/KeyValueObjectStore.js
new file mode 100644
index 0000000..04beb85
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/KeyValueObjectStore.js
@@ -0,0 +1,176 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+
+//#############################################################################
+
+Clipperz.KeyValueObjectStore = function(args) {
+ args = args || {};
+
+// this._name = args['name'] || "unnamed KeyValueObjectStore";
+ this._values = args['values'] || {};
+// this._referenceObjectStore = null;
+//console.log("new KeyValueObjectStore", args, this._values);
+
+ return this;
+}
+
+Clipperz.KeyValueObjectStore.prototype = MochiKit.Base.update(null, {
+
+ 'values': function() {
+ return this._values;
+ },
+
+ 'initWithValues': function (someValues) {
+ this._values = Clipperz.Base.deepClone(someValues) || {};
+ return this;
+ },
+
+ 'setValues': function (someValues) {
+//console.log("KeyValueObjectStore.setValues", someValues);
+ this._values = someValues;
+ return this;
+ },
+
+// 'initWithObjectStore': function (anObjectStore) {
+// this._referenceObjectStore = anObjectStore;
+// },
+
+ 'removeAllData': function () {
+ this._values = {};
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getValue': function(aKeyPath) {
+ var result;
+ var keys;
+ var i,c;
+
+ result = this.values();
+
+ keys = (aKeyPath + '').split('.');
+ c = keys.length;
+ i = 0;
+
+ while ((i<c) && (result != null)) {
+ if (typeof result[keys[i]] != 'undefined') {
+ result = result[keys[i]];
+ } else {
+ result = null;
+ }
+
+ i++;
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setValue': function(aKeyPath, aValue) {
+ var targetObject;
+ var keys;
+ var i,c;
+
+//console.log(">>> KeyValueObjectStore.setValue", this, this.values(), aKeyPath, aValue);
+ targetObject = this.values();
+ keys = (aKeyPath + '').split('.');
+ c = keys.length - 1;
+ for (i=0; i<c; i++) {
+//console.log("--- KeyValueObjectStore.setValue", i, targetObject, keys[i]);
+ if (typeof targetObject[keys[i]] == 'undefined') {
+ targetObject[keys[i]] = {}
+ }
+
+ targetObject = targetObject[keys[i]];
+ }
+
+ targetObject[keys[c]] = aValue;
+//console.log("<<< KeyValueObjectStore.setValue");
+
+ return aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'removeValue': function (aKeyPath) {
+// this.setValue(aKeyPath, null);
+
+ var targetObject;
+ var keys;
+ var i,c;
+
+ targetObject = this.values();
+ keys = ('' + aKeyPath).split('.');
+ c = keys.length - 1;
+ for (i=0; i<c; i++) {
+ if (typeof targetObject[keys[i]] == 'undefined') {
+ targetObject[keys[i]] = {}
+ }
+
+ targetObject = targetObject[keys[i]];
+ }
+
+ delete targetObject[keys[c]];
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredGetOrSet': function(aKeyPath, aGetterFunction) {
+ var deferredResult;
+
+ if (this.getValue(aKeyPath) != null) {
+ deferredResult = MochiKit.Async.succeed(this.getValue(aKeyPath));
+ } else {
+ deferredResult = new Clipperz.Async.Deferred("KeyValueObjectStore.deferredGetOrSet [" + aKeyPath + "]", {trace:false});
+
+ deferredResult.addCallback(aGetterFunction);
+ deferredResult.addMethod(this, 'setValue', aKeyPath);
+ deferredResult.callback();
+ }
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isEmpty': function () {
+ return (MochiKit.Base.keys(this.values()).length == 0)
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'dumpData': function () {
+ return Clipperz.Base.serializeJSON(this.values());
+ },
+*/
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/Logging.js b/frontend/gamma/js/Clipperz/Logging.js
new file mode 100644
index 0000000..d6c107e
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Logging.js
@@ -0,0 +1,42 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz');
+
+if (typeof console == 'undefined') {
+ Clipperz.log = MochiKit.Logging.logDebug;
+// Safari/WebKit 4
+} else if (navigator.userAgent.match(/WebKit/)) {
+// Clipperz.log = console.log;
+ Clipperz.log = MochiKit.Logging.logDebug;
+} else if (navigator.userAgent.match(/Gecko/)) {
+ Clipperz.log = function () {
+// firebug 1.3 bug see http://code.google.com/p/fbug/issues/detail?id=1347
+ console.log.apply(window._firebug, arguments);
+ };
+} \ No newline at end of file
diff --git a/frontend/gamma/js/Clipperz/PM/BookmarkletProcessor.js b/frontend/gamma/js/Clipperz/PM/BookmarkletProcessor.js
new file mode 100644
index 0000000..789d6b8
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/BookmarkletProcessor.js
@@ -0,0 +1,196 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+
+Clipperz.PM.BookmarkletProcessor = function(aConfiguration) {
+ this._configuration = aConfiguration;
+
+ this._editableFields = null;
+ this._favicon = null;
+
+ return this;
+}
+
+Clipperz.PM.BookmarkletProcessor.prototype = MochiKit.Base.update(null, {
+
+ 'toString': function() {
+ return "Clipperz.PM.BookmarkletProcessor";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'configuration': function() {
+ return this._configuration;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'pageTitle': function() {
+ return this.configuration().page.title;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'fields': function() {
+ return this.configuration().form.inputs;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'editableFields': function() {
+ if (this._editableFields == null) {
+ this._editableFields = MochiKit.Base.filter(function(aField) {
+ var result;
+ var type;
+
+ type = aField['type'].toLowerCase();
+ result = ((type != 'hidden') && (type != 'submit') && (type != 'checkbox') && (type != 'radio') && (type != 'select'));
+
+ return result;
+ }, this.fields())
+ }
+
+ return this._editableFields;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hostname': function() {
+ if (this._hostname == null) {
+ var actionUrl;
+
+ actionUrl = this.configuration()['form']['attributes']['action'];
+ this._hostname = actionUrl.replace(/ ^ h t t p s ? : \ / \ / ( [ ^ \ / ] * ) \ / . * /, '$1');
+ }
+
+ return this._hostname;
+ },
+
+ 'favicon': function() {
+ if (this._favicon == null) {
+ this._favicon = "http://" + this.hostname() + "/favicon.ico";
+ }
+
+ return this._favicon;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+//#############################################################################
+/ *
+Clipperz.PM.BookmarkletProcessor.createRecordFromBookmarkletConfiguration = function(anUser, aConfiguration) {
+ var processor;
+ var record;
+ var recordVersion;
+ var directLogin;
+ var bindings;
+ var i,c;
+
+ processor = new Clipperz.PM.BookmarkletProcessor(aConfiguration);
+
+ record = new Clipperz.PM.DataModel.Record({
+ 'label': processor.pageTitle(),
+ 'notes': "",
+ 'user': anUser
+ });
+ recordVersion = new Clipperz.PM.DataModel.Record.Version(record, {})
+ record.setCurrentVersion(recordVersion);
+
+ bindings = {};
+
+ c = processor.editableFields().length;
+ for (i=0; i<c; i++) {
+ var formField;
+ var recordField;
+
+ formField = processor.editableFields()[i];
+ recordField = new Clipperz.PM.DataModel.RecordField({
+ 'label': formField['name'],
+ 'value': formField['value'],
+ 'type': Clipperz.PM.Strings.inputTypeToRecordFieldType[formField['type']],
+ 'hidden': false,
+ 'recordVersion': recordVersion
+ });
+ recordVersion.addField(recordField);
+
+ bindings[formField['name']] = recordField.key();
+ }
+
+ directLogin = new Clipperz.PM.DataModel.DirectLogin({
+ 'record': record,
+ 'label': processor.pageTitle(),
+ 'favicon': processor.favicon(),
+ 'formData': processor.configuration()['form'],
+ 'bindingData': bindings,
+ 'bookmarkletVersion': '0.2'
+ });
+ record.addDirectLogin(directLogin);
+
+ anUser.addRecord(record);
+
+ return record;
+};
+* /
+//-----------------------------------------------------------------------------
+
+Clipperz.PM.BookmarkletProcessor.sanitizeBookmarkletConfiguration = function(aConfiguration) {
+ var result;
+
+// throw "XSS Bookmarklet attempt";
+
+ result = aConfiguration;
+
+ return result;
+};
+
+//-----------------------------------------------------------------------------
+
+Clipperz.PM.BookmarkletProcessor.checkBookmarkletConfiguration = function(aConfiguration) {
+ var result;
+
+ try {
+ result = Clipperz.Base.evalJSON(aConfiguration);
+ result = Clipperz.PM.BookmarkletProcessor.sanitizeBookmarkletConfiguration(result);
+
+ if (result['version'] != '0.2.3') {
+ throw "WrongBookmarkletVersion";
+ }
+ } catch (exception) {
+ throw exception;
+ }
+
+ return result;
+};
+
+//-----------------------------------------------------------------------------
+*/ \ No newline at end of file
diff --git a/frontend/gamma/js/Clipperz/PM/Connection.js b/frontend/gamma/js/Clipperz/PM/Connection.js
new file mode 100644
index 0000000..6e58c60
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/Connection.js
@@ -0,0 +1,619 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+
+//-----------------------------------------------------------------------------
+//
+// Abstract C O N N E C T I O N class
+//
+//-----------------------------------------------------------------------------
+
+Clipperz.PM.Connection = function (args) {
+ args = args || {};
+
+ this._proxy = args.proxy || Clipperz.PM.Proxy.defaultProxy;
+ this._getCredentialsFunction = args.getCredentialsFunction;
+
+ this._clipperz_pm_crypto_version = null;
+ this._connectionId = null;
+ this._sharedSecret = null;
+
+ return this;
+}
+
+Clipperz.PM.Connection.prototype = MochiKit.Base.update(null, {
+
+ 'toString': function() {
+ return "Connection [" + this.version() + "]";
+ },
+
+ //=========================================================================
+
+ 'version': function() {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ 'clipperz_pm_crypto_version': function() {
+ if (this._clipperz_pm_crypto_version == null) {
+ var connectionVersions;
+ var versions;
+ var version;
+ var i, c;
+
+ version = null;
+ connectionVersions = Clipperz.PM.Connection.communicationProtocol.versions;
+ versions = MochiKit.Base.keys(connectionVersions);
+ c = versions.length;
+ for (i=0; i<c; i++) {
+ if (! (versions[i] == 'current')) {
+ if (this instanceof connectionVersions[versions[i]]) {
+ version = versions[i];
+ };
+ }
+ }
+
+ this._clipperz_pm_crypto_version = version;
+ }
+
+ return this._clipperz_pm_crypto_version;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'defaultErrorHandler': function(anErrorString, anException) {
+MochiKit.Logging.logError("### Connection.defaultErrorHandler: " + anErrorString + " (" + anException + ")");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getCredentialsFunction': function () {
+ return this._getCredentialsFunction;
+ },
+
+ 'normalizedCredentials': function(someValues) {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //=========================================================================
+
+ 'proxy': function () {
+ return this._proxy;
+ },
+
+ //=========================================================================
+
+ 'register': function () {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ 'login': function() {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'message': function(someArguments, aCallback) {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'serverSideUserCredentials': function() {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //=========================================================================
+
+ 'sharedSecret': function () {
+ return this._sharedSecret;
+ },
+
+ 'setSharedSecret': function (aValue) {
+ this._sharedSecret = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'connectionId': function() {
+ return this._connectionId;
+ },
+
+ 'setConnectionId': function(aValue) {
+ this._connectionId = aValue;
+ },
+
+ //=========================================================================
+/*
+// TODO: ?????
+ 'oneTimePassword': function() {
+ return this._oneTimePassword;
+ },
+
+ 'setOneTimePassword': function(aValue) {
+ this._oneTimePassword = aValue;
+ },
+*/
+ //=========================================================================
+
+ 'reset': function() {
+ this.setSharedSecret(null);
+ this.setConnectionId(null);
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+
+}
+);
+
+
+if (typeof(Clipperz.PM.Connection.SRP) == 'undefined') { Clipperz.PM.Connection.SRP = {}; }
+//-----------------------------------------------------------------------------
+//
+// S R P [ 1 . 0 ] C O N N E C T I O N class
+//
+//-----------------------------------------------------------------------------
+
+Clipperz.PM.Connection.SRP['1.0'] = function (args) {
+ Clipperz.PM.Connection.call(this, args);
+
+ return this;
+}
+
+Clipperz.PM.Connection.SRP['1.0'].prototype = MochiKit.Base.update(new Clipperz.PM.Connection(), {
+
+ 'version': function() {
+ return '1.0';
+ },
+
+ //=========================================================================
+
+ 'register': function (someUserData) {
+ var deferredResult;
+ var cryptoVersion;
+ var srpConnection;
+
+ cryptoVersion = this.clipperz_pm_crypto_version();
+
+ deferredResult = new Clipperz.Async.Deferred("Connection.registerWithVersion", {trace:false});
+ deferredResult.collectResults({
+ 'credentials': [
+ this.getCredentialsFunction(),
+ MochiKit.Base.method(this, 'normalizedCredentials'),
+ MochiKit.Base.bind(function(someCredentials) {
+ var srpConnection;
+ var result;
+
+ srpConnection = new Clipperz.Crypto.SRP.Connection({ C:someCredentials['username'], P:someCredentials['password'], hash:this.hash() });
+ result = srpConnection.serverSideCredentials();
+ result['version'] = Clipperz.PM.Connection.communicationProtocol.currentVersion;
+
+ return result;
+ }, this)
+ ],
+ 'user': MochiKit.Base.partial(MochiKit.Async.succeed, someUserData),
+ 'version': MochiKit.Base.partial(MochiKit.Async.succeed, Clipperz.PM.Connection.communicationProtocol.currentVersion),
+ 'message': MochiKit.Base.partial(MochiKit.Async.succeed, 'completeRegistration')
+ });
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ deferredResult.addMethod(this.proxy(), 'registration');
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateCredentials': function (aUsername, aPassphrase, someUserData) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Connection.updateCredentials", {trace:false});
+ deferredResult.collectResults({
+ 'credentials': [
+ MochiKit.Base.method(this, 'normalizedCredentials', {username:aUsername, password:aPassphrase}),
+ MochiKit.Base.bind(function(someCredentials) {
+ var srpConnection;
+ var result;
+
+ srpConnection = new Clipperz.Crypto.SRP.Connection({ C:someCredentials['username'], P:someCredentials['password'], hash:this.hash() });
+ result = srpConnection.serverSideCredentials();
+ result['version'] = Clipperz.PM.Connection.communicationProtocol.currentVersion;
+
+ return result;
+ }, this)
+ ],
+ 'user': MochiKit.Base.partial(MochiKit.Async.succeed, someUserData)
+ });
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ deferredResult.addMethod(this, 'message', 'upgradeUserCredentials');
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ deferredResult.callback();
+
+ return deferredResult;
+
+ },
+
+ //=========================================================================
+
+ 'redeemOneTimePassword': function (someParameters) {
+//console.log("Connections.redeemOneTimePassword", someParameters['username'], someParameters['password']);
+/*
+ //=========================================================================
+ // LOGIN WITH PASSPHRASE, extracted from the TRUNK version (LoginPanel.js)
+ deferredResult.addCallback(function(anUsername, aOneTimePassword) {
+ var args;
+
+ args = {
+ 'message': 'oneTimePassword',
+ 'version': Clipperz.PM.Crypto.communicationProtocol.currentVersion,
+ 'parameters': {
+ 'oneTimePasswordKey': Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword(anUsername, aOneTimePassword),
+ 'oneTimePasswordKeyChecksum': Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(anUsername, aOneTimePassword)
+ }
+ }
+
+ return args;
+ }, anUsername, oneTimePassword);
+ deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'OTP_login_loadingOTP');
+ deferredResult.addCallback(MochiKit.Base.method(Clipperz.PM.Proxy.defaultProxy, 'handshake'));
+ deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'OTP_login_extractingPassphrase');
+ deferredResult.addCallback(function(aResult) {
+ return Clipperz.PM.Crypto.deferredDecrypt(oneTimePassword, aResult['data'], aResult['version']);
+ });
+ deferredResult.addCallback(function(aResult) {
+ return (new Clipperz.ByteArray().appendBase64String(aResult['passphrase'])).asString();
+ });
+ deferredResult.addMethod(this, 'doLoginWithUsernameAndPassphrase', anUsername),
+*/
+ var args;
+ var normalizedOTP;
+
+ normalizedOTP = Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword(someParameters['password']);
+
+ args = {
+ 'message': 'oneTimePassword',
+ 'version': Clipperz.PM.Connection.communicationProtocol.currentVersion,
+ 'parameters': {
+ 'oneTimePasswordKey': Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword(someParameters['username'], normalizedOTP),
+ 'oneTimePasswordKeyChecksum': Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(someParameters['username'], normalizedOTP)
+ }
+ }
+
+ return Clipperz.Async.callbacks("Connction.redeemOTP", [
+ MochiKit.Base.method(this.proxy(), 'handshake', args),
+ function(aResult) {
+ return Clipperz.PM.Crypto.deferredDecrypt({
+ value: aResult['data'],
+ key: normalizedOTP,
+ version:aResult['version']
+ });
+ },
+ function(aResult) {
+ return (new Clipperz.ByteArray().appendBase64String(aResult['passphrase'])).asString();
+ }
+ ], {trace:false})
+ },
+
+ 'login': function(/*anUsername, aPassphrase*/) {
+ var deferredResult;
+ var cryptoVersion;
+ var srpConnection;
+
+ cryptoVersion = this.clipperz_pm_crypto_version();
+
+ deferredResult = new Clipperz.Async.Deferred("Connection.login", {trace:false});
+ deferredResult.addCallback(this.getCredentialsFunction());
+ deferredResult.addMethod(this, 'normalizedCredentials');
+// deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_sendingCredentials');
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ deferredResult.addCallback(MochiKit.Base.bind(function(someCredentials) {
+ srpConnection = new Clipperz.Crypto.SRP.Connection({ C:someCredentials['username'], P:someCredentials['password'], hash:this.hash() });
+ }, this));
+ deferredResult.addCallback(function() {
+ var result;
+
+ result = {
+ message: 'connect',
+ version: cryptoVersion,
+ parameters: {
+ C: srpConnection.C(),
+ A: srpConnection.A().asString(16)
+// reconnecting: this.connectionId()
+ }
+ };
+
+// TODO: ?????
+// if (isReconnecting == true) {
+// args.parameters['reconnecting'] = aConnection.connectionId();
+// }
+
+ return result;
+ });
+ deferredResult.addMethod(this.proxy(), 'handshake');
+// deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_credentialVerification');
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ deferredResult.addCallback(function(someParameters) {
+ var result;
+
+ srpConnection.set_s(new Clipperz.Crypto.BigInt(someParameters['s'], 16));
+ srpConnection.set_B(new Clipperz.Crypto.BigInt(someParameters['B'], 16));
+
+// TODO: ?????
+// if (typeof(someParameters['oneTimePassword']) != 'undefined') {
+// this.setOneTimePassword(someParameters['oneTimePassword']);
+// }
+
+ result = {
+ message: 'credentialCheck',
+ version: cryptoVersion,
+ parameters: {
+ M1: srpConnection.M1()
+ }
+ };
+
+ return result;
+ });
+ deferredResult.addMethod(this.proxy(), 'handshake');
+ deferredResult.addCallback(function(someParameters) {
+ var result;
+
+ if (someParameters['M2'] == srpConnection.M2()) {
+ result = MochiKit.Async.succeed(someParameters);
+ } else {
+ result = MochiKit.Async.fail(Clipperz.PM.Connection.exception.WrongChecksum);
+ }
+
+ return result;
+ });
+ deferredResult.addCallback(MochiKit.Base.bind(function(someParameters) {
+ this.setConnectionId(someParameters['connectionId']);
+ this.setSharedSecret(srpConnection.K());
+
+// TODO: ?????
+// if (this.oneTimePassword() != null) {
+/// ?? result = this.user().oneTimePasswordManager().archiveOneTimePassword(this.oneTimePassword()));
+// }
+ return someParameters;
+ }, this));
+// deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'updatedProgressState', 'connection_loggedIn');
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ deferredResult.addCallback(MochiKit.Async.succeed, {result:"done"});
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'logout': function() {
+ return Clipperz.Async.callbacks("Connection.logout", [
+ MochiKit.Base.method(this, 'setSharedSecret'),
+ MochiKit.Base.method(this.proxy(), 'logout', {})
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'ping': function () {
+ // TODO: ping the server in order to have a valid session
+ },
+
+ //=========================================================================
+
+ 'message': function(aMessageName, someParameters) {
+ var args;
+
+//console.log(">>> Connection.message", aMessageName, someParameters);
+ args = {
+ message: aMessageName,
+ srpSharedSecret: this.sharedSecret(),
+ parameters: (someParameters || {})
+ }
+
+ return this.sendMessage(args);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'sendMessage': function(someArguments) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Connection.sendMessage", {trace:false});
+ deferredResult.addMethod(this.proxy(), 'message', someArguments);
+ deferredResult.addCallback(MochiKit.Base.bind(function(res) {
+ if (typeof(res['lock']) != 'undefined') {
+// TODO: ?????
+// ?? this.user().setLock(res['lock']);
+ }
+ return res;
+ }, this));
+
+ deferredResult.addErrback(MochiKit.Base.method(this, 'messageExceptionHandler'), someArguments);
+ deferredResult.callback();
+
+ return deferredResult
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'messageExceptionHandler': function(anOriginalMessageArguments, anError) {
+ var result;
+
+console.log(">>> Connection.messageExceptionHandler", anError, anError.message);
+ if (anError instanceof MochiKit.Async.CancelledError) {
+ result = anError;
+ } else {
+ if ((anError.message == 'Trying to communicate without an active connection') ||
+ (anError.message == 'No tollManager available for current session')
+ ) {
+ result = this.reestablishConnection(anOriginalMessageArguments);
+ } else if (anError.message == 'Session with stale data') {
+ MochiKit.Signal.signal(this, 'EXCEPTION');
+ } else {
+ result = anError;
+ }
+ }
+console.log("<<< Connection.messageExceptionHandler", anError)
+
+ return result;;
+ },
+
+ //=========================================================================
+
+ 'reestablishConnection': function(anOriginalMessageArguments) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Connection.reestablishConnection");
+ deferredResult.addMethod(this, 'reset');
+ deferredResult.addMethod(this, 'login', true);
+ deferredResult.addCallback(MochiKit.Base.bind(function(aMessage) {
+ aMessage['srpSharedSecret'] = this.sharedSecret();
+ return aMessage;
+ }, this), anOriginalMessageArguments);
+ deferredResult.addMethod(this, 'sendMessage');
+ deferredResult.addErrback(MochiKit.Signal.signal, this, 'EXCEPTION', null);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'serverSideUserCredentials': function(aUsername, aPassword) {
+ var result;
+ var newSrpConnection;
+ var normalizedAttributes;
+
+ normalizedAttributes = this.normalizedCredentials({username:aUsername, password:aPassword});
+ newSrpConnection = new Clipperz.Crypto.SRP.Connection({ C:normalizedAttributes['username'], P:normalizedAttributes['password'], hash:this.hash() });
+ result = newSrpConnection.serverSideCredentials();
+ result['version'] = this.clipperz_pm_crypto_version();
+
+ return result;
+ },
+
+ //=========================================================================
+
+ 'normalizedCredentials': function(someValues) {
+ var result;
+
+ result = {}
+ result['username'] = this.hash()(new Clipperz.ByteArray(someValues['username'])).toHexString().substring(2);
+ result['password'] = this.hash()(new Clipperz.ByteArray(someValues['password'] + someValues['username'])).toHexString().substring(2);
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'hash': function() {
+ return Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].hash;
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
+
+
+//-----------------------------------------------------------------------------
+//
+// S R P [ 1 . 1 ] C O N N E C T I O N class
+//
+//-----------------------------------------------------------------------------
+
+Clipperz.PM.Connection.SRP['1.1'] = function (args) {
+ Clipperz.PM.Connection.SRP['1.0'].call(this, args);
+
+ return this;
+}
+
+Clipperz.PM.Connection.SRP['1.1'].prototype = MochiKit.Base.update(new Clipperz.PM.Connection.SRP['1.0'](), {
+
+ 'version': function() {
+ return '1.1';
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'normalizedCredentials': function(someValues) {
+ var result;
+
+ result = {}
+ result['username'] = this.hash()(new Clipperz.ByteArray(someValues['username'] + someValues['password'])).toHexString().substring(2);
+ result['password'] = this.hash()(new Clipperz.ByteArray(someValues['password'] + someValues['username'])).toHexString().substring(2);
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'hash': function() {
+ return Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].hash;
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
+Clipperz.PM.Connection.exception = {
+ WrongChecksum: new MochiKit.Base.NamedError("Clipperz.ByteArray.exception.InvalidValue"),
+ UnexpectedRequest: new MochiKit.Base.NamedError("Clipperz.ByteArray.exception.UnexpectedRequest")
+};
+
+
+Clipperz.PM.Connection.communicationProtocol = {
+ 'currentVersion': '0.2',
+ 'versions': {
+ '0.1': Clipperz.PM.Connection.SRP['1.0'], //Clipperz.Crypto.SRP.versions['1.0'].Connection,
+ '0.2': Clipperz.PM.Connection.SRP['1.1'] //Clipperz.Crypto.SRP.versions['1.1'].Connection
+ },
+ 'fallbackVersions': {
+// 'current': '0.1',
+ '0.2': '0.1',
+ '0.1': null
+ }
+};
+
+MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.versions, {
+ 'current': Clipperz.PM.Connection.communicationProtocol.versions[Clipperz.PM.Connection.communicationProtocol.currentVersion]
+});
+
+MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.fallbackVersions, {
+ 'current': Clipperz.PM.Connection.communicationProtocol.fallbackVersions[Clipperz.PM.Connection.communicationProtocol.currentVersion]
+});
+
+
+
diff --git a/frontend/gamma/js/Clipperz/PM/Crypto.js b/frontend/gamma/js/Clipperz/PM/Crypto.js
new file mode 100644
index 0000000..bfafbea
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/Crypto.js
@@ -0,0 +1,513 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+if (typeof(Clipperz.PM.Crypto) == 'undefined') { Clipperz.PM.Crypto = {}; }
+
+Clipperz.PM.Crypto.VERSION = "0.2";
+Clipperz.PM.Crypto.NAME = "Clipperz.PM.Crypto";
+
+Clipperz.PM.Crypto.encryptingFunctions = {};
+
+MochiKit.Base.update(Clipperz.PM.Crypto, {
+
+ '__repr__': function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return this.__repr__();
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'communicationProtocol': {
+ 'currentVersion': '0.2',
+ 'versions': {
+ '0.1': Clipperz.PM.Connection.SRP['1.0'], //Clipperz.Crypto.SRP.versions['1.0'].Connection,
+ '0.2': Clipperz.PM.Connection.SRP['1.1'] //Clipperz.Crypto.SRP.versions['1.1'].Connection
+ },
+ 'fallbackVersions': {
+ 'current': '0.1',
+ '0.2': '0.1',
+ '0.1': null
+ }
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'encryptingFunctions': {
+ 'currentVersion': '0.3',
+ 'versions': {
+
+ //#####################################################################
+
+ '0.1': {
+ 'encrypt': function(aKey, aValue) {
+ return Clipperz.Crypto.Base.encryptUsingSecretKey(aKey, Clipperz.Base.serializeJSON(aValue));
+ },
+
+ 'deferredEncrypt': function(aKey, aValue) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Crypto[0.1].deferredEncrypt");
+ deferredResult.addCallback(Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].encrypt, aKey, aValue);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ 'decrypt': function(aKey, aValue) {
+ var result;
+
+ if (aValue != null) {
+ result = Clipperz.Base.evalJSON(Clipperz.Crypto.Base.decryptUsingSecretKey(aKey, aValue));
+ } else {
+ result = null;
+ }
+
+ return result;
+ },
+
+ 'deferredDecrypt': function(aKey, aValue) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Crypto.[0.1].deferredDecrypt");
+ deferredResult.addCallback(Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].decrypt, aKey, aValue);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ 'hash': function(aValue) {
+ var result;
+ var strngResult;
+
+ stringResult = Clipperz.Crypto.Base.computeHashValue(aValue.asString()); // !!!!!!!
+ result = new Clipperz.ByteArray("0x" + stringResult);
+
+ return result;
+ },
+
+ 'deriveKey': function(aStringValue) {
+ return Clipperz.Crypto.Base.computeHashValue(aStringValue);
+ }
+ },
+
+ //#####################################################################
+
+ '0.2': {
+ 'encrypt': function(aKey, aValue, aNonce) {
+ var result;
+ var key, value;
+ var dataToEncrypt;
+ var encryptedData;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ value = new Clipperz.ByteArray(Clipperz.Base.serializeJSON(aValue));
+ dataToEncrypt = Clipperz.Crypto.SHA.sha_d256(value).appendBlock(value);
+ encryptedData = Clipperz.Crypto.AES.encrypt(key, dataToEncrypt, aNonce);
+ result = encryptedData.toBase64String();
+
+ return result;
+ },
+
+ 'deferredEncrypt': function(aKey, aValue, aNonce) {
+ var deferredResult;
+ var key, value;
+ var dataToEncrypt;
+// var encryptedData;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ value = new Clipperz.ByteArray(Clipperz.Base.serializeJSON(aValue));
+ dataToEncrypt = Clipperz.Crypto.SHA.sha_d256(value).appendBlock(value);
+
+ deferredResult = new Clipperz.Async.Deferred("Crypto[0.2].deferredEncrypt")
+ deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncrypt, key, dataToEncrypt, aNonce);
+ deferredResult.addCallback(function(aResult) {
+ return aResult.toBase64String();
+ })
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ 'decrypt': function(aKey, aValue) {
+ var result;
+
+ if (aValue != null) {
+ var key, value;
+ var decryptedData;
+ var decryptedValue;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ value = new Clipperz.ByteArray().appendBase64String(aValue);
+
+ decryptedData = Clipperz.Crypto.AES.decrypt(key, value);
+ decryptedValue = decryptedData.split((256/8));
+
+ try {
+ result = Clipperz.Base.evalJSON(decryptedValue.asString());
+ } catch (exception) {
+ MochiKit.Logging.logError("Error while decrypting data [1]");
+ throw Clipperz.Crypto.Base.exception.CorruptedMessage;
+ }
+ } else {
+ result = null;
+ }
+
+ return result;
+ },
+
+ 'deferredDecrypt': function(aKey, aValue) {
+ var result;
+
+ if (aValue != null) {
+ var deferredResult;
+ var key, value;
+// var decryptedData;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ value = new Clipperz.ByteArray().appendBase64String(aValue);
+
+ deferredResult = new Clipperz.Async.Deferred("Crypto.[0.2].deferredDecrypt");
+ deferredResult.addCallback(Clipperz.Crypto.AES.deferredDecrypt, key, value);
+ deferredResult.addCallback(function(aResult) {
+ var result;
+ var decryptedData;
+
+ decryptedData = aResult.split((256/8));
+
+ try {
+ result = Clipperz.Base.evalJSON(decryptedData.asString());
+ } catch (exception) {
+ MochiKit.Logging.logError("Error while decrypting data [2]");
+ throw Clipperz.Crypto.Base.exception.CorruptedMessage;
+ }
+
+ return result;
+ })
+ deferredResult.callback();
+
+ result = deferredResult;
+ } else {
+ result = MochiKit.Async.succeed(null);
+ }
+
+ return result;
+ },
+
+ 'hash': Clipperz.Crypto.SHA.sha_d256,
+
+ 'deriveKey': function(aStringValue) {
+ var byteData;
+ var result;
+
+ byteData = new Clipperz.ByteArray(aStringValue);
+ result = Clipperz.Crypto.SHA.sha_d256(byteData);
+
+ return result;
+ }
+ },
+
+ //#####################################################################
+
+ '0.3': {
+ 'encrypt': function(aKey, aValue, aNonce) {
+ var result;
+ var key, value;
+ var data;
+ var dataToEncrypt;
+ var encryptedData;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ value = Clipperz.Base.serializeJSON(aValue);
+ data = new Clipperz.ByteArray(value);
+ encryptedData = Clipperz.Crypto.AES.encrypt(key, data, aNonce);
+ result = encryptedData.toBase64String();
+
+ return result;
+ },
+
+ 'deferredEncrypt': function(aKey, aValue, aNonce) {
+ var deferredResult;
+ var key, value;
+ var data;
+ var dataToEncrypt;
+ var encryptedData;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ value = Clipperz.Base.serializeJSON(aValue);
+ data = new Clipperz.ByteArray(value);
+
+ deferredResult = new Clipperz.Async.Deferred("Crypto[0.3].deferredEncrypt")
+ deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncrypt, key, data, aNonce);
+ deferredResult.addCallback(function(aResult) {
+ return aResult.toBase64String();
+ })
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ 'decrypt': function(aKey, aValue) {
+ var result;
+
+ if (aValue != null) {
+ var key, value;
+ var decryptedData;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ value = new Clipperz.ByteArray().appendBase64String(aValue);
+
+ decryptedData = Clipperz.Crypto.AES.decrypt(key, value);
+
+ value = decryptedData.asString();
+ try {
+ result = Clipperz.Base.evalJSON(value);
+ } catch (exception) {
+ MochiKit.Logging.logError("Error while decrypting data [3]");
+ throw Clipperz.Crypto.Base.exception.CorruptedMessage;
+ }
+ } else {
+ result = null;
+ }
+
+ return result;
+ },
+
+ 'deferredDecrypt': function(aKey, aValue) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Crypto[0.3].deferredDecrypt", {trace: false});
+// now = new Date;
+
+ if (aValue != null) {
+ var key, value;
+// var decryptedData;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ value = new Clipperz.ByteArray().appendBase64String(aValue);
+
+ deferredResult.addCallback(Clipperz.Crypto.AES.deferredDecrypt, key, value);
+ deferredResult.addCallback(MochiKit.Async.wait, 0.1);
+ deferredResult.addCallback(function(aResult) {
+ return aResult.asString();
+ });
+ deferredResult.addCallback(MochiKit.Async.wait, 0.1);
+ deferredResult.addCallback(Clipperz.Base.evalJSON);
+ deferredResult.addErrback(function(anError) {
+ MochiKit.Logging.logError("Error while decrypting data [4]");
+ throw Clipperz.Crypto.Base.exception.CorruptedMessage;
+ })
+ } else {
+ deferredResult.addCallback(function() {
+ return null;
+ });
+ }
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ 'hash': Clipperz.Crypto.SHA.sha_d256,
+
+ 'deriveKey': function(aStringValue) {
+ var byteData;
+ var result;
+
+ byteData = new Clipperz.ByteArray(aStringValue);
+ result = Clipperz.Crypto.SHA.sha_d256(byteData);
+
+ return result;
+ }
+
+ },
+
+ //#####################################################################
+/*
+ '0.4': {
+ 'encrypt': function(aKey, aValue, aNonce) {
+ var result;
+ var key, value;
+ var data;
+ var dataToEncrypt;
+ var encryptedData;
+
+//MochiKit.Logging.logDebug(">>> [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt");
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+//MochiKit.Logging.logDebug("--- [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt - 1");
+ value = Clipperz.Base.serializeJSON(aValue);
+//MochiKit.Logging.logDebug("--- [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt - 2");
+/ *
+//MochiKit.Logging.logDebug("--> encrypt.fullSize: " + value.length);
+ value = value.replace(/":{"label":"/g, '":{l:"');
+ value = value.replace(/":{"key":"/g, '":{k:"');
+ value = value.replace(/":{"notes":"/g, '":{n:"');
+ value = value.replace(/":{"record":"/g, '":{r:"');
+ value = value.replace(/", "label":"/g, '",l:"');
+ value = value.replace(/", "favicon":"/g, '",f:"');
+//MochiKit.Logging.logDebug("<-- encrypt.compressed: " + value.length);
+* /
+ data = new Clipperz.ByteArray(value);
+//MochiKit.Logging.logDebug("--- [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt - 3");
+ encryptedData = Clipperz.Crypto.AES.encrypt(key, data, aNonce);
+//MochiKit.Logging.logDebug("--- [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt - 4");
+ result = encryptedData.toBase64String();
+//MochiKit.Logging.logDebug("<<< [" + (new Date()).valueOf() + "] Clipperz.PM.Crypto.versions[0.3].encrypt");
+
+ return result;
+ },
+
+ 'decrypt': function(aKey, aValue) {
+ var result;
+
+ if (aValue != null) {
+ var key, value;
+ var decryptedData;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ value = new Clipperz.ByteArray().appendBase64String(aValue);
+
+ decryptedData = Clipperz.Crypto.AES.decrypt(key, value);
+
+ value = decryptedData.asString();
+/ *
+ value = value.replace(/":{l:"/g, '":{"label":"');
+ value = value.replace(/":{k:"/g, '":{"key":"');
+ value = value.replace(/":{n:"/g, '":{"notes":"');
+ value = value.replace(/":{r:"/g, '":{"record":"');
+ value = value.replace(/",l:"/g, '", "label":"');
+ value = value.replace(/",f:"/g, '", "favicon":"');
+* /
+ try {
+ result = Clipperz.Base.evalJSON(value);
+ } catch (exception) {
+ MochiKit.Logging.logError("Error while decrypting data");
+ throw Clipperz.Crypto.Base.exception.CorruptedMessage;
+ }
+
+
+ } else {
+ result = null;
+ }
+
+ return result;
+ },
+
+ 'hash': Clipperz.Crypto.SHA.sha_d256
+ },
+*/
+ //#####################################################################
+ __syntaxFix__: "syntax fix"
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'encrypt': function(aKey, aValue, aVersion) {
+ return Clipperz.PM.Crypto.encryptingFunctions.versions[aVersion].encrypt(aKey, aValue);
+ },
+
+ 'deferredEncrypt': function(someParameters) {
+ return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters['version']].deferredEncrypt(someParameters['key'], someParameters['value']);
+ },
+
+ //.........................................................................
+
+ 'decrypt': function(aKey, aValue, aVersion) {
+ return Clipperz.PM.Crypto.encryptingFunctions.versions[aVersion].decrypt(aKey, aValue);
+ },
+
+ 'deferredDecrypt': function(someParameters) {
+ return Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters['version']].deferredDecrypt(someParameters['key'], someParameters['value']);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hash': function(aValue) {
+ return Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion]['hash'](aValue);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'randomKey': function() {
+ return Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deriveKey': function(aValue) {
+ return Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion].deriveKey(aValue);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'passwordEntropy': function(aValue) {
+ var result;
+ var bitPerChar;
+
+ bitPerChar = 4;
+ if (/[a-z]/.test(aValue)) {
+ bitPerChar ++;
+ }
+ if (/[A-Z]/.test(aValue)) {
+ bitPerChar ++;
+ }
+ if (/[^a-zA-Z0-9]/.test(aValue)) {
+ bitPerChar ++;
+ }
+
+ result = aValue.length * bitPerChar;
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'nullValue': '####',
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
+//*****************************************************************************
+
+//MochiKit.Base.update(Clipperz.PM.Connection.communicationProtocol.versions, {
+// 'current': Clipperz.PM.Connection.communicationProtocol.versions[Clipperz.PM.Connection.communicationProtocol.currentVersion]
+//});
+
+MochiKit.Base.update(Clipperz.PM.Crypto.encryptingFunctions.versions, {
+ 'current': Clipperz.PM.Crypto.encryptingFunctions.versions[Clipperz.PM.Crypto.encryptingFunctions.currentVersion]
+});
+
+//*****************************************************************************
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/DirectLogin.js b/frontend/gamma/js/Clipperz/PM/DataModel/DirectLogin.js
new file mode 100644
index 0000000..1d38509
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/DirectLogin.js
@@ -0,0 +1,1076 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.DataModel');
+
+Clipperz.PM.DataModel.DirectLogin = function(args) {
+ args = args || {};
+
+ Clipperz.PM.DataModel.DirectLogin.superclass.constructor.apply(this, arguments);
+
+ this._reference = args.reference
+ || Clipperz.PM.Crypto.randomKey();
+ this._record = args.record
+ || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ this._retrieveIndexDataFunction = args.retrieveIndexDataFunction
+ || this.record().retrieveDirectLoginIndexDataFunction()
+ || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._setIndexDataFunction = args.setIndexDataFunction
+ || this.record().setDirectLoginIndexDataFunction()
+ || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._removeIndexDataFunction = args.removeIndexDataFunction
+ || this.record().removeDirectLoginIndexDataFunction()
+ || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ this._inputs = null;
+ this._bindings = null;
+ this._formValues = null;
+
+// this._inputsDeferredLock = new MochiKit.Async.DeferredLock();
+// this._bindingsDeferredLock = new MochiKit.Async.DeferredLock();
+// this._formValuesDeferredLock = new MochiKit.Async.DeferredLock();
+
+ this._transientState = null;
+
+ this._isBrandNew = MochiKit.Base.isUndefinedOrNull(args.reference);
+
+ this.record().addDirectLogin(this);
+
+ return this;
+}
+
+Clipperz.Base.extend(Clipperz.PM.DataModel.DirectLogin, Object, {
+
+ 'toString': function() {
+ return "DirectLogin (" + this.reference() + ")";
+ },
+
+ //=========================================================================
+
+ 'reference': function () {
+ return this._reference;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'record': function () {
+ return this._record;
+ },
+
+ //=========================================================================
+
+ 'isBrandNew': function () {
+ return this._isBrandNew;
+ },
+
+ //=========================================================================
+
+ 'removeIndexDataFunction': function () {
+ return this._removeIndexDataFunction;
+ },
+
+ 'remove': function () {
+ return Clipperz.Async.callbacks("DirectLogin.remove", [
+ MochiKit.Base.partial(this.removeIndexDataFunction(), this.reference()),
+ MochiKit.Base.method(this.record(), 'removeDirectLogin', this)
+ ], {trace:false});
+ },
+
+ //=========================================================================
+/*
+ 'inputsDeferredLock': function () {
+ return this._inputsDeferredLock;
+ },
+
+ 'bindingsDeferredLock': function () {
+ return this._bindingsDeferredLock;
+ },
+
+ 'formValuesDeferredLock': function () {
+ return this._formValuesDeferredLock;
+ },
+*/
+ //=========================================================================
+
+ 'label': function () {
+ return this.getIndexDataForKey('label');
+ },
+
+ 'setLabelKeepingBackwardCompatibilityWithBeta': function (aValue) {
+ return Clipperz.Async.callbacks("DirectLogin.setLabelKeepingBackwardCompatibilityWithBeta", [
+ MochiKit.Base.method(this, 'setIndexDataForKey', 'label', aValue),
+ MochiKit.Base.method(this, 'setValue', 'label', aValue)
+ ], {trace:false});
+ },
+
+ 'setLabel': function (aValue) {
+ return this.setLabelKeepingBackwardCompatibilityWithBeta(aValue);
+// return this.setIndexDataForKey('label', aValue);
+ },
+
+ //=========================================================================
+
+ 'favicon': function () {
+ return this.getIndexDataForKey('favicon');
+ },
+
+ 'setFavicon': function (aValue) {
+ return this.setIndexDataForKey('favicon', aValue);
+ },
+
+ 'faviconUrlWithBookmarkletConfiguration': function (aBookmarkletConfiguration) {
+ var result;
+
+ if (! MochiKit.Base.isUndefinedOrNull(aBookmarkletConfiguration['page']['favicon'])) {
+ result = aBookmarkletConfiguration['page']['favicon'];
+ } else if (! MochiKit.Base.isUndefinedOrNull(aBookmarkletConfiguration['form']['attributes']['action'])) {
+ var actionUrl;
+ var hostname;
+
+ actionUrl = aBookmarkletConfiguration['form']['attributes']['action'];
+ hostname = actionUrl.replace(/^https?:\/\/([^\/]*)\/.*/, '$1');
+ result = "http://" + hostname + "/favicon.ico";
+ } else {
+ result = null;
+ }
+
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'faviconData': function () {
+ var regexp = new RegExp('^data\:\/\/.*', 'i');
+
+ return Clipperz.Async.callbacks("DirectLogin.favicon", [
+ MochiKit.Base.method(this, 'getIndexDataForKey', 'favicon'),
+ MochiKit.Base.method(regexp, 'test'),
+ Clipperz.Async.deferredIf("is data URL", [
+ MochiKit.Base.method(this, 'getIndexDataForKey', 'favicon')
+ ], [
+ MochiKit.Base.method(this, 'transientState'),
+ MochiKit.Base.itemgetter('faviconData'),
+ Clipperz.Async.deferredIf('has a chaced value for the favicon data', [
+ MochiKit.Base.operator.identity
+ ], [
+ MochiKit.Base.method(this, 'getIndexDataForKey', 'favicon'),
+ MochiKit.Base.method(this, 'loadFaviconDataFromURL')
+ ])
+
+ ])
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'loadFaviconDataFromURL': function (anURL) {
+ var deferredResult;
+ var image;
+
+ deferredResult = new Clipperz.Async.Deferred("DirectLogin.loadFaviconDataFromURL", {trace:false});
+ deferredResult.addCallback(function (anEvent) {
+ var image = anEvent.src();
+ var canvas = document.createElement("canvas");
+ var result;
+
+ canvas.width = image.width;
+ canvas.height = image.height;
+
+ var ctx = canvas.getContext("2d");
+ ctx.drawImage(image, 0, 0);
+
+ result = canvas.toDataURL(/*"image/png"* /);
+
+ return result;
+ });
+ deferredResult.addErrback(MochiKit.Async.succeed, Clipperz.PM.Strings.getValue('defaultFaviconUrl'));
+ deferredResult.addBoth(MochiKit.Base.bind(function (aDataUrl) {
+ this.transientState()['faviconData'] = aDataUrl;
+
+ return aDataUrl;
+ }, this));
+
+ image = new Image();
+ MochiKit.Signal.connect(image, 'onload', MochiKit.Base.method(deferredResult, 'callback'));
+ MochiKit.Signal.connect(image, 'onerror', MochiKit.Base.method(deferredResult, 'errback'));
+ MochiKit.Signal.connect(image, 'onabort', MochiKit.Base.method(deferredResult, 'errback'));
+
+ image.src = anURL;
+
+ return deferredResult;
+ },
+*/
+
+ //=========================================================================
+
+ 'type': function () {
+ return this.getValue('formData.attributes.type')
+ },
+
+ //=========================================================================
+
+ 'serializedData': function () {
+ return Clipperz.Async.collectResults("DirectLogin.serializedData", {
+ 'bookmarkletVersion': MochiKit.Base.method(this, 'getValue', 'bookmarkletVersion'),
+ 'formData': MochiKit.Base.method(this, 'getValue', 'formData'),
+ 'formValues': MochiKit.Base.method(this, 'getValue', 'formValues'),
+ 'bindingData': [
+ MochiKit.Base.method(this, 'bindings'),
+ function (someBindings) {
+ var result;
+ var bindingKey;
+
+ result = {}
+ for (bindingKey in someBindings) {
+ result[bindingKey] = someBindings[bindingKey].serializedData();
+ }
+
+ return result;
+ }
+ ]
+ }, {trace:false})()
+ },
+
+ //=========================================================================
+/*
+ 'fixFormDataFromBookmarkletVersion_0_1': function(aValue) {
+//{"type":"radio", "name":"action", "value":"new-user", "checked":false }, { "type":"radio", "name":"action", "value":"sign-in", "checked":true }
+// ||
+// \ /
+// \/
+//{"name":"dominio", "type":"radio", "options":[{"value":"@alice.it", "checked":true}, {"value":"@tin.it", "checked":false}, {"value":"@virgilio.it", "checked":false}, {"value":"@tim.it", "checked":false}]}
+ var result;
+ var inputs;
+ var updatedInputs;
+ var radios;
+
+ result = aValue;
+ inputs = aValue['inputs'];
+
+ updatedInputs = MochiKit.Base.filter(function(anInput) {
+ var result;
+ var type;
+
+ type = anInput['type'] || 'text';
+ result = type.toLowerCase() != 'radio';
+
+ return result;
+ }, inputs);
+ radios = MochiKit.Base.filter(function(anInput) {
+ var result;
+ var type;
+
+ type = anInput['type'] || 'text';
+ result = type.toLowerCase() == 'radio';
+
+ return result;
+ }, inputs);
+
+ if (radios.length > 0) {
+ var updatedRadios;
+
+ updatedRadios = {};
+ MochiKit.Iter.forEach(radios, MochiKit.Base.bind(function(aRadio) {
+ var radioConfiguration;
+
+ radioConfiguration = updatedRadios[aRadio['name']];
+ if (radioConfiguration == null) {
+ radioConfiguration = {type:'radio', name:aRadio['name'], options:[]};
+ updatedRadios[aRadio['name']] = radioConfiguration;
+ }
+
+// TODO: remove the value: field and replace it with element.dom.value = <some value>
+ radioConfiguration.options.push({value:aRadio['value'], checked:aRadio['checked']});
+
+// TODO: shoud remove the 'formValues' call, as it is now deferred
+// if ((aRadio['checked'] == true) && (this.formValues()[aRadio['name']] == null)) {
+// this.formValues()[aRadio['name']] = aRadio['value'];
+// }
+ }, this))
+
+ updatedInputs = MochiKit.Base.concat(updatedInputs, MochiKit.Base.values(updatedRadios));
+ }
+
+ delete result.inputs;
+ result.inputs = updatedInputs;
+
+ return result;
+ },
+
+ '_fixConfiguration': function (aConfiguration) {
+ var fixedConfiguration;
+// var inputs;
+// var bindings;
+// var i,c;
+
+ fixedConfiguration = Clipperz.Base.deepClone(aConfiguration);
+
+//console.log("PROCESS CONFIGURATION", aConfiguration);
+ switch (aConfiguration['bookmarkletVersion']) {
+ case '0.1':
+ fixedConfiguration['formData'] = this.fixFormDataFromBookmarkletVersion_0_1(aConfiguration['formData']);
+ break;
+ case '0.2':
+ fixedConfiguration['formData'] = aConfiguration['formData'];
+ break;
+ }
+
+/ *
+ aConfiguration['_inputs'] = [];
+ c = formData['inputs'].length;
+ for (i=0; i<c; i++) {
+ aConfiguration['_inputs'].push(new Clipperz.PM.DataModel.DirectLoginInput(formData['inputs'][i]));
+ }
+* /
+/ *
+ aConfiguration['_bindings'] = {};
+ if (aConfiguration['legacyBindingData'] == null) {
+ if (aConfiguration['bindingData'] != null) {
+ var bindingKey;
+
+ for (bindingKey in aConfiguration['bindingData']) {
+ var newBinding;
+
+ newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(bindingKey, {fieldKey:aConfiguration['bindingData'][bindingKey]});
+ aConfiguration['_bindings'][newBinding.key()] = newBinding;
+ }
+ } else {
+ var editableFields;
+
+ editableFields = MochiKit.Base.filter(function(aField) {
+ var result;
+ var type;
+
+ type = aField['type'].toLowerCase();
+ result = ((type != 'hidden') && (type != 'submit') && (type != 'checkbox') && (type != 'radio') && (type != 'select'));
+
+ return result;
+ }, aConfiguration['_inputs']);
+
+ MochiKit.Iter.forEach(editableFields, MochiKit.Base.bind(function(anEditableField) {
+ var newBinding;
+
+ newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(anEditableField['name']);
+ aConfiguration['_bindings'][newBinding.key()] = newBinding;
+ }, this));
+ }
+
+ } else {
+ var bindingKey;
+
+ for (bindingKey in aConfiguration['legacyBindingData']) {
+ var newBinding;
+
+ newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(bindingKey, {fieldName:aConfiguration['legacyBindingData'][bindingKey]});
+ aConfiguration['_bindings'][newBinding.key()] = newBinding;
+ }
+ }
+* /
+
+ return fixedConfiguration;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getObjectDataStore': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("DirectLogin.getObjectDataStore", {trace:false});
+ deferredResult.acquireLock(this.objectDataStoreDeferredLock());
+ deferredResult.addCallback(MochiKit.Base.bind(function () {
+ var innerDeferredResult;
+
+ if (this._objectDataStore == null) {
+ this._objectDataStore = new Clipperz.KeyValueObjectStore();
+
+ innerDeferredResult = new Clipperz.Async.Deferred("DirectLogin.getObjectDataStore <inner deferred>", {trace:false});
+// innerDeferredResult.addMethod(this.record(), 'getValue', 'directLogins' + '.' + this.reference());
+ innerDeferredResult.addMethod(this, 'getValue', ''),
+ innerDeferredResult.addMethod(this, 'setOriginalState');
+ innerDeferredResult.addMethod(this, '_fixConfiguration');
+ innerDeferredResult.addMethod(this._objectDataStore, 'initWithValues');
+// innerDeferredResult.addMethod(this._objectDataStore, 'setValues');
+ innerDeferredResult.callback();
+ } else {
+ innerDeferredResult = MochiKit.Async.succeed(this._objectDataStore);
+ }
+
+ return innerDeferredResult;
+ }, this));
+ deferredResult.releaseLock(this.objectDataStoreDeferredLock());
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hasInitiatedObjectDataStore': function () {
+ return (this._objectDataStore != null);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'resetObjectDataStore': function () {
+ this._objectDataStore.removeAllData();
+ this._objectDataStore = null;
+ },
+*/
+ //=========================================================================
+
+ 'bookmarkletConfiguration': function () {
+ return Clipperz.Async.callbacks("DirectLogin.bookmarkletConfiguration", [
+ Clipperz.Async.collectResults("DirectLogin.bookmarkletConfiguration <inner results>", {
+ 'label': MochiKit.Base.method(this, 'label'),
+ 'configuration': MochiKit.Base.method(this, 'getValue', '')
+ }, {trace:false}),
+ function (someValues) {
+ var result;
+
+ if (someValues['configuration'] != null) {
+ var configuration;
+
+ configuration = {
+ 'page': {
+ 'title': someValues['label']
+ // 'favicon'
+ // 'url'
+ },
+ 'form': someValues['configuration']['formData'],
+ 'version': someValues['configuration']['bookmarkletVersion']
+ }
+
+ result = Clipperz.Base.formatJSON(configuration);
+ } else {
+ result = '';
+ }
+
+ return result;
+ }
+ ], {trace:false});
+
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setBookmarkletConfiguration': function (aValue) {
+ var bookmarkletConfiguration;
+
+ bookmarkletConfiguration = Clipperz.PM.DataModel.DirectLogin.checkBookmarkletConfiguration(aValue);
+//console.log("BOOKMARKLET CONFIGURATION", bookmarkletConfiguration);
+ return Clipperz.Async.callbacks("DirectLogin.setBookmarkletConfiguration", [
+ MochiKit.Base.method(this, 'setValue', 'formData', bookmarkletConfiguration['form']),
+//function (aValue) { console.log("SET VALUE - formData", aValue); return aValue; },
+ MochiKit.Base.method(this, 'setValue', 'bookmarkletVersion', bookmarkletConfiguration['version']),
+
+ MochiKit.Base.method(this, 'favicon'),
+ Clipperz.Async.deferredIf("the favicon is not set", [
+ ], [
+ MochiKit.Base.method(this, 'faviconUrlWithBookmarkletConfiguration', bookmarkletConfiguration),
+ MochiKit.Base.method(this, 'setFavicon')
+ ]),
+
+ MochiKit.Base.method(this, 'updateInputsAfterChangingBookmarkletConfiguration'),
+ MochiKit.Base.method(this, 'updateFormValuesAfterChangingBookmarkletConfiguration'),
+ MochiKit.Base.method(this, 'updateBindingsAfterChangingBookmarkletConfiguration'),
+
+ MochiKit.Base.noop
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'formAttributes': function () {
+ return this.getValue('formData.attributes');
+ },
+
+ //=========================================================================
+
+ 'inputs': function () {
+ return Clipperz.Async.callbacks("DirectLogin.inputs", [
+ Clipperz.Async.deferredIf("this._inputs is defined", [
+ ], [
+ MochiKit.Base.method(this, 'updateInputsAfterChangingBookmarkletConfiguration')
+ ])
+ ], {trace:false}, this._inputs);
+ },
+
+ 'setInputWithFormDataConfiguration': function (aFormDataConfiguration) {
+ this._inputs = {};
+
+ if (aFormDataConfiguration != null) {
+ MochiKit.Iter.forEach(aFormDataConfiguration['inputs'], MochiKit.Base.bind(function (anInputData) {
+ var newInput;
+
+ newInput = new Clipperz.PM.DataModel.DirectLoginInput(anInputData);
+ this._inputs[newInput.name()] = newInput;
+ }, this));
+ }
+
+ return this._inputs;
+ },
+
+ 'updateInputsAfterChangingBookmarkletConfiguration': function () {
+ return Clipperz.Async.callbacks("DirectLogin.updateInputsAfterChangingBookmarkletConfiguration", [
+// MochiKit.Base.method(this, 'getValue', ''),
+//function (aValue) { console.log("VALUE", aValue); return aValue },
+ MochiKit.Base.method(this, 'getValue', 'formData'),
+//function (aValue) { console.log("FORM DATA", aValue); return aValue },
+ MochiKit.Base.method(this, 'setInputWithFormDataConfiguration')
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'inputValues': function () {
+ return Clipperz.Async.callbacks("DirectLogin.inputValues", [
+ MochiKit.Base.method(this, 'inputs'),
+ MochiKit.Base.values,
+//function (aValue) { console.log("INPUTS", aValue); return aValue; },
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.partial(MochiKit.Base.method(this, 'inputValue'))),
+ Clipperz.Async.collectAll,
+ Clipperz.Base.mergeItems
+ ], {trace:false});
+ },
+
+ 'inputValue': function (anInput) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("DirectLogin.inputValue", {trace:false});
+
+ if (anInput.needsFormValue()) {
+ deferredResult.addMethod(this, 'formValues');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(anInput.name()));
+ deferredResult.addMethodcaller('value');
+ } else if (anInput.needsBinding()) {
+ deferredResult.addMethod(this, 'bindings');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(anInput.name()));
+ deferredResult.addMethodcaller('field');
+ deferredResult.addMethodcaller('value');
+ } else {
+ deferredResult.addCallback(MochiKit.Async.succeed, anInput.value());
+ }
+ deferredResult.addCallback(function (anActualValue) {
+ return [anInput.name(), anActualValue];
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'bindings': function () {
+ return Clipperz.Async.callbacks("DirectLogin.bindings", [
+ Clipperz.Async.deferredIf("this._bindings is defined", [
+ ], [
+ MochiKit.Base.method(this, 'updateBindingsAfterChangingBookmarkletConfiguration'),
+ MochiKit.Base.bind(function () { return this._bindings;}, this)
+ ])
+ ], {trace:false}, this._bindings);
+ },
+
+ 'bindFormFieldWithLabelToRecordFieldWithLabel': function (aFormFieldLabel, aRecordFieldLabel) {
+ return Clipperz.Async.callbacks("DirectLogin.bindFormFieldWithLabelToCardFieldWithLabel", [
+ Clipperz.Async.collectResults("DirectLogin.bindFormFieldWithLabelToCardFieldWithLabel - collect results", {
+ 'binding': [
+ MochiKit.Base.method(this, 'bindings'),
+ MochiKit.Base.itemgetter(aFormFieldLabel)
+ ],
+ 'field': [
+ MochiKit.Base.method(this.record(), 'fieldWithLabel', aRecordFieldLabel)
+ ]
+ }),
+ function (someValues) {
+ someValues['binding'].setField(someValues['field'])
+ }
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'bindingValues': function () {
+ return Clipperz.Async.callbacks("DirectLogin.bindingValues", [
+ Clipperz.Async.collectResults("DirectLogin.bindingValues [collectResults]", {
+ 'fieldValues': [
+ MochiKit.Base.method(this, 'record'),
+ MochiKit.Base.methodcaller('getFieldsValues')
+ ],
+ 'bindings': MochiKit.Base.method(this, 'bindings')
+ }, {trace:false}),
+ function (someData) {
+ var result;
+ var bindingKey;
+
+ result = {};
+ for (bindingKey in someData['bindings']) {
+ result[bindingKey] = someData['fieldValues'][someData['bindings'][bindingKey].fieldKey()]['value'];
+ }
+
+ return result;
+ }
+ ], {trace:false});
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'updateBindingsAfterChangingBookmarkletConfiguration': function () {
+ return Clipperz.Async.callbacks("DirectLogin.updateBindingsAfterChangingBookmarkletConfiguration", [
+ Clipperz.Async.collectResults("DirectLogin.updateBindingsAfterChangingBookmarkletConfiguration<collect results>", {
+ 'currentValues': MochiKit.Base.method(this, 'getValue', ''),
+ 'originalValues': MochiKit.Base.method(this, 'originalConfiguration'),
+ 'inputs': MochiKit.Base.method(this, 'inputs')
+ }, {trace:false}),
+ MochiKit.Base.bind(function (someValues) {
+ var availableBindingValues;
+ var inputRequiringBindingValues;
+ var newBindingValues;
+
+ if (MochiKit.Base.isUndefinedOrNull(someValues['originalValues']) || MochiKit.Base.isUndefinedOrNull(someValues['originalValues']['bindingData'])) {
+ availableBindingValues = {};
+ } else {
+ availableBindingValues = Clipperz.Base.deepClone(someValues['originalValues']['bindingData'])
+ }
+
+ if (someValues['currentValues'] != null) {
+ MochiKit.Base.update(availableBindingValues, someValues['currentValues']['bindingData']);
+ }
+
+ this._bindings = {};
+ newBindingValues = {}
+ MochiKit.Iter.forEach(MochiKit.Base.filter(MochiKit.Base.methodcaller('needsBinding'), MochiKit.Base.values(someValues['inputs'])), MochiKit.Base.bind(function (anInput) {
+ var newBinding;
+
+ newBindingValues[anInput.name()] = availableBindingValues[anInput.name()];
+ newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, {
+ 'key': anInput.name(),
+ 'field': availableBindingValues[anInput.name()]
+ });
+
+ this._bindings[anInput.name()] = newBinding;
+ }, this))
+//console.log("THIS._BINDINGS", this._bindings);
+
+ return newBindingValues;
+
+/*
+ this._bindings = {};
+//console.log("CONFIGURATION", aConfiguration);
+
+ if (someValues['currentValues'] != null) {
+ if (someValues['currentValues']['bindingData'] != null) {
+ var bindingKey;
+
+//console.log("BINDING DATA", someValues['currentValues']['bindingData']);
+ for (bindingKey in someValues['currentValues']['bindingData']) {
+ var newBinding;
+
+ newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, {
+ 'key': bindingKey,
+ 'field': someValues['currentValues']['bindingData'][bindingKey]
+ });
+ this._bindings[newBinding.key()] = newBinding;
+ }
+ } else if (someValues['currentValues']['legacyBindingData'] == null) {
+ var bindingKey;
+
+ for (bindingKey in someValues['currentValues']['legacyBindingData']) {
+ var newBinding;
+
+ newBinding = new Clipperz.PM.DataModel.DirectLoginBinding(this, {
+ 'key': bindingKey,
+ 'field': someValues['currentValues']['legacyBindingData'][bindingKey]
+ });
+ this._bindings[newBinding.key()] = newBinding;
+ }
+ } else {
+ WTF = TODO;
+ }
+ }
+
+ return this._bindings;
+*/
+ }, this),
+ MochiKit.Base.method(this, 'setValue', 'bindingData')
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'formValues': function () {
+ return Clipperz.Async.callbacks("DirectLogin.formValues", [
+ Clipperz.Async.deferredIf("this._formValues is defined", [
+ ], [
+ MochiKit.Base.method(this, 'updateFormValuesAfterChangingBookmarkletConfiguration'),
+ MochiKit.Base.bind(function () { return this._formValues;}, this)
+ ])
+ ], {trace:false}, this._formValues);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateFormValuesAfterChangingBookmarkletConfiguration': function () {
+ return Clipperz.Async.callbacks("DirectLogin.updateFormValuesAfterChangingBookmarkletConfiguration", [
+ Clipperz.Async.collectResults("DirectLogin.updateFormValuesAfterChangingBookmarkletConfiguration <collect results>", {
+ 'currentValues': MochiKit.Base.method(this, 'getValue', ''),
+ 'originalValues': MochiKit.Base.method(this, 'originalConfiguration'),
+ 'inputs': MochiKit.Base.method(this, 'inputs')
+ }, {trace:false}),
+ MochiKit.Base.bind(function (someValues) {
+ var availableFormValues;
+ var inputRequiringFormValues;
+ var newFormValues;
+
+ if (MochiKit.Base.isUndefinedOrNull(someValues['originalValues']) || MochiKit.Base.isUndefinedOrNull(someValues['originalValues']['formValues'])) {
+ availableFormValues = {};
+ } else {
+ availableFormValues = Clipperz.Base.deepClone(someValues['originalValues']['formValues'])
+ }
+
+ MochiKit.Base.update(availableFormValues, someValues['currentValues']['formValues']);
+
+ this._formValues = {};
+ newFormValues = {};
+ MochiKit.Iter.forEach(MochiKit.Base.filter(MochiKit.Base.methodcaller('needsFormValue'), MochiKit.Base.values(someValues['inputs'])), MochiKit.Base.bind(function (anInput) {
+ var newFormValue;
+ var fieldOptions;
+
+ fieldOptions = {
+ 'type': anInput.type(),
+ 'options': anInput.options()
+ };
+
+ newFormValues[anInput.name()] = availableFormValues[anInput.name()]
+ newFormValue = new Clipperz.PM.DataModel.DirectLoginFormValue(this, {
+ 'key': anInput.name(),
+ 'fieldOptions': fieldOptions,
+ 'value': availableFormValues[anInput.name()]
+ });
+
+ this._formValues[anInput.name()] = newFormValue;
+ }, this))
+
+ return newFormValues;
+ }, this),
+ MochiKit.Base.method(this, 'setValue', 'formValues')
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'retrieveIndexDataFunction': function () {
+ return this._retrieveIndexDataFunction;
+ },
+
+ 'getIndexDataForKey': function (aKey) {
+ return Clipperz.Async.callbacks("DirectLogin.getIndexDataForKey", [
+ MochiKit.Base.partial(this.retrieveIndexDataFunction(), this.reference()),
+ Clipperz.Async.deferredIf("DirectLogin.getIndexDataForKey - index data not null", [
+ MochiKit.Base.itemgetter(aKey)
+ ],[
+ MochiKit.Async.succeed
+ ])
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setIndexDataForKey': function (aKey, aValue) {
+ return Clipperz.Async.callbacks("DirectLogin.setValueForKey", [
+ MochiKit.Base.method(this, 'getIndexDataForKey', aKey),
+ MochiKit.Base.bind(function (anActualValue) {
+ var transientStateKey;
+
+ transientStateKey = 'original_' + aKey;
+ if (MochiKit.Base.isUndefinedOrNull(this.transientState()[transientStateKey])) {
+ if (anActualValue != aValue) {
+ this.transientState()[transientStateKey] = anActualValue;
+ }
+ } else if (this.transientState()[transientStateKey] == aValue) {
+ this.transientState()[transientStateKey] = null;
+ }
+ }, this),
+ MochiKit.Base.partial(this._setIndexDataFunction, this.reference(), aKey, aValue)
+ ], {trace:false})
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'setValueForKey': function (aKey, aValue) {
+ return Clipperz.Async.callbacks("DirectLogin.setValueForKey", [
+ MochiKit.Base.method(this, 'getIndexDataForKey', aKey),
+ MochiKit.Base.bind(function (anActualValue) {
+ var transientStateKey;
+
+ transientStateKey = 'original_' + aKey;
+ if (MochiKit.Base.isUndefinedOrNull(this.transientState()[transientStateKey])) {
+ if (anActualValue != aValue) {
+ this.transientState()[transientStateKey] = anActualValue;
+ }
+ } else if (this.transientState()[transientStateKey] == aValue) {
+ this.transientState()[transientStateKey] = null;
+ }
+ }, this),
+ MochiKit.Base.method(this, 'setIndexDataForKey', aKey, aValue)
+ ], {trace:false})
+ },
+*/
+ //=========================================================================
+/*
+ 'storedConfiguration': function () {
+ return this.record().getValue('directLogins' + '.' + this.reference());
+ },
+
+// 'setStoredConfiguration': function (aValue) {
+// return this.record().setValue('directLogins' + '.' + this.reference(), aValue);
+// },
+*/
+ //=========================================================================
+
+ 'hasPendingChanges': function () {
+ var result;
+ var deferredResult;
+
+ result = false;
+ result = result || this.isBrandNew();
+ result = result || (! MochiKit.Base.isUndefinedOrNull(this.transientState()['original_label']));
+ result = result || (! MochiKit.Base.isUndefinedOrNull(this.transientState()['original_favicon']));
+
+ if ((result == false) && (this.originalConfiguration() != null)) {
+ deferredResult = Clipperz.Async.callbacks("DirectLogin.hasPendingChanges", [
+ MochiKit.Base.method(this, 'serializedData'),
+ MochiKit.Base.bind(function (aCurrentConfiguration) {
+ var originalConfiguration;
+ var currentConfiguration;
+ var result;
+
+ originalConfiguration = this.originalConfiguration();
+ currentConfiguration = aCurrentConfiguration;
+
+ result = false;
+ result = result || (MochiKit.Base.compare(originalConfiguration['bookmarkletVersion'], currentConfiguration['bookmarkletVersion']) != 0);
+ result = result || (MochiKit.Base.compare(originalConfiguration['formData'], currentConfiguration['formData']) != 0);
+ result = result || (MochiKit.Base.compare(originalConfiguration['formValues'], currentConfiguration['formValues']) != 0);
+ result = result || (MochiKit.Base.compare(originalConfiguration['bindingData'], currentConfiguration['bindingData']) != 0);
+
+ return result;
+ }, this)
+ ], {trace:false});
+ } else {
+ deferredResult = MochiKit.Async.succeed(result);
+ }
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'revertChanges': function () {
+ var deferredResult;
+
+ if (this.transientState()['original_label'] != null) {
+ this.setLabel(this.transientState()['original_label']);
+ }
+
+ if (this.transientState()['original_favicon'] != null) {
+ this.setFavicon(this.transientState()['original_favicon']);
+ }
+
+ if (this.originalConfiguration() != null) {
+ deferredResult = this.setValue('', this.originalConfiguration());
+ } else {
+ deferredResult = MochiKit.Async.succeed();
+ }
+
+ this._inputs = null;
+ this._bindings = null;
+ this._formValues = null;
+
+ this.resetTransientState(false);
+
+/*
+ if (this.hasInitiatedObjectDataStore()) {
+ deferredResult = Clipperz.Async.callbacks("DirectLogin.revertChanges", [
+// MochiKit.Base.method(this.record(), 'setValue', 'directLogins' + '.' + this.reference(), this.originalState()),
+ MochiKit.Base.method(this, 'setValue', '', this.originalState()),
+ MochiKit.Base.method(this, 'resetObjectDataStore')
+ ], {trace:false})
+ } else {
+ deferredResult = MochiKit.Async.succeed();
+ }
+*/
+ return deferredResult;
+ },
+
+
+ //=========================================================================
+
+ 'transientState': function () {
+ if (this._transientState == null) {
+ this._transientState = {}
+ }
+
+ return this._transientState;
+ },
+
+ 'resetTransientState': function (isCommitting) {
+ this._transientState = null;
+ },
+
+ 'commitTransientState': function (isCommitting) {
+ this._transientState = null;
+ this._isBrandNew = false;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'originalConfiguration': function () {
+ return this.transientState()['original_configuration'];
+ },
+
+ 'setOriginalConfiguration': function (aConfiguration) {
+ this.transientState()['original_configuration'] = Clipperz.Base.deepClone(aConfiguration);
+ },
+
+ //=========================================================================
+
+ 'actualKey': function (aValueKey) {
+ var actualKey;
+
+ actualKey = 'directLogins' + '.' + this.reference();
+ if (aValueKey != '') {
+ actualKey = actualKey + '.' + aValueKey;
+ }
+
+ return actualKey;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getValue': function (aValueKey) {
+ return this.record().getValue(this.actualKey(aValueKey));
+ },
+
+ 'setValue': function (aValueKey, aValue) {
+// return this.record().setValue(this.actualKey(aValueKey), aValue);
+
+ return Clipperz.Async.callbacks("DirectLogin.setValue", [
+ MochiKit.Base.method(this, 'getValue', ''),
+ MochiKit.Base.bind(function (aValue) {
+ if (this.originalConfiguration() == null) {
+ this.setOriginalConfiguration(aValue);
+ }
+ }, this),
+// MochiKit.Base.method(this, 'originalConfiguration'),
+// Clipperz.Async.deferredIf("originalConfiguration has been set", [
+// ], [
+// MochiKit.Base.method(this, 'getValue', ''),
+// MochiKit.Base.method(this, 'setOriginalConfiguration')
+// ]),
+ MochiKit.Base.method(this.record(), 'setValue', this.actualKey(aValueKey), aValue)
+ ], {trace:false});
+ },
+
+ 'removeValue': function (aValueKey) {
+// return this.record().removeValue(this.actualKey(aValueKey));
+
+ return Clipperz.Async.callbacks("DirectLogin.setValue", [
+ MochiKit.Base.method(this, 'originalConfiguration'),
+ Clipperz.Async.deferredIf("originalConfiguration has been set", [
+ ], [
+ MochiKit.Base.method(this, 'getValue', ''),
+ MochiKit.Base.method(this, 'setOriginalConfiguration')
+ ]),
+ MochiKit.Base.method(this.record(), 'removeValue', this.actualKey(aValueKey))
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'deleteAllCleanTextData': function () {
+ this._inputs = null;
+ this._bindings = null;
+ this._formValues = null;
+
+ this.resetTransientState();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hasAnyCleanTextData': function () {
+ var result;
+
+ result = false;
+
+ result = result || (this._inputs != null);
+ result = result || (this._bindings != null);
+ result = result || (this._formValues != null);
+ result = result || (MochiKit.Base.keys(this.transientState()).length != 0);
+
+ return MochiKit.Async.succeed(result);
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+//#############################################################################
+
+Clipperz.PM.DataModel.DirectLogin.exception = {
+ 'WrongBookmarkletConfiguration': new MochiKit.Base.NamedError("Clipperz.PM.DataModel.DirectLogin.exception.WrongBookmarkletConfiguration")
+};
+
+Clipperz.PM.DataModel.DirectLogin.checkBookmarkletConfiguration = function(aConfiguration) {
+ var configuration;
+
+ try {
+ configuration = Clipperz.Base.evalJSON(aConfiguration);
+// configuration = Clipperz.PM.BookmarkletProcessor.sanitizeBookmarkletConfiguration(configuration);
+
+ if (MochiKit.Base.isUndefinedOrNull(configuration['page']['title'])
+ || MochiKit.Base.isUndefinedOrNull(configuration['form']['attributes']['action'])
+// || MochiKit.Base.isUndefinedOrNull(configuration['form']['attributes']['method'])
+ || MochiKit.Base.isUndefinedOrNull(configuration['form']['inputs'])
+ || MochiKit.Base.isUndefinedOrNull(configuration['version'])
+ ) {
+ throw Clipperz.PM.DataModel.DirectLogin.exception.WrongBookmarkletConfiguration;
+ }
+
+// if (MochiKit.Base.isUndefinedOrNull(configuration['favicon'])) {
+// throw Clipperz.PM.DataModel.DirectLogin.exception.WrongBookmarkletConfiguration;
+// }
+
+ } catch (exception) {
+ throw exception;
+ }
+
+ return configuration;
+};
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/DirectLoginBinding.js b/frontend/gamma/js/Clipperz/PM/DataModel/DirectLoginBinding.js
new file mode 100644
index 0000000..fd55c63
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/DirectLoginBinding.js
@@ -0,0 +1,125 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
+
+
+//#############################################################################
+
+Clipperz.PM.DataModel.DirectLoginBinding = function(aDirectLogin, args) {
+ args = args || {};
+
+ this._directLogin = aDirectLogin|| Clipperz.Base.exception.raise('MandatoryParameter');
+
+ this._key = args.key || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._fieldKey = args.field || /* this.directLogin().fieldWithName(args.fieldName).reference() || */ null;
+
+ return this;
+}
+
+Clipperz.PM.DataModel.DirectLoginBinding.prototype = MochiKit.Base.update(null, {
+
+ 'toString': function() {
+ return "DirectLoginBinding (" + this.key() + ", " + this.fieldKey() + ")";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'directLogin': function () {
+ return this._directLogin;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'key': function() {
+ return this._key;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'fieldKey': function() {
+ return this._fieldKey;
+ },
+
+ 'setFieldKey': function(aValue) {
+ this._fieldKey = aValue;
+
+ return this.directLogin().setValue('bindingData' + '.' + this.key(), aValue);
+ },
+
+// 'fieldName': function() {
+// return this._fieldName;
+// },
+
+ //-------------------------------------------------------------------------
+
+ 'field': function() {
+ var deferredResult;
+
+ if (this.fieldKey() != null) {
+ deferredResult = Clipperz.Async.callbacks("DirectLoginBinding.field [1]", [
+ MochiKit.Base.method(this.directLogin().record(), 'fields'),
+ MochiKit.Base.itemgetter(this.fieldKey())
+ ], {trace:false});
+// } else if (this.fieldName() != null) {
+// WTF = TODO;
+// result = this.directLogin().record().fieldWithName(this.fieldName());
+//
+// this.setFieldKey(result.key());
+ } else {
+ deferredResult = MochiKit.Async.succeed(null);
+ }
+
+ return deferredResult;
+ },
+
+ 'setField': function (aField) {
+ this.setFieldKey(aField.reference());
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'fieldValue': function () {
+ return Clipperz.Async.callbacks("DirectLoginBinding.fieldValue", [
+ MochiKit.Base.method('field'),
+ MochiKit.Base.methodcaller('value')
+ ], {trace:false});
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'serializedData': function() {
+ return this.fieldKey();
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/DirectLoginFormValue.js b/frontend/gamma/js/Clipperz/PM/DataModel/DirectLoginFormValue.js
new file mode 100644
index 0000000..939ab4b
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/DirectLoginFormValue.js
@@ -0,0 +1,107 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
+
+
+//#############################################################################
+
+Clipperz.PM.DataModel.DirectLoginFormValue = function(aDirectLogin, args) {
+ args = args || {};
+
+ this._directLogin = aDirectLogin|| Clipperz.Base.exception.raise('MandatoryParameter');
+
+ this._key = args.key || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._fieldOptions = args.fieldOptions || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._value = args.value || null;
+
+ return this;
+}
+
+Clipperz.PM.DataModel.DirectLoginFormValue.prototype = MochiKit.Base.update(null, {
+
+ 'toString': function() {
+ return "DirectLoginFormValue (" + this.key() + ", " + this.value() + ")";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'directLogin': function () {
+ return this._directLogin;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'key': function() {
+ return this._key;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'fieldOptions': function() {
+ return this._fieldOptions;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'type': function () {
+ return this.fieldOptions()['type'];
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'value': function() {
+ var result;
+
+ result = this._value;
+
+// if ((result == null) && (this.type() == 'checkbox')) {
+// result = false;
+// };
+
+ return result;
+ },
+
+ 'setValue': function (aValue) {
+//console.log("DirectLoginFormValue.setValue", aValue);
+ this._value = aValue;
+ return this.directLogin().setValue('formValues' + '.' + this.key(), aValue);
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'serializedData': function() {
+ return this.value();
+ },
+*/
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/DirectLoginInput.js b/frontend/gamma/js/Clipperz/PM/DataModel/DirectLoginInput.js
new file mode 100644
index 0000000..673d5ee
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/DirectLoginInput.js
@@ -0,0 +1,203 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
+
+//#############################################################################
+
+Clipperz.PM.DataModel.DirectLoginInput = function(args) {
+ this._args = args;
+
+ return this;
+}
+
+Clipperz.PM.DataModel.DirectLoginInput.prototype = MochiKit.Base.update(null, {
+
+ 'args': function() {
+ return this._args;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'name': function() {
+ return this.args()['name'];
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'type': function() {
+ var result;
+
+ result = this.args()['type'];
+
+ if (result != null) {
+ result = result.toLowerCase();
+ }
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'options': function() {
+ return this.args()['options'];
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'value': function() {
+ return this.args()['value'];
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'formConfiguration': function(someFormValues, someBindings, someFields) {
+ var result;
+//console.log("### DirectLoginInput.formConfiguration", someFields);
+ if (this.shouldSetValue()) {
+ switch (this.type()) {
+ case 'select':
+ var currentValue;
+ var options;
+
+// currentValue = this.directLogin()._configuration['formValues'][this.name()];
+ currentValue = someFormValues[this.name()];
+ options = this.args()['options'];
+
+ result = MochiKit.DOM.SELECT({name:this.name()},
+ MochiKit.Base.map(function(anOption) {
+ var options;
+
+ options = {value:anOption['value']};
+ if (currentValue == anOption['value']) {
+ options.selected = true;
+ }
+
+ return MochiKit.DOM.OPTION(options, anOption['label'])
+ }, options)
+ )
+ break;
+ case 'checkbox':
+ var options;
+
+ options = {type:'checkbox', name: this.name()};
+// if (this.directLogin()._configuration['formValues'][this.name()] == true) {
+ if (someFormValues[this.name()] == true) {
+ options['checked'] = true;
+ };
+
+ result = MochiKit.DOM.INPUT(options, null);
+ break;
+ case 'radio':
+ var currentName;
+ var currentValue;
+ var options;
+
+ currentName = this.name();
+// currentValue = this.directLogin()._configuration['formValues'][this.name()];
+ currentValue = someFormValues[this.name()];
+ options = this.args()['options'];
+
+ result = MochiKit.DOM.DIV(null,
+ MochiKit.Base.map(function(anOption) {
+ var options;
+ var isChecked;
+ var inputNode;
+ var divNode;
+
+ options = {type:'radio', name:currentName, value:anOption['value']}
+ isChecked = (currentValue == anOption['value']);
+ if (isChecked) {
+ options.checked = true;
+ }
+
+ if (Clipperz_IEisBroken == true) {
+ var checkedValue;
+
+ checkedValue = (isChecked ? " CHECKED" : "");
+ inputNode = MochiKit.DOM.currentDocument().createElement("<INPUT TYPE='RADIO' NAME='" + currentName + "' VALUE='" + anOption['value'] + "'" + checkedValue + ">");
+ } else {
+ inputNode = MochiKit.DOM.INPUT(options, anOption['value']);
+ }
+ divNode = MochiKit.DOM.DIV(null, inputNode);
+
+ return divNode;
+ }, options)
+ );
+ break;
+ }
+ } else {
+ var binding;
+// binding = this.directLogin().bindings()[this.name()];
+ binding = someBindings[this.name()];
+
+//console.log("### binding", binding);
+//if (binding != null) {
+/// console.log(" binding.field()", binding.field());
+/// console.log(" binding.field().value()", binding.field().value());
+// console.log(" someFields[binding.fieldKey()].value()", someFields[binding.fieldKey()].value());
+//}
+ result = MochiKit.DOM.INPUT({
+ type:((this.type() != 'password') ? this.type() : 'text'),
+ name:this.name(),
+// value:((binding != null)? binding.field().value() : this.value())
+ value:((binding != null)? someFields[binding.fieldKey()]['value'] : this.value())
+// value:((binding != null)? someFields[binding.fieldKey()].value() : this.value())
+ }, null);
+ }
+
+ return result;
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'needsFormValue': function() {
+ var type;
+ var result;
+
+ type = this.type();
+ result = ((type == 'checkbox') || (type == 'radio') || (type == 'select'));
+
+ return result;
+ },
+
+ 'needsBinding': function() {
+ var type;
+ var result;
+
+ type = this.type();
+ result = ((type == 'text') || (type == 'password'));
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/EncryptedRemoteObject.js b/frontend/gamma/js/Clipperz/PM/DataModel/EncryptedRemoteObject.js
new file mode 100644
index 0000000..3408b08
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/EncryptedRemoteObject.js
@@ -0,0 +1,551 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try { if (typeof(Clipperz.KeyValueObjectStore) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.PM.DataModel.EncryptedRemoteObject depends on Clipperz.KeyValueObjectStore!";
+}
+
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
+
+Clipperz.PM.DataModel.EncryptedRemoteObject = function(args) {
+ args = args || {};
+
+ this._name = args.name || null;
+ this._reference = args.reference || Clipperz.PM.Crypto.randomKey();
+ this._isBrandNew = ((args.reference == null) && (args.remoteData == null));
+
+ if ((this._isBrandNew == false) && (args['retrieveKeyFunction'] == null)) {
+ Clipperz.Base.exception.raise('MandatoryParameter');
+ } else {
+ this._retrieveKeyFunction = args['retrieveKeyFunction'];
+ }
+
+ this._retrieveRemoteDataFunction = args.retrieveRemoteDataFunction || null;
+ this._remoteData = args.remoteData || null;
+// this._remoteData = args.remoteData ? Clipperz.Base.deepClone(args.remoteData) : null;
+ if ((!this._isBrandNew) && ((this._retrieveRemoteDataFunction == null) && (this._remoteData == null))) {
+ Clipperz.Base.exception.raise('MandatoryParameter');
+ }
+
+
+ this._encryptedDataKeypath = args.encryptedDataKeypath || 'data'; //Clipperz.Base.exception.raise('MandatoryParameter');
+ this._encryptedVersionKeypath = args.encryptedVersionKeypath || 'version'; //Clipperz.Base.exception.raise('MandatoryParameter');
+
+
+ this._transientState = null;
+ this._deferredLocks = {};
+
+ if (this._isBrandNew == true) {
+ this._objectDataStore = new Clipperz.KeyValueObjectStore(/*{'name':'EncryptedRemoteObject.objectDataStore [1]'}*/);
+ } else {
+ this._objectDataStore = null;
+ }
+
+ return this;
+}
+
+//
+// Basic data workflow
+// =======================
+//
+// getRemoteData
+// unpackRemoteData
+// getDecryptData [encryptedDataKeypath, encryptedVersionKeypath]
+// unpackData
+//
+//
+// ?? packData
+// ?? encryptDataWithKey
+// ?? packRemoteData [encryptedDataKeypath (?), encryptedVersionKeypath (?)]
+//
+
+Clipperz.PM.DataModel.EncryptedRemoteObject.prototype = MochiKit.Base.update(null, {
+
+ 'toString': function () {
+ return "Clipperz.PM.DataModel.EncryptedRemoteObject" + (this.name() != null ? " - " + this.name() : "");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'name': function () {
+ return this._name;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'reference': function () {
+ return this._reference;
+ },
+
+ 'setReference': function (aValue) {
+ this._reference = aValue;
+
+ return this._reference;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'transientState': function () {
+ if (this._transientState == null) {
+ this._transientState = new Clipperz.KeyValueObjectStore(/*{'name':'EncryptedRemoteObject.transientState [2]'}*/);
+ }
+
+ return this._transientState;
+ },
+
+ 'resetTransientState': function (isCommitting) {
+ if (this._transientState != null) {
+ this._transientState.removeAllData();
+ }
+
+ this._transientState = null;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isBrandNew': function () {
+ return this._isBrandNew;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getKey': function () {
+ var deferredResult;
+ var deferredLock;
+
+ deferredLock = this.getDeferredLockForKey('key');
+
+ deferredResult = new Clipperz.Async.Deferred("EncryptedRemoteObject.getKey", {trace:false});
+ deferredResult.acquireLock(deferredLock);
+ deferredResult.addMethod(
+ this.decryptedDataStore(),
+ 'deferredGetOrSet',
+ 'decryptionKey',
+ MochiKit.Base.partial(this.retrieveKeyFunction(), this.reference())
+ );
+ deferredResult.releaseLock(deferredLock);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+
+ 'retrieveKeyFunction': function () {
+ return this._retrieveKeyFunction;
+ },
+
+ 'setRetrieveKeyFunction': function (aFunction) {
+ this._retrieveKeyFunction = aFunction;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hasLoadedRemoteData': function () {
+ return (this._remoteData != null);
+ },
+
+ 'getRemoteData': function () {
+ var deferredResult;
+ var deferredLock;
+
+ deferredLock = this.getDeferredLockForKey('remoteData');
+
+ deferredResult = new Clipperz.Async.Deferred("EncryptedRemoteObjects.getRemoteData", {trace:false});
+ deferredResult.acquireLock(deferredLock);
+ deferredResult.addCallback(MochiKit.Base.bind(function () {
+ var innerDeferredResult;
+
+ if (this._remoteData != null) {
+ innerDeferredResult = MochiKit.Async.succeed(this._remoteData);
+ } else {
+ innerDeferredResult = Clipperz.Async.callbacks("EncryptedRemoteObjects.getRemoteData <inner deferred>", [
+ MochiKit.Base.partial(this.retrieveRemoteDataFunction(), this.reference()),
+ MochiKit.Base.method(this, 'unpackRemoteData'),
+ MochiKit.Base.bind(function (someData) {
+ this._remoteData = someData;
+ return this._remoteData;
+ }, this)
+ ], {trace:false});
+ }
+
+ return innerDeferredResult;
+ }, this))
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ deferredResult.releaseLock(deferredLock);
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'unpackRemoteData': function (someData) {
+ return MochiKit.Async.succeed(someData);
+ },
+
+ //.........................................................................
+
+ 'packRemoteData': function (someData) {
+ var result;
+
+ result = {
+ 'reference': this.reference(),
+ 'data': someData,
+ 'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion
+ };
+
+ return MochiKit.Async.succeed(result);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'retrieveRemoteDataFunction': function () {
+ return this._retrieveRemoteDataFunction;
+ },
+
+ 'setRetrieveRemoteDataFunction': function (aFunction) {
+ this._retrieveRemoteDataFunction = aFunction;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'decryptedDataStore': function () {
+ if (this._decryptedDataStore == null) {
+ this._decryptedDataStore = new Clipperz.KeyValueObjectStore(/*{'name':'EncryptedRemoteObject.decryptedDataStore [3]'}*/);
+ };
+
+ return this._decryptedDataStore;
+ },
+
+ //.........................................................................
+
+ 'getDecryptedData': function () {
+ var deferredResult;
+ var deferredLock;
+
+ deferredLock = this.getDeferredLockForKey('decryptedData');
+
+ deferredResult = new Clipperz.Async.Deferred("EncryptedRemoteObject.getDecryptedData", {trace:false});
+ deferredResult.acquireLock(deferredLock);
+ deferredResult.addMethod(this, 'decryptedDataStore');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('deferredGetOrSet', 'decryptedData', MochiKit.Base.bind(function () {
+ var innerDeferredResult;
+
+ innerDeferredResult = new Clipperz.Async.Deferred("EncryptedRemoteObject.getDecryptedData <inner deferred>", {trace:false});
+
+ innerDeferredResult.addMethod(this, 'getRemoteData');
+ innerDeferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ innerDeferredResult.collectResults({
+ 'key': MochiKit.Base.method(this, 'getKey'),
+ 'value': MochiKit.Base.itemgetter(this._encryptedDataKeypath),
+ 'version': MochiKit.Base.itemgetter(this._encryptedVersionKeypath)
+ });
+
+ innerDeferredResult.addCallback(Clipperz.PM.Crypto.deferredDecrypt);
+ innerDeferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ innerDeferredResult.addMethod(this, 'unpackData');
+ innerDeferredResult.callback();
+
+ return innerDeferredResult;
+ }, this)));
+ deferredResult.releaseLock(deferredLock);
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setValue': function(aKey, aValue) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("EncryptedRemoteObject.setValue", {trace:false});
+ deferredResult.addMethod(this, '_getObjectDataStore');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setValue', aKey, aValue));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //.........................................................................
+
+ 'getValue': function (aKey) {
+ return Clipperz.Async.callbacks("EncryptedRemoteObject.getValue", [
+ MochiKit.Base.method(this, '_getObjectDataStore'),
+ MochiKit.Base.methodcaller('getValue', aKey)
+ ], {trace:false});
+ },
+
+ //.........................................................................
+
+ 'removeValue': function (aKey) {
+ return Clipperz.Async.callbacks("EncryptedRemoteObject.removeValue", [
+ MochiKit.Base.method(this, '_getObjectDataStore'),
+ MochiKit.Base.methodcaller('removeValue', aKey)
+ ], {trace:false});
+ },
+
+ //.........................................................................
+
+ 'values': function () {
+ return Clipperz.Async.callbacks("EncryptedRemoteObject.values", [
+ MochiKit.Base.method(this, '_getObjectDataStore'),
+ MochiKit.Base.methodcaller('values')
+ ], {trace:false});
+ },
+
+ 'setValues': function (someValues) {
+ return Clipperz.Async.callbacks("EncryptedRemoteObject.values", [
+ MochiKit.Base.method(this, '_getObjectDataStore'),
+ MochiKit.Base.methodcaller('setValues', someValues)
+ ], {trace:false});
+ },
+
+ //.........................................................................
+
+ '_getObjectDataStore': function () {
+ var deferredResult;
+ var deferredLock;
+
+ deferredLock = this.getDeferredLockForKey('objectDataStore');
+
+ deferredResult = new Clipperz.Async.Deferred("EncryptedRemoteObject._getObjectDataStore", {trace:false});
+ deferredResult.acquireLock(deferredLock);
+ deferredResult.addCallback(MochiKit.Base.bind(function () {
+ var innerDeferredResult;
+
+ if (this._objectDataStore == null) {
+ this._objectDataStore = new Clipperz.KeyValueObjectStore(/*{'name':'EncryptedRemoteObject.objectDataStore [4]'}*/);
+
+ innerDeferredResult = new Clipperz.Async.Deferred("EncryptedRemoteObject._getObjectDataStore <inner deferred>", {trace:false});
+ innerDeferredResult.addMethod(this, 'getDecryptedData');
+ innerDeferredResult.addMethod(this._objectDataStore, 'initWithValues');
+ innerDeferredResult.callback();
+ } else {
+ innerDeferredResult = MochiKit.Async.succeed(this._objectDataStore);
+ }
+
+ return innerDeferredResult;
+ }, this));
+ deferredResult.releaseLock(deferredLock);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ 'hasInitiatedObjectDataStore': function () {
+ return (this._objectDataStore != null);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getDeferredLockForKey': function (aKey) {
+ var result;
+
+ result = this._deferredLocks[aKey];
+
+ if (typeof(result) == 'undefined') {
+ result = new MochiKit.Async.DeferredLock();
+ this._deferredLocks[aKey] = result;
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'unpackData': function (someData) { // ++
+ return someData;
+ },
+
+ 'packData': function (someData) { // ++
+ return someData;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hasPendingChanges': function () {
+ var deferredResult;
+ var tempObj = this;
+
+ if (this.isBrandNew()) {
+// deferredResult = MochiKit.Async.succeed(true);
+ deferredResult = this.hasPendingChangesWhenBrandNew();
+ } else if (this.hasInitiatedObjectDataStore()) {
+ deferredResult = new Clipperz.Async.Deferred("EncryptedRemoteObject.hasPendingChanges", {trace:false});
+ deferredResult.collectResults({
+ 'decryptedData': [
+ MochiKit.Base.method(this, 'getDecryptedData'),
+ Clipperz.Base.serializeJSON
+ ],
+ 'objectData': [
+ MochiKit.Base.method(this, '_getObjectDataStore'),
+ MochiKit.Base.methodcaller('values'),
+ Clipperz.Base.serializeJSON
+ ]
+ });
+ deferredResult.addCallback(function (someValues) {
+//if (someValues['decryptedData'] != someValues['objectData']) {
+// console.log("ORIGINAL DATA", '[[[' + someValues['decryptedData'] + ']]]');
+// console.log("CURRENT DATA", '>>>' + someValues['objectData'] + '<<<');
+//}
+ return (someValues['decryptedData'] != someValues['objectData']);
+ });
+ deferredResult.callback();
+ } else {
+ deferredResult = MochiKit.Async.succeed(false);
+ }
+
+ return deferredResult;
+ },
+
+ 'hasPendingChangesWhenBrandNew': function () {
+ return MochiKit.Async.succeed(true);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'commitTransientState': function () {
+ var deferredResult;
+
+// if (this.transientState().getValue('__prepareRemoteData') == true) {
+ if (this.transientState().getValue('packedRemoteData') != null) {
+ deferredResult = Clipperz.Async.callbacks("EncryptedRemoteObject.commitTransientState - prepareRemoteData", [
+ MochiKit.Base.bind(function (someData) {
+ this._remoteData = this.transientState().getValue('packedRemoteData');
+ }, this),
+
+ MochiKit.Base.method(this, '_getObjectDataStore'),
+ MochiKit.Base.methodcaller('values'),
+ Clipperz.Base.deepClone,
+ MochiKit.Base.method(this.decryptedDataStore(), 'setValue', 'decryptedData'),
+
+ MochiKit.Base.method(this, 'resetTransientState', true)
+ ], {trace:false});
+
+ } else {
+ deferredResult = Clipperz.Async.callbacks("EncryptedRemoteObject.commitTransientState - NO prepareRemoteData", [
+ MochiKit.Base.method(this, 'resetTransientState', true)
+ ], {trace:false});
+ }
+
+ this._isBrandNew = false;
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'revertChanges': function () {
+ if (this.hasInitiatedObjectDataStore()) {
+ this._objectDataStore.removeAllData();
+ this._objectDataStore = null;
+ }
+ this.resetTransientState(false);
+
+ return MochiKit.Async.succeed();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deleteAllCleanTextData': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("EncryptedRemoteObject.deleteAllCleanTextData", {trace:false});
+
+ deferredResult.addMethod(this, 'resetTransientState', false);
+
+ deferredResult.acquireLock(this.getDeferredLockForKey('decryptedData'));
+ deferredResult.addCallback(MochiKit.Base.bind(function () {
+ if (this._decryptedDataStore != null) {
+ this._decryptedDataStore.removeAllData();
+ }
+ }, this));
+ deferredResult.releaseLock(this.getDeferredLockForKey('decryptedData'));
+
+ deferredResult.acquireLock(this.getDeferredLockForKey('objectDataStore'));
+ deferredResult.addCallback(MochiKit.Base.bind(function () {
+ if (this._objectDataStore != null) {
+ this._objectDataStore.removeAllData();
+ this._objectDataStore = null;
+ }
+ }, this));
+ deferredResult.releaseLock(this.getDeferredLockForKey('objectDataStore'));
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //.........................................................................
+
+ 'hasAnyCleanTextData': function () {
+ var result;
+
+ result = false;
+
+ result = result || (! this.decryptedDataStore().isEmpty());
+ result = result || (! this.transientState().isEmpty());
+ if (this.hasInitiatedObjectDataStore()) {
+ result = result || (! this._objectDataStore.isEmpty());
+ }
+
+ return MochiKit.Async.succeed(result);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'prepareRemoteDataWithKey': function (aKey) {
+ return Clipperz.Async.callbacks("EncryptedRemoteObject.prepareRemoteDataWithKey", [
+// MochiKit.Base.method(this.transientState(), 'setValue', '__prepareRemoteData', true),
+ MochiKit.Base.method(this, '_getObjectDataStore'),
+ MochiKit.Base.methodcaller('values'),
+ MochiKit.Base.method(this, 'packData'),
+ function (someData) {
+ return Clipperz.PM.Crypto.deferredEncrypt({
+ 'key': aKey,
+ 'value': someData,
+ 'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion
+ })
+ },
+ MochiKit.Base.method(this, 'packRemoteData'),
+ MochiKit.Base.method(this.transientState(), 'setValue', 'packedRemoteData'),
+ function (someData) {
+ MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ return someData;
+ }
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/OneTimePassword.js b/frontend/gamma/js/Clipperz/PM/DataModel/OneTimePassword.js
new file mode 100644
index 0000000..9f1c197
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/OneTimePassword.js
@@ -0,0 +1,357 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
+
+
+//#############################################################################
+
+Clipperz.PM.DataModel.OneTimePassword = function(args) {
+ args = args || {};
+
+// this._user = args['user'];
+ this._reference = args['reference'] || Clipperz.PM.Crypto.randomKey();
+ this._password = args['password'];
+ this._passwordValue = Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword(args['password']);
+ this._creationDate = args['created'] ? Clipperz.PM.Date.parseDateWithUTCFormat(args['created']) : new Date();
+ this._usageDate = args['used'] ? Clipperz.PM.Date.parseDateWithUTCFormat(args['used']) : null;
+
+ this._status = args['status'] || 'ACTIVE'; // 'REQUESTED', 'USED', 'DISABLED'
+ this._connectionInfo= null;
+
+ this._key = null;
+ this._keyChecksum = null;
+
+ return this;
+}
+
+Clipperz.PM.DataModel.OneTimePassword.prototype = MochiKit.Base.update(null, {
+
+ 'toString': function() {
+ return "Clipperz.PM.DataModel.OneTimePassword";
+ },
+/*
+ //-------------------------------------------------------------------------
+
+ 'user': function() {
+ return this._user;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'password': function() {
+ return this._password;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'passwordValue': function() {
+ return this._passwordValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'creationDate': function() {
+ return this._creationDate;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'reference': function() {
+ return this._reference;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'key': function() {
+ if (this._key == null) {
+ this._key = Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword(this.user().username(), this.passwordValue());
+ }
+
+ return this._key;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'keyChecksum': function() {
+ if (this._keyChecksum == null) {
+ this._keyChecksum = Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword(this.user().username(), this.passwordValue());
+ }
+
+ return this._keyChecksum;
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'status': function() {
+ return this._status;
+ },
+
+ 'setStatus': function(aValue) {
+ this._status = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'serializedData': function() {
+ var result;
+
+ result = {
+ 'password': this.password(),
+ 'created': this.creationDate() ? Clipperz.PM.Date.formatDateWithUTCFormat(this.creationDate()) : null,
+ 'used': this.usageDate() ? Clipperz.PM.Date.formatDateWithUTCFormat(this.usageDate()) : null,
+ 'status': this.status()
+ };
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'packedPassphrase': function() {
+ var result;
+ var packedPassphrase;
+ var encodedPassphrase;
+ var prefixPadding;
+ var suffixPadding;
+ var getRandomBytes;
+
+ getRandomBytes = MochiKit.Base.method(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'getRandomBytes');
+
+ encodedPassphrase = new Clipperz.ByteArray(this.user().passphrase()).toBase64String();
+//MochiKit.Logging.logDebug("--- encodedPassphrase.length: " + encodedPassphrase.length);
+ prefixPadding = getRandomBytes(getRandomBytes(1).byteAtIndex(0)).toBase64String();
+//MochiKit.Logging.logDebug("--- prefixPadding.length: " + prefixPadding.length);
+ suffixPadding = getRandomBytes((500 - prefixPadding.length - encodedPassphrase.length) * 6 / 8).toBase64String();
+//MochiKit.Logging.logDebug("--- suffixPadding.length: " + suffixPadding.length);
+//MochiKit.Logging.logDebug("--- total.length: " + (prefixPadding.length + encodedPassphrase.length + suffixPadding.length));
+
+ packedPassphrase = {
+ 'prefix': prefixPadding,
+ 'passphrase': encodedPassphrase,
+ 'suffix': suffixPadding
+ };
+
+// result = Clipperz.Base.serializeJSON(packedPassphrase);
+ result = packedPassphrase;
+//MochiKit.Logging.logDebug("===== OTP packedPassprase: [" + result.length + "]" + result);
+//MochiKit.Logging.logDebug("<<< OneTimePassword.packedPassphrase");
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'encryptedPackedPassphrase': function() {
+ return Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion(this.passwordValue(), this.packedPassphrase())
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'encryptedData': function() {
+ var deferredResult;
+ var result;
+
+//MochiKit.Logging.logDebug(">>> OneTimePassword.encryptedData");
+//MochiKit.Logging.logDebug("--- OneTimePassword.encryptedData - id: " + this.reference());
+ result = {
+ 'reference': this.reference(),
+ 'key': this.key(),
+ 'keyChecksum': this.keyChecksum(),
+ 'data': "",
+ 'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion
+ }
+//MochiKit.Logging.logDebug("--- OneTimePassword.encryptedData - 2: " + Clipperz.Base.serializeJSON(result));
+ deferredResult = new MochiKit.Async.Deferred();
+//MochiKit.Logging.logDebug("--- OneTimePassword.encryptedData - 3");
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePassword.encryptedData - 1: " + res); return res;});
+//# deferredResult.addCallback(Clipperz.PM.Crypto.deferredEncryptWithCurrentVersion, this.passwordValue(), this.packedPassphrase());
+ deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedPackedPassphrase'));
+//MochiKit.Logging.logDebug("--- OneTimePassword.encryptedData - 4");
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePassword.encryptedData - 2: [" + res.length + "]" + res); return res;});
+ deferredResult.addCallback(function(aResult, res) {
+ aResult['data'] = res;
+ return aResult;
+ }, result);
+//MochiKit.Logging.logDebug("--- OneTimePassword.encryptedData - 5");
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePassword.encryptedData - 3: " + Clipperz.Base.serializeJSON(res)); return res;});
+ deferredResult.callback();
+//MochiKit.Logging.logDebug("--- OneTimePassword.encryptedData - 6");
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'saveChanges': function() {
+ var deferredResult;
+ var result;
+
+//MochiKit.Logging.logDebug(">>> OneTimePassword.saveChanges");
+ result = {};
+ deferredResult = new MochiKit.Async.Deferred();
+
+ deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_encryptUserData');
+ deferredResult.addCallback(MochiKit.Base.method(this.user(), 'encryptedData'));
+ deferredResult.addCallback(function(aResult, res) {
+ aResult['user'] = res;
+ return aResult;
+ }, result);
+
+ deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_encryptOTPData');
+ deferredResult.addCallback(MochiKit.Base.method(this, 'encryptedData'));
+ deferredResult.addCallback(function(aResult, res) {
+ aResult['oneTimePassword'] = res;
+ return aResult;
+ }, result);
+
+ deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_sendingData');
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePassword.saveChanges - 1: " + Clipperz.Base.serializeJSON(res)); return res;});
+ deferredResult.addCallback(MochiKit.Base.method(this.user().connection(), 'message'), 'addNewOneTimePassword');
+
+ deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'updatedProgressState', 'saveOTP_updatingInterface');
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePassword.saveChanges - 2: " + res); return res;});
+ deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'notify', 'OTPUpdated');
+ deferredResult.addCallback(Clipperz.NotificationCenter.deferredNotification, this, 'oneTimePassword_saveChanges_done', null);
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("OneTimePassword.saveChanges - 2: " + res); return res;});
+ deferredResult.callback();
+//MochiKit.Logging.logDebug("<<< OneTimePassword.saveChanges");
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'usageDate': function() {
+ return this._usageDate;
+ },
+
+ 'setUsageDate': function(aValue) {
+ this._usageDate = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'connectionInfo': function() {
+ return this._connectionInfo;
+ },
+
+ 'setConnectionInfo': function(aValue) {
+ this._connectionInfo = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isExpired': function() {
+ return (this.usageDate() != null);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateStatusWithValues': function(someValues) {
+ var result;
+
+ result = false;
+
+ if (someValues['status'] != this.status()) {
+ result = true;
+ }
+
+ this.setStatus(someValues['status']);
+ this.setUsageDate(Clipperz.PM.Date.parseDateWithUTCFormat(someValues['requestDate']));
+ this.setConnectionInfo(someValues['connection']);
+
+ return result;
+ },
+*/
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+//#############################################################################
+
+Clipperz.PM.DataModel.OneTimePassword.computeKeyWithUsernameAndPassword = function(anUsername, aPassword) {
+ return Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aPassword)).toHexString().substring(2);
+}
+
+Clipperz.PM.DataModel.OneTimePassword.computeKeyChecksumWithUsernameAndPassword = function(anUsername, aPassword) {
+ return Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(anUsername + aPassword)).toHexString().substring(2);
+}
+
+//=============================================================================
+
+Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue = function(aPassword) {
+ var result;
+
+// "yaxx k7ww - f8y6 tqz5 - 58b6 th44 - 9cwv q0fg"
+//console.log("Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue", aPassword);
+ if (aPassword.replace(/[\s\-]/g, '').length == 32) {
+ try {
+ var passwordByteArray;
+
+ passwordByteArray = new Clipperz.ByteArray();
+ passwordByteArray.appendBase32String(aPassword);
+
+ result = true;
+ } catch(exception) {
+ result = false;
+ }
+ } else {
+ result = false;
+ }
+
+ return result;
+}
+
+//=============================================================================
+
+Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword = function(aPassword) {
+ var result;
+
+ if (aPassword.replace(/[\s\-]/g, '').length == 32) {
+ try {
+ var passwordByteArray;
+
+ passwordByteArray = new Clipperz.ByteArray();
+ passwordByteArray.appendBase32String(aPassword);
+
+ result = passwordByteArray.toBase64String();
+ } catch(exception) {
+ result = aPassword;
+ }
+ } else {
+ result = aPassword;
+ }
+
+//console.log("Clipperz.PM.DataModel.OneTimePassword.normalizedOneTimePassword", aPassword, result);
+ return result;
+}
+
+//#############################################################################
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/Record.Version.Field.js b/frontend/gamma/js/Clipperz/PM/DataModel/Record.Version.Field.js
new file mode 100644
index 0000000..147aa7d
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/Record.Version.Field.js
@@ -0,0 +1,167 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try { if (typeof(Clipperz.PM.DataModel.Record.Version) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.PM.DataModel.Record.Version.Field depends on Clipperz.PM.DataModel.Record.Version!";
+}
+
+Clipperz.PM.DataModel.Record.Version.Field = function(args) {
+ Clipperz.PM.DataModel.Record.Version.Field.superclass.constructor.apply(this, arguments);
+
+ this._recordVersion = args.recordVersion || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._reference = args.reference || Clipperz.PM.Crypto.randomKey();
+
+ return this;
+}
+
+
+Clipperz.Base.extend(Clipperz.PM.DataModel.Record.Version.Field, Object, {
+
+ 'toString': function() {
+ return "Record.Version.Field (" + this.reference() + ")";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'recordVersion': function () {
+ return this._recordVersion;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'reference': function () {
+ return this._reference;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getItem': function (aKey) {
+ return Clipperz.Async.callbacks("Clipperz.PM.DataModel.Record.Version.Field.getItem", [
+ MochiKit.Base.method(this, 'recordVersion'),
+ MochiKit.Base.methodcaller('getValue', 'fields' + '.' + this.reference() + '.' + aKey)
+ ], {trace:false});
+ },
+
+ 'setItem': function (aKey, aValue) {
+ return Clipperz.Async.callbacks("Clipperz.PM.DataModel.Record.Version.Field.getItem", [
+ MochiKit.Base.method(this, 'recordVersion'),
+ MochiKit.Base.methodcaller('setValue', 'fields' + '.' + this.reference() + '.' + aKey, aValue)
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'label': function () {
+ return this.getItem('label');
+ },
+
+ 'setLabel': function (aValue) {
+ return this.setItem('label', aValue);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'value': function () {
+ return this.getItem('value');
+ },
+
+ 'setValue': function (aValue) {
+ return this.setItem('value', aValue);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'actionType': function () {
+ return Clipperz.Async.callbacks("Clipperz.PM.DataModel.Record.Version.Field.actionType", [
+ Clipperz.Async.collectResults("Clipperz.PM.DataModel.Record.Version.Field.actionType [collect results]", {
+ 'isHidden': MochiKit.Base.method(this, 'isHidden'),
+ 'value': MochiKit.Base.method(this, 'value')
+ }, {trace:false}),
+ function (someValues) {
+ var result; // 'NONE', 'URL', 'EMAIL', 'PASSWORD'
+
+ result = 'NONE';
+
+ if (someValues['isHidden']) {
+ result = 'PASSWORD';
+ } else if (Clipperz.Base.isUrl(someValues['value'])) {
+ result = 'URL'
+ } else if (Clipperz.Base.isEmail(someValues['value'])) {
+ result = 'EMAIL'
+ };
+
+ return result;
+ }
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isHidden': function () {
+ return this.getItem('hidden');
+ },
+
+ 'setIsHidden': function (aValue) {
+ return this.setItem('hidden', aValue);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isEmpty': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.Record.Version.Field.isEmpty", {trace:false});
+
+ deferredResult.collectResults({
+ 'label': [
+ MochiKit.Base.method(this, 'label'),
+ MochiKit.Base.partial(MochiKit.Base.operator.eq, '')
+ ],
+ 'value': [
+ MochiKit.Base.method(this, 'value'),
+ MochiKit.Base.partial(MochiKit.Base.operator.eq, '')
+ ],
+ 'isHidden': [
+ MochiKit.Base.method(this, 'isHidden'),
+ MochiKit.Base.partial(MochiKit.Base.operator.eq, false)
+ ]
+ });
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(function(someValues) {
+ return MochiKit.Iter.every(someValues, MochiKit.Base.operator.identity);
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/Record.Version.js b/frontend/gamma/js/Clipperz/PM/DataModel/Record.Version.js
new file mode 100644
index 0000000..6e50f8e
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/Record.Version.js
@@ -0,0 +1,336 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try { if (typeof(Clipperz.PM.DataModel.Record) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.PM.DataModel.Record.Version depends on Clipperz.PM.DataModel.Record!";
+}
+
+Clipperz.PM.DataModel.Record.Version = function(args) {
+//console.log(">>> Record.new");
+ Clipperz.PM.DataModel.Record.Version.superclass.constructor.apply(this, arguments);
+
+ this._getVersionFunction = args.getVersion || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._fields = null;
+
+ return this;
+}
+
+
+Clipperz.Base.extend(Clipperz.PM.DataModel.Record.Version, Clipperz.PM.DataModel.EncryptedRemoteObject, {
+
+ 'toString': function() {
+ return "Record.Version (" + this.reference() + ")";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'reference': function () {
+ return this._reference;
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'hasPendingChanges': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.Record.Version.hasPendingChanges", {trace:false});
+ deferredResult.addCallback(MochiKit.Base.bind(Clipperz.PM.DataModel.Record.Version.superclass.hasPendingChanges, this));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+*/
+ //-------------------------------------------------------------------------
+
+
+ 'hasPendingChangesWhenBrandNew': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.Record.Version.hasPendingChangesWhenBrandNew", {trace:false});
+ deferredResult.addMethod(this, 'fields');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.methodcaller('isEmpty'))
+ deferredResult.addCallback(Clipperz.Async.collectAll);
+ deferredResult.addCallback(function(someValues) {
+ return MochiKit.Iter.every(someValues, MochiKit.Base.operator.identity);
+ });
+ deferredResult.addCallback(MochiKit.Base.operator.lognot)
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'commitTransientState': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.Record.Version.commitTransientState", {trace:false});
+ deferredResult.addCallback(MochiKit.Base.bind(Clipperz.PM.DataModel.Record.Version.superclass.commitTransientState, this));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'unpackData': function (someData) { // ++
+ var result;
+
+//console.log("Record.Version - UNPACK DATA", this, someData);
+ result = someData;
+ if ((someData['fields'] != null) && (someData['fields'] instanceof Array)) {
+ var fields;
+ var i,c;
+
+ fields = someData['fields'];
+ delete someData['fields'];
+
+ someData['fields'] = {};
+ c = fields.length;
+ for (i=0; i<c; i++) {
+ someData['fields'][i] = fields[i];
+ }
+ }
+
+
+
+ return result;
+ },
+
+ //=========================================================================
+
+ 'fields': function () {
+ var deferredResult;
+ var deferredLock;
+
+ deferredLock = this.getDeferredLockForKey('fields');
+
+ deferredResult = new Clipperz.Async.Deferred("Record.Version.fields", {trace:false});
+ deferredResult.acquireLock(deferredLock);
+ deferredResult.addCallback(MochiKit.Base.bind(function () {
+ var innerDeferredResult;
+
+ if (this._fields == null) {
+ innerDeferredResult = new Clipperz.Async.Deferred("Record.Version.fields <inner deferred>", {trace:false});
+ innerDeferredResult.addMethod(this, 'getValue', 'fields');
+ innerDeferredResult.addCallback(MochiKit.Base.bind(function (someObjectData) {
+ var reference;
+
+ this._fields = {};
+
+ for (reference in someObjectData) {
+ var recordVersionField;
+
+ recordVersionField = new Clipperz.PM.DataModel.Record.Version.Field({
+ 'recordVersion': this,
+ 'reference': reference
+ });
+
+ this._fields[reference] = recordVersionField;
+ }
+
+ return this._fields;
+ }, this));
+ innerDeferredResult.callback();
+ } else {
+ innerDeferredResult = MochiKit.Async.succeed(this._fields);
+ }
+
+ return innerDeferredResult;
+ }, this));
+ deferredResult.releaseLock(deferredLock);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getFieldsValues': function () {
+ return this.getValue('fields');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addField': function (someParameters) {
+ var newField;
+
+ newField = new Clipperz.PM.DataModel.Record.Version.Field({recordVersion:this});
+
+ return Clipperz.Async.callbacks("Record.Version.addField", [
+ MochiKit.Base.method(this, 'fields'),
+
+ MochiKit.Base.method(this, '_getObjectDataStore'),
+ MochiKit.Base.methodcaller('values'),
+ Clipperz.Base.serializeJSON,
+
+ MochiKit.Base.bind(function () { this._fields[newField.reference()] = newField; }, this),
+ MochiKit.Base.method(newField, 'setLabel', someParameters['label']),
+ MochiKit.Base.method(newField, 'setValue', someParameters['value']),
+ MochiKit.Base.method(newField, 'setIsHidden', someParameters['isHidden']),
+
+ MochiKit.Base.method(this, '_getObjectDataStore'),
+ MochiKit.Base.methodcaller('values'),
+ Clipperz.Base.serializeJSON,
+
+ MochiKit.Base.partial(MochiKit.Async.succeed, newField)
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'removeField': function (aField) {
+ return Clipperz.Async.callbacks("Record.Version.removeField", [
+ MochiKit.Base.method(this, 'fields'),
+ MochiKit.Base.bind(function () { delete this._fields[aField.reference()]; }, this),
+ MochiKit.Base.method(this, 'removeValue', 'fields' + '.' + aField.reference())
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'sortFieldReference': function (someSortedFieldReferences) {
+
+
+
+ },
+*/
+ //=========================================================================
+/*
+ 'directLogins': function () {
+ return MochiKit.Base.values(this._directLogins);
+ },
+
+ 'addDirectLogin': function (aDirectLogin) {
+ this._directLogins[aDirectLogin.reference()] = aDirectLogin;
+ },
+*/
+
+ //=========================================================================
+/*
+ 'updateValues': function (anotherVersion) {
+ return Clipperz.Async.callbacks("Record.Version.updateValue", [
+ MochiKit.Base.partial(MochiKit.Async.succeed, this)
+ ], {trace:false});
+ },
+*/
+ //=========================================================================
+
+ 'setRemoteData': function (aValue) {
+ this._remoteData = aValue;
+
+ return aValue;
+ },
+
+ //=========================================================================
+
+ 'getVersionFunction': function () {
+ return this._getVersionFunction;
+ },
+
+ 'previousVersion': function () {
+ return Clipperz.Async.callbacks("Record.Versions.previousVersion", [
+ MochiKit.Base.method(this, 'previousVersionReference'),
+ this.getVersionFunction()
+ ], {trace:false});
+ },
+
+ 'previousVersionReference': function () {
+ return this.getValue('previousVersionReference');
+ },
+
+ 'previousVersionKey': function () {
+// TODO: this value i encrypted on its own. So it can not be saved in the main objectStore!!!
+ return this.getValue('previousVersionKey');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setPreviousVersionReferenceAndKey': function (aVersionObjectAndKey) {
+// this._previousVersion = anotherVersion;
+ return Clipperz.Async.callbacks("Record.Version.setPreviousVersion", [
+ MochiKit.Base.method(this, 'setValue', 'previousVersionReference', aVersionObjectAndKey['reference']),
+ MochiKit.Base.method(this, 'setValue', 'previousVersionKey', aVersionObjectAndKey['key'])
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'revertChanges': function () {
+ this.setReference(this.transientState()['originalReference']);
+ Clipperz.PM.DataModel.Record.Version.superclass.revertChanges.apply(this, arguments);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'prepareRemoteDataWithKey': function (aKey) {
+ var deferredResult;
+ var result;
+
+ result = {};
+
+//console.log("prepareRemoteDataWithKey", aKey);
+ deferredResult = new Clipperz.Async.Deferred("Record.Version.prepareRemoteDataWithKey", {trace:false});
+ if (this.isBrandNew() == false) {
+ this.transientState()['originalReference'] = this.reference();
+
+ deferredResult.collectResults({
+ 'key': MochiKit.Base.partial(MochiKit.Async.succeed, aKey),
+ 'value': MochiKit.Base.method(this, 'getKey'),
+ 'version': MochiKit.Base.partial(MochiKit.Async.succeed, Clipperz.PM.Crypto.encryptingFunctions.currentVersion)
+ });
+ deferredResult.addCallback(Clipperz.PM.Crypto.deferredEncrypt);
+ deferredResult.addCallback(Clipperz.Async.setItem, result, 'previousVersionKey');
+ } else {
+ deferredResult.addCallback(Clipperz.Async.setItem, result, 'previousVersionKey', Clipperz.PM.Crypto.nullValue);
+ }
+ deferredResult.addCallback(MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.prepareRemoteDataWithKey, this, aKey));
+ deferredResult.addCallback(MochiKit.Base.update, result);
+ deferredResult.addMethod(this, 'setRemoteData');
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+/*
+ 'deleteAllCleanTextData': function () {
+ return Clipperz.PM.DataModel.Record.Version.superclass.deleteAllCleanTextData.apply(this, arguments);
+ },
+
+ 'hasAnyCleanTextData': function () {
+ return Clipperz.PM.DataModel.Record.Version.superclass.hasAnyCleanTextData.apply(this, arguments);
+ },
+*/
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/Record.js b/frontend/gamma/js/Clipperz/PM/DataModel/Record.js
new file mode 100644
index 0000000..85dd06b
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/Record.js
@@ -0,0 +1,881 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
+
+
+Clipperz.PM.DataModel.Record = function(args) {
+//console.log(">>> new Clipperz.PM.DataModel.Record", args);
+ Clipperz.PM.DataModel.Record.superclass.constructor.apply(this, arguments);
+
+ this._updateDate = (args.updateDate ? Clipperz.PM.Date.parse(args.updateDate) : Clipperz.Base.exception.raise('MandatoryParameter'));
+
+ this._retrieveIndexDataFunction = args.retrieveIndexDataFunction || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._updateIndexDataFunction = args.updateIndexDataFunction || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ this._retrieveDirectLoginIndexDataFunction = args.retrieveDirectLoginIndexDataFunction || null;
+ this._setDirectLoginIndexDataFunction = args.setDirectLoginIndexDataFunction || null;
+ this._removeDirectLoginIndexDataFunction = args.removeDirectLoginIndexDataFunction || null;
+
+ this._createNewDirectLoginFunction = args.createNewDirectLoginFunction || null;
+
+ this._directLogins = {};
+
+ this._versions = {};
+
+ this._currentRecordVersion = null;
+ if (this.isBrandNew()) {
+ var newVersion;
+
+ this.setNotes('');
+ newVersion = new Clipperz.PM.DataModel.Record.Version({
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getVersionKey'),
+ 'getVersion': MochiKit.Base.method(this, 'getVersion')
+
+ });
+ this._versions[newVersion.reference()] = newVersion;
+ this._currentVersionReference = newVersion.reference();
+// this.setLabel('');
+ }
+
+//console.log("<<< new Clipperz.PM.DataModel.Record", args);
+
+ return this;
+}
+
+
+Clipperz.Base.extend(Clipperz.PM.DataModel.Record, Clipperz.PM.DataModel.EncryptedRemoteObject, {
+
+ 'toString': function() {
+ return "Record (" + this.reference() + ")";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'reference': function () {
+ return this._reference;
+ },
+
+ //=========================================================================
+
+ 'getIndexData': function () {
+ return this._retrieveIndexDataFunction(this.reference());
+ },
+
+ //.........................................................................
+
+ 'getIndexDataForKey': function (aKey) {
+ return Clipperz.Async.callbacks("Record.getIndexDataForKey", [
+ MochiKit.Base.method(this, 'getIndexData'),
+ MochiKit.Base.itemgetter(aKey)
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setIndexDataForKey': function (aKey, aValue) {
+// return this._updateIndexDataFunction(this.reference(), aKey, aValue);
+
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Record.setIndexDataForKey", {trace:false});
+ deferredResult.addMethod(this, 'getIndexDataForKey', aKey);
+ deferredResult.addCallback(MochiKit.Base.bind(function (aCurrentValue) {
+ var result;
+ var originalValue;
+
+ originalValue = this.transientState().getValue('originalValues.indexData.' + aKey);
+ if (originalValue == null) {
+ originalValue = this.transientState().setValue('originalValues.indexData.' + aKey, aCurrentValue);
+ }
+
+ if (aCurrentValue != aValue) {
+ if (originalValue != aValue) {
+ this.transientState().setValue('hasPendingChanges.indexData.' + aKey, true);
+ } else {
+ this.transientState().setValue('hasPendingChanges.indexData.' + aKey, false);
+ }
+
+ result = this._updateIndexDataFunction(this.reference(), aKey, aValue);
+ } else {
+ result = MochiKit.Async.succeed(aValue);
+ }
+
+ return result;
+ }, this));
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+/*
+ 'key': function () {
+ return this.getIndexDataForKey('key');
+ },
+*/
+ //=========================================================================
+
+ 'label': function () {
+ return this.getIndexDataForKey('label');
+ },
+
+ //.........................................................................
+
+ 'setLabel': function (aValue) {
+ return this.setIndexDataForKey('label', aValue);
+ },
+
+ //=========================================================================
+
+ 'headerNotes': function () {
+ return this.getIndexDataForKey('notes');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'notes': function () {
+ return Clipperz.Async.callbacks("Record.notes", [
+ MochiKit.Base.method(this, 'headerNotes'),
+ MochiKit.Base.bind(function (someHeaderNotes) {
+ var result;
+
+ if ((someHeaderNotes == null) || (typeof(someHeaderNotes) == 'undefined')) {
+ result = this.getValue('notes');
+ } else {
+ result = MochiKit.Async.succeed(someHeaderNotes);
+ }
+
+ return result;
+ }, this)
+ ], {trace:false});
+ },
+
+ //.........................................................................
+
+ 'setNotes': function (aValue) {
+ return this.setValue('notes', aValue);
+ },
+
+ //=========================================================================
+
+ 'updateDate': function () {
+ return MochiKit.Async.succeed(this._updateDate);
+ },
+
+ //=========================================================================
+
+ 'favicon': function () {
+ var result;
+ var directLogins;
+
+ directLogins = MochiKit.Base.values(this.directLogins());
+ if (directLogins.length > 0) {
+ result = directLogins[0].favicon();
+// } else if (/* is there an URL to use for searching a favicon */){
+ } else {
+ result = null; // MochiKit.Async.succeed(Clipperz.PM.Strings['defaultFaviconUrl']);
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'searchableContent': function () {
+ var deferredResult;
+
+//console.log(">>> searchableContent");
+ deferredResult = new Clipperz.Async.Deferred("Record.searchableContent", {trace:false});
+
+ deferredResult.collectResults({
+ 'recordLabel': MochiKit.Base.method(this, 'label'),
+ 'directLoginLabels': [
+ MochiKit.Base.method(this, 'directLoginReferences'),
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.itemgetter('label'))
+ ]
+ })
+ deferredResult.addCallback(function (someValues) {
+ return someValues['recordLabel'] + ' ' + someValues['directLoginLabels'].join(' ');
+ });
+ deferredResult.callback();
+//console.log("<<< searchableContent");
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isMatching': function (aRegExp) {
+ return Clipperz.Async.callbacks("deferredFilterFunction", [
+ MochiKit.Base.method(this, 'searchableContent'),
+ MochiKit.Base.method(aRegExp, 'test'),
+ function (doesItMatch) {
+ var result;
+
+ if (doesItMatch) {
+ result = MochiKit.Async.succeed('match');
+ } else {
+ result = MochiKit.Async.fail('miss');
+ }
+
+ return result;
+ }
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'directLogins': function () {
+ return this._directLogins;
+ },
+
+ 'addDirectLogin': function (aDirectLogin) {
+ this._directLogins[aDirectLogin.reference()] = aDirectLogin;
+ },
+
+ 'directLoginWithReference': function (aDirectLoginReference) {
+ return this._directLogins[aDirectLoginReference];
+ },
+
+ 'createNewDirectLoginFunction': function () {
+ return this._createNewDirectLoginFunction;
+ },
+
+ 'saveOriginalDirectLoginStatusToTransientState': function () {
+ if (this.transientState().getValue('directLogins') == null) {
+// this.transientState().setValue('directLogins', this._directLogins)
+//console.log("SET TRANSIENT STATE", Clipperz.Base.serializeJSON(MochiKit.Base.keys(this.transientState().getValue('directLogins'))))
+ MochiKit.Iter.forEach(MochiKit.Base.keys(this._directLogins), MochiKit.Base.bind(function(aKey) {
+ this.transientState().setValue('directLogins' + '.' + aKey, this._directLogins[aKey])
+ }, this))
+ }
+ },
+
+ 'createNewDirectLogin': function () {
+ this.saveOriginalDirectLoginStatusToTransientState();
+
+ return this.createNewDirectLoginFunction()(this);
+ },
+
+ 'removeDirectLogin': function(aDirectLogin) {
+ this.saveOriginalDirectLoginStatusToTransientState();
+
+ return Clipperz.Async.callbacks("Record.removeDirectLogin", [
+ MochiKit.Base.method(this, 'removeValue', 'directLogins' + '.' + aDirectLogin.reference()),
+ MochiKit.Base.bind(function () {
+ delete this._directLogins[aDirectLogin.reference()]
+ }, this)
+ ], {trace:false});
+
+ },
+
+ 'directLoginReferences': function () {
+ var result;
+
+ result = Clipperz.Async.callbacks("Record.directLoginReferences", [
+ MochiKit.Base.method(this, 'directLogins'),
+ MochiKit.Base.values,
+ function (someDirectLogins) {
+ var result;
+ var i,c;
+
+ result = [];
+ c = someDirectLogins.length;
+ for (i=0; i<c; i++) {
+ result.push(Clipperz.Async.collectResults("Record.directLoginReferences - collectResults", {
+ '_rowObject': MochiKit.Async.succeed,
+ '_reference': MochiKit.Base.methodcaller('reference'),
+ 'label': MochiKit.Base.methodcaller('label'),
+ 'favicon': MochiKit.Base.methodcaller('favicon')
+ }, {trace:false})(someDirectLogins[i]));
+ };
+
+ return result;
+ },
+ Clipperz.Async.collectAll
+ ], {trace:false});
+
+ return result;
+ },
+
+ //=========================================================================
+
+ 'unpackRemoteData': function (someData) {
+ var result;
+
+//console.log("new Clipperz.PM.DataModel.Record.Version [2]");
+/*
+ this._currentRecordVersion = new Clipperz.PM.DataModel.Record.Version({
+ 'reference': someData['currentVersion']['reference'],
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getCurrentRecordVersionKey'),
+ 'remoteData': someData['currentVersion'],
+ });
+*/
+ var versionKey;
+
+ for (versionKey in someData['versions']) {
+//console.log("### versionKey", versionKey);
+ this._versions[versionKey] = new Clipperz.PM.DataModel.Record.Version({
+ 'reference': versionKey,
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getVersionKey'),
+ 'remoteData': someData['versions'][versionKey],
+ 'getVersion': MochiKit.Base.method(this, 'getVersion')
+ })
+ }
+
+// this._currentVersionReference = someData['currentVersion']['reference'];
+ this._currentVersionReference = someData['currentVersion'];
+//console.log("=== currentVersionReference", this._currentVersionReference, someData);
+
+ result = Clipperz.PM.DataModel.Record.superclass.unpackRemoteData.apply(this, arguments);
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'unpackData': function (someData) {
+ var result;
+
+ result = Clipperz.PM.DataModel.Record.superclass.unpackData.apply(this, arguments);
+
+ if (MochiKit.Base.isUndefinedOrNull(result['notes'])) {
+ result['notes'] = ''
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'prepareRemoteDataWithKey': function (aKey) {
+ var deferredResult;
+ var newVersionKey;
+ var result;
+
+ newVersionKey = Clipperz.PM.Crypto.randomKey();
+ result = {};
+
+ deferredResult = new Clipperz.Async.Deferred("Record.prepareRemoteDataWithKey", {trace:false});
+ deferredResult.addCallbackList([
+ Clipperz.Async.collectResults("Record.prepareRemoteDataWithKey - collect results", {
+ 'isBrandNew': MochiKit.Base.method(this, 'isBrandNew'),
+ 'versionHasPendingChanges': [
+// MochiKit.Base.method(this, 'getCurrentRecordVersion'),
+// MochiKit.Base.methodcaller('hasPendingChanges')
+ MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'hasPendingChanges')
+ ]
+ }),
+ Clipperz.Async.or,
+
+ Clipperz.Async.deferredIf("Current Version has pending changes", [
+ MochiKit.Base.method(this, 'createNewRecordVersion'),
+ MochiKit.Base.methodcaller('prepareRemoteDataWithKey', newVersionKey),
+ MochiKit.Base.partial(Clipperz.Async.setItem, result, 'currentRecordVersion'),
+ MochiKit.Base.method(this, 'setCurrentRecordVersionKey', newVersionKey)
+ ], []),
+
+ MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.prepareRemoteDataWithKey, this, aKey),
+ MochiKit.Base.partial(Clipperz.Async.setItem, result, 'record'),
+
+ MochiKit.Base.partial(MochiKit.Async.succeed, result)
+ ]);
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'fields': function () {
+ return this.invokeCurrentRecordVersionMethod('fields');
+ },
+
+ 'addField': function (someParameters) {
+ return this.invokeCurrentRecordVersionMethod('addField', someParameters);
+ },
+
+ 'removeField': function (someParameters) {
+ return this.invokeCurrentRecordVersionMethod('removeField', someParameters);
+ },
+
+// 'sortFieldReference': function (someSortedFieldReferences) {
+// return this.invokeCurrentRecordVersionMethod('sortFieldReference', someSortedFieldReferences);
+// },
+
+ 'getFieldsValues': function () {
+ return this.invokeCurrentRecordVersionMethod('getFieldsValues');
+ },
+
+ 'fieldWithLabel': function (aLabel) {
+ return Clipperz.Async.callbacks("Record.fieldWithLabel", [
+ MochiKit.Base.method(this, 'fields'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(Clipperz.Async.deferredFilter, function (aField) {
+ return Clipperz.Async.callbacks("Record.fieldWithLabel - check field label", [
+ MochiKit.Base.methodcaller('label'),
+ MochiKit.Base.partial(MochiKit.Base.operator.eq, aLabel)
+ ], {trace:false}, aField);
+ }),
+ function (someFilteredResults) {
+ var result;
+
+ switch (someFilteredResults.length) {
+ case 0:
+ result = null;
+ break;
+ case 1:
+ result = someFilteredResults[0];
+ break;
+ default:
+ WTF = TODO;
+ break;
+ }
+
+ return result;
+ }
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'getVersion': function (aVersionReference) {
+ return Clipperz.Async.callbacks("Record.getVersion", [
+ MochiKit.Base.method(this, 'getVersions'),
+ MochiKit.Base.itemgetter(aVersionReference)
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getVersionKey': function (aVersionReference) {
+ var deferredResult;
+ var transientStateKey;
+
+ transientStateKey = 'versionKeys' + '.' + aVersionReference;
+ if (this.transientState().getValue(transientStateKey) != null) {
+ deferredResult = MochiKit.Async.succeed(this.transientState().getValue(transientStateKey));
+ } else {
+ deferredResult = Clipperz.Async.callbacks("Record.getVersionKey", [
+ MochiKit.Base.method(this, 'getVersions'),
+ MochiKit.Base.partial(MochiKit.Base.operator.eq, aVersionReference, this.currentVersionReference()),
+ Clipperz.Async.deferredIf("getVersionKey for current version", [
+ MochiKit.Base.method(this, 'getCurrentRecordVersionKey'),
+ MochiKit.Base.method(this.transientState(), 'setValue', transientStateKey)
+ ],[
+ MochiKit.Async.fail
+ ])
+ ], {trace:false});
+ }
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'versions': function () {
+ return this._versions;
+ },
+
+ 'getVersions': function () {
+ return Clipperz.Async.callbacks("Record.versions", [
+ MochiKit.Base.method(this, 'getValue', 'fakeKey, just to trigger unpackRemoteData'),
+ MochiKit.Base.bind(function () { return this._versions; }, this)
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getCurrentRecordVersion': function () {
+ return Clipperz.Async.callbacks("Record.getCurrentRecordVersion", [
+// MochiKit.Base.method(this, 'getValue', 'fakeKey, just to trigger unpackRemoteData'),
+// MochiKit.Base.bind(function () { return this._currentRecordVersion; }, this)
+
+ MochiKit.Base.method(this, 'versions'),
+ MochiKit.Base.itemgetter(this.currentVersionReference()),
+ Clipperz.Async.deferredIf("The current version is available", [
+ MochiKit.Async.succeed
+ ], [
+ MochiKit.Base.method(this, 'getVersions'),
+ MochiKit.Base.bind(function (someVersions) { return someVersions[this.currentVersionReference()]}, this)
+ ])
+ ], {trace:false});
+ },
+
+ 'setCurrentRecordVersion': function (aRecordVersion) {
+ this._currentVersionReference = aRecordVersion.reference();
+ },
+
+ //.........................................................................
+
+ 'currentVersionReference': function () {
+//console.log("currentVersionReference");
+ return this._currentVersionReference;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'createNewRecordVersion': function () {
+ var deferredResult;
+
+ if (this.isBrandNew()) {
+ deferredResult = this.getCurrentRecordVersion();
+ } else {
+ var newVersion;
+
+ newVersion = new Clipperz.PM.DataModel.Record.Version({
+ // 'reference': versionKey,
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getVersionKey'),
+// 'remoteData': {},
+ 'getVersion': MochiKit.Base.method(this, 'getVersion')
+ })
+ this._versions[newVersion.reference()] = newVersion;
+
+ deferredResult = Clipperz.Async.callbacks("Record.createNewRecordVersion", [
+// MochiKit.Base.method(this, 'getCurrentRecordVersion'),
+// MochiKit.Base.methodcaller('values'),
+ MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'values'),
+ MochiKit.Base.method(newVersion, 'setValues'),
+
+ Clipperz.Async.collectResults("Record.createNewRecordVersion [collect results]", {
+ 'reference': MochiKit.Base.method(this, 'currentVersionReference'),
+ 'key': MochiKit.Base.method(this, 'getCurrentRecordVersionKey')
+ }, {trace:false}),
+ MochiKit.Base.method(newVersion, 'setPreviousVersionReferenceAndKey'),
+
+// MochiKit.Base.method(this, 'getCurrentRecordVersion'),
+// MochiKit.Base.method(this, 'revertChanges'),
+ MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'revertChanges'),
+
+ MochiKit.Base.method(this, 'setCurrentRecordVersion', newVersion),
+ MochiKit.Base.partial(MochiKit.Async.succeed, newVersion)
+ ], {trace:false});
+ }
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getCurrentRecordVersionKey': function () {
+//console.log("getCurrentRecordVersionKey");
+ return Clipperz.Async.callbacks("Record.getCurrentRecordVersionKey", [
+ MochiKit.Base.method(this, 'getValue', 'currentVersionKey'),
+ Clipperz.Async.deferredIf("currentVersionKey is NOT null", [
+ MochiKit.Async.succeed
+ ], [
+ MochiKit.Base.method(this, 'getKey')
+ ])
+ ], {trace:false});
+ },
+
+ 'setCurrentRecordVersionKey': function (aValue) {
+ // TODO: triple check this method!
+ return Clipperz.Async.callbacks("Record.setCurrentRecordVersionKey", [
+ MochiKit.Base.method(this, 'setValue', 'currentVersionKey', aValue)
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'invokeCurrentRecordVersionMethod': function (aMethodName, someValues) {
+//console.log(">>> invokeCurrentRecordVersionMethod", aMethodName);
+ return Clipperz.Async.callbacks("Record.invokeCurrentRecordVersionMethod", [
+ MochiKit.Base.method(this, 'getCurrentRecordVersion'),
+//function (aValue) { console.log("=== getCurrentRecordVersion", aValue); return aValue},
+ MochiKit.Base.methodcaller(aMethodName, someValues)
+ ], {trace:false});
+ },
+
+
+ 'lazilyinvokeCurrentRecordVersionMethod': function (aMethodName, someValues, defaultResult) {
+ return Clipperz.Async.callbacks("Record.lazilyinvokeCurrentRecordVersionMethod", [
+ MochiKit.Base.method(this, 'currentVersionReference'),
+//function (aValue) { console.log("LAZY -> versions", aValue); return aValue; },
+ Clipperz.Async.deferredIf("versions has been loaded", [
+//function (aValue) { console.log("LAZY -> then"); return aValue; },
+ MochiKit.Base.method(this, 'getCurrentRecordVersion'),
+ MochiKit.Base.methodcaller(aMethodName, someValues),
+//function (aValue) { console.log("LAZY <- then"); return aValue; }
+ ], [
+//function (aValue) { console.log("LAZY -> else"); return aValue; },
+ MochiKit.Base.partial(MochiKit.Async.succeed, defaultResult),
+//function (aValue) { console.log("LAZY <- else"); return aValue; }
+ ])
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'hasPendingChanges': function () {
+ var deferredResult;
+
+ if (this.hasInitiatedObjectDataStore()) {
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.Record.hasPendingChanges", {trace:false});
+ deferredResult.collectResults({
+ 'super': MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.hasPendingChanges, this),
+ 'currentVersion': [
+// MochiKit.Base.method(this, 'getCurrentRecordVersion'),
+// MochiKit.Base.methodcaller('hasPendingChanges')
+ MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'hasPendingChanges')
+ ],
+ 'directLogins': [
+ MochiKit.Base.method(this, 'directLogins'),
+//function (aValue) { console.log("Record.directLogins", aValue); return aValue; },
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasPendingChanges')),
+ Clipperz.Async.collectAll,
+ Clipperz.Async.or
+// function(someValues) {
+// return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
+// }
+ ]
+ });
+//deferredResult.addCallback(function (aValue) { console.log("Record.hasPendingResults", aValue); return aValue; });
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(MochiKit.Base.bind(function(someValues) {
+ var result;
+ result = MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
+
+ if ((result == false) && (this.isBrandNew() == false)) {
+ result = MochiKit.Iter.some(MochiKit.Base.values(this.transientState().getValue('hasPendingChanges.indexData')), MochiKit.Base.operator.identity);
+ }
+
+ return result;
+ }, this));
+
+ deferredResult.callback();
+ } else {
+ deferredResult = Clipperz.Async.callbacks("Recrod.hasPendingChanges [hasInitiatedObjectDataStore == false]", [
+ MochiKit.Base.method(this, 'directLogins'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasPendingChanges')),
+ Clipperz.Async.collectAll,
+ Clipperz.Async.or
+// function(someValues) {
+// return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
+// }
+ ], {trace:false})
+ }
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hasPendingChangesWhenBrandNew': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.Record.hasPendingChangesWhenBrandNew", {trace:false});
+ deferredResult.collectResults({
+ 'label': [
+ MochiKit.Base.method(this, 'label'),
+ MochiKit.Base.partial(MochiKit.Base.operator.ne, '')
+ ],
+ 'notes': [
+ MochiKit.Base.method(this, 'notes'),
+ MochiKit.Base.partial(MochiKit.Base.operator.ne, '')
+ ]
+ });
+// deferredResult.addCallback(MochiKit.Base.values);
+// deferredResult.addCallback(function(someValues) {
+// return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
+// });
+ deferredResult.addCallback(Clipperz.Async.or);
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isBrandNewWithNoPendingChanges': function () {
+ var deferredResult;
+
+ if (this.isBrandNew() == false) {
+ deferredResult = MochiKit.Async.succeed(false);
+ } else {
+ deferredResult = Clipperz.Async.callbacks("Record.isBrandNewWithNoPendingChanges", [
+ MochiKit.Base.method(this, 'hasPendingChanges'),
+ MochiKit.Base.operator.lognot
+ ], {trace:false});
+ }
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'revertChanges': function () {
+ var deferredResult;
+
+ if (this.isBrandNew() == false) {
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.Record.revertChanges", {trace:false});
+ deferredResult.addMethod(this, 'hasPendingChanges');
+ deferredResult.addIf([
+// MochiKit.Base.method(this, 'getCurrentRecordVersion'),
+// MochiKit.Base.methodcaller('revertChanges'),
+ MochiKit.Base.method(this,'invokeCurrentRecordVersionMethod', 'revertChanges'),
+
+ MochiKit.Base.method(this, 'directLogins'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('revertChanges')),
+
+ MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.revertChanges, this)
+ ], [
+ MochiKit.Async.succeed
+ ]);
+ deferredResult.callback();
+ } else {
+// this.deleteAllCleanTextData();
+ deferredResult = MochiKit.Async.succeed();
+ }
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'resetTransientState': function (isCommitting) {
+// if ((isCommitting == false) && (this.transientState().getValue('directLogins') != null)) {
+// this._directLogins = this.transientState().getValue('directLogins');
+// }
+
+ return Clipperz.Async.callbacks("Record.resetTransientState", [
+//- MochiKit.Base.method(this, 'getCurrentRecordVersion'),
+//- MochiKit.Base.methodcaller('resetTransientState'),
+// MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'resetTransientState'),
+ MochiKit.Base.method(this, 'lazilyinvokeCurrentRecordVersionMethod', 'resetTransientState'),
+
+ MochiKit.Base.method(this, 'directLogins'),
+//function (aValue) { console.log("resetTransientState - directLogins", aValue); return aValue; },
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('resetTransientState')),
+
+ MochiKit.Base.bind(function () {
+ if ((isCommitting == false) && (this.transientState().getValue('directLogins') != null)) {
+ this._directLogins = this.transientState().getValue('directLogins');
+ }
+ }, this),
+
+ MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.resetTransientState, this, isCommitting)
+ ], {trace:false})
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'commitTransientState': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.Record.commitTransientState", {trace:false});
+ deferredResult.addMethod(this, 'hasPendingChanges');
+ deferredResult.addIf([
+ MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.commitTransientState, this),
+// MochiKit.Base.method(this, 'getCurrentRecordVersion'),
+// MochiKit.Base.methodcaller('commitTransientState'),
+ MochiKit.Base.method(this, 'invokeCurrentRecordVersionMethod', 'commitTransientState'),
+ MochiKit.Base.method(this, 'directLogins'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('commitTransientState'))
+ ], [
+ MochiKit.Async.succeed
+ ]);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'retrieveDirectLoginIndexDataFunction': function () {
+//console.log("Record.retrieveDirectLoginIndexDataFunction", this._retrieveDirectLoginIndexDataFunction);
+ return this._retrieveDirectLoginIndexDataFunction;
+ },
+
+ 'setDirectLoginIndexDataFunction': function () {
+ return this._setDirectLoginIndexDataFunction;
+ },
+
+ 'removeDirectLoginIndexDataFunction': function () {
+ return this._removeDirectLoginIndexDataFunction;
+ },
+
+ //=========================================================================
+
+ 'deleteAllCleanTextData': function () {
+// return Clipperz.PM.DataModel.Record.superclass.deleteAllCleanTextData.apply(this, arguments);
+
+ return Clipperz.Async.callbacks("Record.deleteAllCleanTextData", [
+ MochiKit.Base.method(this, 'versions'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('deleteAllCleanTextData')),
+
+ MochiKit.Base.method(this, 'directLogins'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('deleteAllCleanTextData')),
+
+ MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.deleteAllCleanTextData, this)
+ ], {trace:false});
+ },
+
+ 'hasAnyCleanTextData': function () {
+// return Clipperz.PM.DataModel.Record.superclass.hasAnyCleanTextData.apply(this, arguments);
+
+ return Clipperz.Async.callbacks("Record.hasAnyCleanTextData", [
+ Clipperz.Async.collectResults("Record.hasAnyCleanTextData [collect results]", {
+ 'versions': [
+ MochiKit.Base.method(this, 'versions'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasAnyCleanTextData')),
+ Clipperz.Async.collectAll
+ ],
+ 'directLogins': [
+ MochiKit.Base.method(this, 'directLogins'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasAnyCleanTextData')),
+ Clipperz.Async.collectAll
+ ],
+ 'super': [
+ MochiKit.Base.bind(Clipperz.PM.DataModel.Record.superclass.hasAnyCleanTextData, this)
+ ]
+ }, {trace:false}),
+ Clipperz.Async.or
+ ])
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.Legacy.js b/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.Legacy.js
new file mode 100644
index 0000000..e675525
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.Legacy.js
@@ -0,0 +1,187 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try { if (typeof(Clipperz.PM.DataModel.User) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.PM.DataModel.User.Header.Legacy depends on Clipperz.PM.DataModel.User!";
+}
+
+if (typeof(Clipperz.PM.DataModel.User.Header) == 'undefined') { Clipperz.PM.DataModel.User.Header = {}; }
+
+Clipperz.PM.DataModel.User.Header.Legacy = function(args) {
+// args = args || {};
+ Clipperz.PM.DataModel.User.Header.Legacy.superclass.constructor.apply(this, arguments);
+
+ this._retrieveRecordDetailFunction = args.retrieveRecordDetailFunction || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._records = null;
+// this._directLogins = null;
+
+ return this;
+}
+
+
+Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.Legacy, Clipperz.PM.DataModel.EncryptedRemoteObject, {
+
+ 'toString': function() {
+ return "Clipperz.PM.DataModel.User.Header.Legacy";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'retrieveRecordDetailFunction': function () {
+ return this._retrieveRecordDetailFunction;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getRecordKey': function (aRecordReference) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("User.Header.Legacy.getRecordKey", {trace:false});
+ deferredResult.addMethod(this, 'getRecordIndexData');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('key'))
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'getRecordIndexData': function (aRecordReference) {
+ return this.getValue('records.' + aRecordReference);
+ },
+
+ 'updateRecordIndexData': function (aRecordReference, aKey, aValue) {
+ return this.setValue('records.' + aRecordReference + "." + aKey, aValue);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getDirectLoginIndexData': function (aDirectLoginReference) {
+ return this.getValue('directLogins.' + aDirectLoginReference);
+ },
+
+ 'setDirectLoginIndexData': function (aDirectLoginReference, aKey, aValue) {
+ return this.setValue('directLogins.' + aDirectLoginReference + '.' + aKey, aValue);
+ },
+
+ 'removeDirectLoginIndexData': function (aDirectLoginReference) {
+ return this.removeValue('directLogins.' + aDirectLoginReference);
+ },
+
+ //=========================================================================
+
+ 'records': function () {
+ var deferredResult;
+ var deferredLock;
+
+ deferredLock = this.getDeferredLockForKey('records');
+
+ deferredResult = new Clipperz.Async.Deferred("User.Header.Legacy.records", {trace:false});
+ deferredResult.acquireLock(deferredLock);
+ deferredResult.addCallback(MochiKit.Base.bind(function () {
+ var innerDeferredResult;
+
+ if (this._records == null) {
+ innerDeferredResult = new Clipperz.Async.Deferred("User.Header.Legacy.records <inner deferred>", {trace:false});
+ innerDeferredResult.collectResults({
+ 'header': [
+// MochiKit.Base.method(this, 'getObjectDataStore'),
+// MochiKit.Base.methodcaller('values')
+ MochiKit.Base.method(this, 'values')
+ ],
+ 'recordsStats': [
+ MochiKit.Base.method(this, 'getRemoteData'),
+ MochiKit.Base.itemgetter('recordsStats')
+ ]
+ });
+ innerDeferredResult.addCallback(MochiKit.Base.bind(function (someObjectData) {
+ var reference;
+
+ this._records = {};
+// this._directLogins = {};
+
+ for (reference in someObjectData['header']['records']) {
+ var record;
+
+ record = new Clipperz.PM.DataModel.Record({
+ 'reference': reference,
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getRecordKey'),
+ 'retrieveRemoteDataFunction': this.retrieveRecordDetailFunction(),
+// 'encryptedDataKeypath': 'data',
+// 'encryptedVersionKeypath': 'version',
+
+ 'retrieveIndexDataFunction': MochiKit.Base.method(this, 'getRecordIndexData'),
+ 'updateIndexDataFunction': MochiKit.Base.method(this, 'updateRecordIndexData'),
+ 'updateDate': someObjectData['recordsStats'][reference]['updateDate'],
+
+ 'retrieveDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'getDirectLoginIndexData'),
+ 'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
+ 'removeDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'removeDirectLoginIndexData')
+ });
+
+ this._records[reference] = record;
+ }
+
+ for (reference in someObjectData['header']['directLogins']) {
+ var directLogin;
+ var record;
+
+ record = this._records[someObjectData['header']['directLogins'][reference]['record']];
+ if (record != null) {
+ directLogin = new Clipperz.PM.DataModel.DirectLogin({
+ 'reference': reference,
+ 'record': record //,
+// 'retrieveIndexDataFunction': MochiKit.Base.method(this, 'getDirectLoginIndexData'),
+// 'setIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
+// 'removeIndexDataFunction': MochiKit.Base.method(this, 'removeDirectLoginIndexData')
+ });
+ } else {
+Clipperz.log("WARNING: DIRECT LOGIN without a matching RECORD!!");
+ }
+ }
+
+ return this._records;
+ }, this));
+ innerDeferredResult.callback();
+ } else {
+ innerDeferredResult = MochiKit.Async.succeed(this._records);
+ }
+
+ return innerDeferredResult;
+ }, this));
+ deferredResult.releaseLock(deferredLock);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js b/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js
new file mode 100644
index 0000000..0ee8599
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js
@@ -0,0 +1,128 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try { if (typeof(Clipperz.PM.DataModel.User) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.PM.DataModel.User.Header.OneTimePasswords depends on Clipperz.PM.DataModel.User!";
+}
+if (typeof(Clipperz.PM.DataModel.User.Header) == 'undefined') { Clipperz.PM.DataModel.User.Header = {}; }
+
+//-----------------------------------------------------------------------------
+
+Clipperz.PM.DataModel.User.Header.OneTimePasswords = function(args) {
+ Clipperz.PM.DataModel.User.Header.OneTimePasswords.superclass.constructor.apply(this, arguments);
+
+ this._oneTimePasswords = null;
+
+ return this;
+}
+
+//-----------------------------------------------------------------------------
+
+Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.OneTimePasswords, Clipperz.PM.DataModel.EncryptedRemoteObject, {
+
+ 'toString': function() {
+ return "Clipperz.PM.DataModel.User.Header.OneTimePasswords";
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'packData': function (someData) { // ++
+ var result;
+
+console.log(">>> OneTimePasswords.packData", someData);
+ result = Clipperz.PM.DataModel.User.Header.OneTimePasswords.superclass.packData.apply(this, arguments);
+console.log("<<< OneTimePasswords.packData");
+
+ return result;
+ },
+*/
+ //-------------------------------------------------------------------------
+/*
+ 'packRemoteData': function (someData) {
+ var result;
+
+console.log(">>> OneTimePasswords.packRemoteData", someData);
+ result = Clipperz.PM.DataModel.User.Header.OneTimePasswords.superclass.packRemoteData.apply(this, arguments);
+console.log("<<< OneTimePasswords.packRemoteData");
+
+ return result;
+ },
+*/
+ //-------------------------------------------------------------------------
+/*
+ 'prepareRemoteDataWithKey': function (aKey) {
+ var result;
+
+console.log(">>> OneTimePasswords.prepareRemoteDataWithKey");
+ result = Clipperz.PM.DataModel.User.Header.OneTimePasswords.superclass.prepareRemoteDataWithKey.apply(this, arguments);
+console.log("<<< OneTimePasswords.prepareRemoteDataWithKey");
+
+ return result;
+ },
+*/
+ //=========================================================================
+
+ 'oneTimePasswords': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("User.Header.OneTimePasswords.oneTimePasswords", {trace:false});
+ if (this._oneTimePasswords == null) {
+ deferredResult.addMethod(this, 'values')
+ deferredResult.addCallback(MochiKit.Base.bind(function (someData) {
+ var otpKey;
+
+ this._oneTimePasswords = {};
+
+ for (otpKey in someData) {
+ var otp;
+ var otpParameters;
+
+ otpParameters = Clipperz.Base.deepClone(someData[otpKey]);
+ otpParameters['reference'] = otpKey;
+
+ otp = new Clipperz.PM.DataModel.OneTimePassword(otpParameters);
+ this._oneTimePasswords[otpKey] = otp;
+ }
+
+ return this._oneTimePasswords;
+
+ }, this));
+ deferredResult.callback();
+ } else {
+ deferredResult = MochiKit.Async.succeed(this._oneTimePasswords);
+ }
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+//-----------------------------------------------------------------------------
+
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.Preferences.js b/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.Preferences.js
new file mode 100644
index 0000000..91b981e
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.Preferences.js
@@ -0,0 +1,53 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try { if (typeof(Clipperz.PM.DataModel.User) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.PM.DataModel.User.Header.Preferences depends on Clipperz.PM.DataModel.User!";
+}
+
+if (typeof(Clipperz.PM.DataModel.User.Header) == 'undefined') { Clipperz.PM.DataModel.User.Header = {}; }
+
+Clipperz.PM.DataModel.User.Header.Preferences = function(args) {
+ Clipperz.PM.DataModel.User.Header.Preferences.superclass.constructor.apply(this, arguments);
+
+ return this;
+}
+
+
+Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.Preferences, Clipperz.PM.DataModel.EncryptedRemoteObject, {
+
+ 'toString': function() {
+ return "Clipperz.PM.DataModel.User.Header.Preferences";
+ },
+
+ //-------------------------------------------------------------------------
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js b/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js
new file mode 100644
index 0000000..6ba58a8
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/User.Header.RecordIndex.js
@@ -0,0 +1,705 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try { if (typeof(Clipperz.PM.DataModel.User) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.PM.DataModel.User.Header.RecordIndex depends on Clipperz.PM.DataModel.User!";
+}
+
+if (typeof(Clipperz.PM.DataModel.User.Header) == 'undefined') { Clipperz.PM.DataModel.User.Header = {}; }
+
+Clipperz.PM.DataModel.User.Header.RecordIndex = function(args) {
+ Clipperz.PM.DataModel.User.Header.RecordIndex.superclass.constructor.apply(this, arguments);
+
+//console.log("NEW Clipperz.PM.DataModel.User.Header.RecordIndex", args);
+ this._recordsData = new Clipperz.PM.DataModel.EncryptedRemoteObject({
+ 'name': 'recordsData',
+ 'retrieveKeyFunction': args.retrieveKeyFunction,
+ 'remoteData': {
+ 'data': args.recordsData['data'],
+ 'version': args.encryptedDataVersion,
+ 'recordsStats': args.recordsStats
+ }//,
+// 'encryptedDataKeypath': 'data',
+// 'encryptedVersionKeypath': 'version'
+ });
+
+ this._directLoginsData = new Clipperz.PM.DataModel.EncryptedRemoteObject({
+ 'name': 'directLoginsData',
+ 'retrieveKeyFunction': args.retrieveKeyFunction,
+ 'remoteData': {
+ 'data': args.directLoginsData['data'],
+ 'version': args.encryptedDataVersion
+ }//,
+// 'encryptedDataKeypath': 'data',
+// 'encryptedVersionKeypath': 'version'
+ });
+
+ this._lock = new MochiKit.Async.DeferredLock();
+ this._transientState = null;
+
+ this._retrieveRecordDetailFunction = args.retrieveRecordDetailFunction || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._recordsIndex = args.recordsData['index'] || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._directLoginsIndex = args.directLoginsData['index'] || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ this._records = null;
+
+ return this;
+}
+
+
+Clipperz.Base.extend(Clipperz.PM.DataModel.User.Header.RecordIndex, Object, {
+
+ 'toString': function() {
+ return "Clipperz.PM.DataModel.User.Header.RecordIndex";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'retrieveRecordDetailFunction': function () {
+ return this._retrieveRecordDetailFunction;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'recordsIndex': function () {
+ return this._recordsIndex;
+ },
+
+ 'recordsData': function () {
+ return this._recordsData;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'directLoginsIndex': function () {
+ return this._directLoginsIndex;
+ },
+
+ 'directLoginsData': function () {
+ return this._directLoginsData;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'lock': function () {
+ return this._lock;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'transientState': function () {
+ if (this._transientState == null) {
+ this._transientState = new Clipperz.KeyValueObjectStore(/*{'name':'User.Header.RecordIndex.transientState [1]'}*/);
+ }
+
+ return this._transientState;
+ },
+
+ 'resetTransientState': function (isCommitting) {
+//console.log("######## UserHeaderRecordIndex - resetTransientState", Clipperz.Base.deepClone(this._transientState));
+ if (this._transientState != null) {
+ this._transientState.removeAllData();
+ }
+
+ this._transientState = null;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getRecordKey': function (aRecordReference) {
+ return Clipperz.Async.callbacks("User.Header.RecordIndex.getRecordKey", [
+ MochiKit.Base.method(this, 'getRecordIndexData', aRecordReference),
+ MochiKit.Base.itemgetter('key')
+ ], {trace:false});
+ },
+
+ 'setRecordKey': function (aRecordReference, aValue) {
+ return this.updateRecordIndexData(aRecordReference, 'key', aValue);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getRecordIndexData': function (aRecordReference) {
+ return this.recordsData().getValue(this.recordsIndex()[aRecordReference]);
+ },
+
+ //.........................................................................
+
+ 'updateRecordIndexData': function (aRecordReference, aKey, aValue) {
+ return this.recordsData().setValue(this.recordsIndex()[aRecordReference]+'.'+aKey, aValue);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getDirectLoginIndexData': function (aDirectLoginReference) {
+ return this.directLoginsData().getValue(this.directLoginsIndex()[aDirectLoginReference]);
+ },
+
+ 'setDirectLoginIndexData': function (aDirectLoginReference, aKey, aValue) {
+//console.log("UserHeaderRecordIndex.setDirectLoginIndexData", aDirectLoginReference, this.directLoginsIndex()[aDirectLoginReference], aKey);
+//if (MochiKit.Base.isUndefinedOrNull(this.directLoginsIndex()[aDirectLoginReference])) {
+// throw "PIPPO";
+//}
+ return this.directLoginsData().setValue(this.directLoginsIndex()[aDirectLoginReference] + '.' + aKey, aValue);
+ },
+
+ 'addDirectLoginIndexData': function (aDirectLoginReference) {
+//console.log("UserHeaderRecordIndex.addDirectLoginIndexData", aDirectLoginReference, this.directLoginsIndex()[aDirectLoginReference]);
+ return this.directLoginsData().setValue(this.directLoginsIndex()[aDirectLoginReference], {});
+ },
+
+ 'removeDirectLoginIndexData': function (aDirectLoginReference) {
+ return this.directLoginsData().removeValue(this.directLoginsIndex()[aDirectLoginReference])
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'records': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.records", {trace:false});
+ deferredResult.acquireLock(this.lock());
+ deferredResult.addCallback(MochiKit.Base.bind(function () {
+ var innerDeferredResult;
+
+ if (this._records == null) {
+ innerDeferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.records <inner deferred>", {trace:false});
+ innerDeferredResult.collectResults({
+ 'records': [
+// MochiKit.Base.method(this.recordsData(), 'getObjectDataStore'),
+// MochiKit.Base.methodcaller('values')
+ MochiKit.Base.method(this.recordsData(), 'values')
+ ],
+ 'recordsStats': [
+ MochiKit.Base.method(this.recordsData(), 'getRemoteData'),
+ MochiKit.Base.itemgetter('recordsStats')
+ ],
+ 'directLogins': [
+// MochiKit.Base.method(this.directLoginsData(), 'getObjectDataStore'),
+// MochiKit.Base.methodcaller('values')
+ MochiKit.Base.method(this.directLoginsData(), 'values')
+ ]
+ })
+ innerDeferredResult.addCallback(MochiKit.Base.bind(function (someData) {
+ var indexReference;
+ var recordsInvertedIndex;
+ var directLoginsInvertedIndex;
+
+ recordsInvertedIndex = Clipperz.PM.DataModel.User.Header.RecordIndex.invertIndex(this.recordsIndex());
+ directLoginsInvertedIndex = Clipperz.PM.DataModel.User.Header.RecordIndex.invertIndex(this.directLoginsIndex());
+
+ this._records = {};
+
+ for (indexReference in someData['records']) {
+ var record;
+ var reference;
+ var updateDate;
+
+ reference = recordsInvertedIndex[indexReference];
+
+ if (typeof(someData['recordsStats'][reference]) != 'undefined') {
+ updateDate = someData['recordsStats'][reference]['updateDate'];
+
+ record = new Clipperz.PM.DataModel.Record({
+ 'reference': reference,
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getRecordKey'),
+ 'retrieveRemoteDataFunction': this.retrieveRecordDetailFunction(),
+
+ 'retrieveIndexDataFunction': MochiKit.Base.method(this, 'getRecordIndexData'),
+ 'updateIndexDataFunction': MochiKit.Base.method(this, 'updateRecordIndexData'),
+ 'updateDate': updateDate,
+
+ 'retrieveDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'getDirectLoginIndexData'),
+ 'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
+ 'removeDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'removeDirectLoginIndexData'),
+
+ 'createNewDirectLoginFunction': MochiKit.Base.method(this, 'createNewDirectLogin')
+ });
+
+ this._records[reference] = record;
+ } else {
+Clipperz.log("SKIPPING record " + reference + " as there are no stas associated - " + Clipperz.Base.serializeJSON(someData['records'][reference]));
+ // # skip the record, as it seems it is not present in the DB
+ // updateDate = Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
+ }
+ }
+
+ for (indexReference in someData['directLogins']) {
+// var directLogin;
+ var reference;
+ var record;
+
+ reference = directLoginsInvertedIndex[indexReference];
+ record = this._records[recordsInvertedIndex[someData['directLogins'][indexReference]['record']]];
+
+ if (record != null) {
+// directLogin = new Clipperz.PM.DataModel.DirectLogin({
+ new Clipperz.PM.DataModel.DirectLogin({
+ 'reference': reference,
+ 'record': record
+ });
+ } else {
+Clipperz.log("WARNING: DIRECT LOGIN without a matching RECORD!!");
+//console.log("direct login data", someData['directLogins']);
+//console.log("current direct login data", someData['directLogins'][indexReference])
+//console.log("reference", reference);
+//console.log("record index", this.recordsIndex());
+//console.log("record inverted index", recordsInvertedIndex);
+ }
+ }
+
+ return this._records;
+ }, this));
+ innerDeferredResult.callback();
+ } else {
+ innerDeferredResult = MochiKit.Async.succeed(this._records);
+ }
+
+ return innerDeferredResult;
+ }, this));
+ deferredResult.releaseLock(this.lock());
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateRecordIndexForNewRecord': function (aNewRecord) {
+ var newRecordIndex;
+ var recordReference;
+
+ recordReference = aNewRecord.reference();
+ newRecordIndex = (MochiKit.Base.listMax(MochiKit.Base.map(MochiKit.Base.partial(MochiKit.Base.operator.mul, 1), MochiKit.Base.values(this.recordsIndex()))) + 1) + '';
+ this.recordsIndex()[recordReference] = newRecordIndex;
+
+ this.transientState().setValue('newlyCreatedRecordsIndex' + '.' + recordReference, newRecordIndex);
+ this.transientState().setValue('newlyCreatedRecordsReferences' + '.' + recordReference, aNewRecord);
+ },
+
+ //.........................................................................
+
+ 'createNewRecord': function () {
+ var deferredResult;
+ var newRecord;
+
+//console.log("#### new Clipperz.PM.DataModel.Record [4]");
+ newRecord = new Clipperz.PM.DataModel.Record({
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getRecordKey'),
+ 'retrieveRemoteDataFunction': this.retrieveRecordDetailFunction(),
+
+ 'retrieveIndexDataFunction': MochiKit.Base.method(this, 'getRecordIndexData'),
+ 'updateIndexDataFunction': MochiKit.Base.method(this, 'updateRecordIndexData'),
+ 'updateDate': Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
+
+ 'retrieveDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'getDirectLoginIndexData'),
+ 'setDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'setDirectLoginIndexData'),
+ 'removeDirectLoginIndexDataFunction': MochiKit.Base.method(this, 'removeDirectLoginIndexData'),
+
+ 'createNewDirectLoginFunction': MochiKit.Base.method(this, 'createNewDirectLogin')
+ });
+
+ this.transientState().setValue('newRecordsReferences' + '.' + newRecord.reference(), newRecord);
+ this.updateRecordIndexForNewRecord(newRecord);
+
+ deferredResult = Clipperz.Async.callbacks("User.Header.RecordIndex.createNewRecord", [
+ MochiKit.Base.method(this, 'records'),
+ MochiKit.Base.partial(Clipperz.Async.setItemOnObject, newRecord.reference(), newRecord),
+ MochiKit.Base.method(this, 'setRecordKey', newRecord.reference(), Clipperz.PM.Crypto.randomKey()),
+ MochiKit.Base.method(newRecord, 'setLabel', ''),
+ MochiKit.Base.partial(MochiKit.Async.succeed, newRecord)
+ ], {trace:false});
+
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deleteRecord': function (aRecord) {
+ var deferredResult;
+ var recordReference;
+
+ recordReference = aRecord.reference();
+
+ deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.deleteRecord", {trace:false});
+
+ deferredResult.addMethod(aRecord, 'directLogins');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'removeDirectLogin'));
+
+ deferredResult.addMethod(this.recordsData(), 'removeValue', this.recordsIndex()[recordReference]);
+ deferredResult.addCallback(MochiKit.Base.bind(function () {
+ this.transientState().setValue('deleteRecordsIndex' + '.' + recordReference, this.recordsIndex()[recordReference]);
+ delete this.recordsIndex()[recordReference];
+ }, this));
+
+ deferredResult.addMethod(this, 'records');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(recordReference));
+ deferredResult.addMethod(this.transientState(), 'setValue', 'deleteRecordsReferences' + '.' + recordReference);
+
+ deferredResult.addMethod(this, 'records');
+ deferredResult.addCallback(MochiKit.Base.bind(function (someRecords) {
+ delete someRecords[recordReference];
+ }, this));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'removeDirectLogin': function (aDirectLogin) {
+ this.directLoginsData().removeValue(this.directLoginsIndex()[aDirectLogin.reference()]);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'createNewDirectLogin': function (aRecord) {
+ var newDirectLogin;
+ var newDirectLoginIndexValue;
+
+ newDirectLogin = new Clipperz.PM.DataModel.DirectLogin({record:aRecord});
+ newDirectLoginIndexValue = MochiKit.Base.listMax(MochiKit.Base.map(function (aValue) { return aValue * 1; }, MochiKit.Base.values(this.directLoginsIndex()))) + 1;
+
+ this.transientState().setValue('newDirectLoginReferences' + '.' + newDirectLogin.reference(), newDirectLogin);
+
+//console.log("UserHeaderRecordIndex.createNewDirectLogin [1]", newDirectLogin.reference(), newDirectLoginIndexValue);
+ this.directLoginsIndex()[newDirectLogin.reference()] = newDirectLoginIndexValue;
+//console.log("UserHeaderRecordIndex.createNewDirectLogin [2]", newDirectLogin.reference(), this.directLoginsIndex()[newDirectLogin.reference()]);
+ this.directLoginsData().setValue(this.directLoginsIndex()[newDirectLogin.reference()], {'record': this.recordsIndex()[aRecord.reference()]});
+
+ return newDirectLogin;
+ },
+
+ //=========================================================================
+
+ 'deleteAllCleanTextData': function () {
+ return Clipperz.Async.callbacks("User.Header.RecordIndex.deleteAllCleanTextData", [
+// MochiKit.Base.method(this, 'records'),
+// MochiKit.Base.values,
+// MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('deleteAllCleanTextData')),
+
+ MochiKit.Base.method(this, 'recordsData'),
+ MochiKit.Base.methodcaller('deleteAllCleanTextData'),
+ MochiKit.Base.method(this, 'directLoginsData'),
+ MochiKit.Base.methodcaller('deleteAllCleanTextData')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hasAnyCleanTextData': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred({trace:false});
+ deferredResult.collectResults({
+ 'recordsData': [
+ MochiKit.Base.method(this, 'recordsData'),
+ MochiKit.Base.methodcaller('hasAnyCleanTextData')
+ ],
+ 'directLoginsData': [
+ MochiKit.Base.method(this, 'directLoginsData'),
+ MochiKit.Base.methodcaller('hasAnyCleanTextData')
+ ],
+// 'records': [
+// MochiKit.Base.method(this, 'records'),
+// MochiKit.Base.values,
+// MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller('hasAnyCleanTextData')),
+// Clipperz.Async.collectAll
+// ]
+ });
+//deferredResult.addCallback(function (aValue) { console.log("USER.Header.RecordIndex.hasAnyCleanTextData", aValue); return aValue});
+
+// deferredResult.addCallback(MochiKit.Base.values);
+// deferredResult.addCallback(MochiKit.Base.flattenArguments);
+// deferredResult.addCallback(function(someValues) {
+// return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
+// });
+ deferredResult.addCallback(Clipperz.Async.or);
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hasPendingChanges': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.hasPendingChanges", {trace:false});
+ deferredResult.collectResults({
+ 'recordsData': [
+ MochiKit.Base.method(this, 'recordsData'),
+ MochiKit.Base.methodcaller('hasPendingChanges')
+ ],
+ 'directLoginsData': [
+ MochiKit.Base.method(this, 'directLoginsData'),
+ MochiKit.Base.methodcaller('hasPendingChanges')
+ ]
+ });
+//deferredResult.addCallback(function (aValue) { console.log("UserHeaderIndex.hasPendingResults", aValue); return aValue; });
+ deferredResult.addCallback(Clipperz.Async.or);
+// deferredResult.addCallback(MochiKit.Base.values);
+// deferredResult.addCallback(MochiKit.Base.flattenArguments);
+// deferredResult.addCallback(function(someValues) {
+// return MochiKit.Iter.some(someValues, MochiKit.Base.operator.identity);
+// });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'commitTransientState': function () {
+ var deferredResult;
+
+ deferredResut = Clipperz.Async.callbacks("User.Header.RecordIndex.commitTransientState", [
+ MochiKit.Base.method(this, 'recordsData'),
+ MochiKit.Base.methodcaller('commitTransientState'),
+
+ MochiKit.Base.method(this, 'directLoginsData'),
+ MochiKit.Base.methodcaller('commitTransientState'),
+
+ MochiKit.Base.method(this, 'resetTransientState', true)
+ ], {trace:false});
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'revertChanges': function () {
+ return Clipperz.Async.callbacks("User.Header.RecordIndex.revertChanges", [
+ MochiKit.Base.method(this, 'recordsData'),
+ MochiKit.Base.methodcaller('revertChanges'),
+
+// MochiKit.Base.method(this, 'directLoginsData'),
+// MochiKit.Base.methodcaller('revertChanges'),
+
+ MochiKit.Base.method(this, 'records'),
+ MochiKit.Base.bind(function (someRecords) {
+ var recordReference;
+
+ for (recordReference in this.transientState().getValue('deleteRecordsReferences')) {
+ this.recordsIndex()[recordReference] = this.transientState().getValue('deleteRecordsIndex' + '.' + recordReference);
+ someRecords[recordReference] = this.transientState().getValue('deleteRecordsReferences' + '.' + recordReference);
+ }
+
+ for (recordReference in this.transientState().getValue('newRecordsReferences')) {
+ delete this.recordsIndex()[recordReference];
+ delete someRecords[recordReference];
+ }
+ }, this),
+
+// MochiKit.Base.method(this, 'directLogins'),
+ MochiKit.Base.bind(function () {
+ var directLoginReference;
+
+// this.transientState().setValue('newDirectLoginReferences' + '.' + newDirectLogin.reference(), newDirectLogin);
+//
+// this.directLoginsIndex()[newDirectLogin.reference()] = newDirectLoginIndexValue;
+// this.directLoginsData().setValue(this.directLoginsIndex()[newDirectLogin.reference()], {'record': this.recordsIndex()[aRecord.reference()]});
+
+
+// for (directLoginReference in this.transientState().getValue('deleteDirectLoginReferences')) {
+// someDirectLogins[directLoginReference] = this.transientState().getValue('deleteDirectLoginReferences' + '.' + recordReference);
+// }
+
+ for (directLoginReference in this.transientState().getValue('newDirectLoginReferences')) {
+// this.directLoginsData().removeValue(this.directLoginsIndex()[directLoginReference]);
+ delete this.directLoginsIndex()[directLoginReference];
+ }
+ }, this),
+
+ MochiKit.Base.method(this, 'directLoginsData'),
+ MochiKit.Base.methodcaller('revertChanges'),
+
+ MochiKit.Base.method(this, 'resetTransientState', false)
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'prepareRemoteDataWithKey': function (aKey) {
+// "records": {
+// "index": {
+// "eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5": "0",
+// "13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551": "1",
+// ...
+// "465a067a0bd2b470fa834de5397e38494de0c7707938262fae3427932e219744": "18",
+// "4fd1dc2ca860b7fb47cef10a84edb3270da05510b0a30a6b0b083898712d4b9e": "19"
+// },
+// "data": "n+AzGEEQXaSRSY4d ... BDypotrXgPo94uHfoXvGFzwCn8w="
+// },
+// "directLogins": {
+// "index": {
+// "61e87fdc4f1d9112e3b30c1f6812d095dcdb24f014c83319091eb6c9899ec348":"0",
+// "989593d4c48929f0c8f1581aa96969c622807e99619ed4732026e967530a68ad":"1",
+// ...
+// "cb9ae0bba1957075ccdbfd3b3481704d62087687a2ac7c411a4f07d444bde0f7":"17",
+// "7e1d069b7fa57c03bd7bf48807520feb953157834503aaff8c9d493f37dea69d":"18"
+// },
+// "data":"5YG9KKU/OZ5guUgFlms6k1 ... ZG/5Fn0uN+LoAsNfHm+EE62x"
+// },
+
+ var deferredResult;
+ var result;
+
+//console.log("recordsIndex", this.recordsIndex());
+ result = {};
+
+ deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.prepareRemoteDataWithKey", {trace:false});
+ deferredResult.collectResults({
+ 'index': MochiKit.Base.partial(MochiKit.Async.succeed, this.recordsIndex()),
+ 'data': [
+ MochiKit.Base.method(this.recordsData(), 'prepareRemoteDataWithKey', aKey),
+ MochiKit.Base.itemgetter('data')
+ ]
+ });
+ deferredResult.addCallback(Clipperz.Async.setItem, result, 'records');
+
+ deferredResult.collectResults({
+ 'index': MochiKit.Base.partial(MochiKit.Async.succeed, this.directLoginsIndex()),
+ 'data': [
+ MochiKit.Base.method(this.directLoginsData(), 'prepareRemoteDataWithKey', aKey),
+ MochiKit.Base.itemgetter('data')
+ ]
+ });
+ deferredResult.addCallback(Clipperz.Async.setItem, result, 'directLogins');
+
+ deferredResult.addCallback(MochiKit.Async.succeed, result);
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateRecordKeyAndPrepareRemoteData': function (aRecord) {
+ var newRecordKey;
+ var deferredResult;
+
+ newRecordKey = Clipperz.PM.Crypto.randomKey();
+
+ deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.updateRecordKeyAndPrepareRemoteData", {trace:false});
+ deferredResult.addCallback(MochiKit.Base.method(aRecord, 'prepareRemoteDataWithKey', newRecordKey));
+ deferredResult.addCallbackPass(MochiKit.Base.method(this, 'setRecordKey', aRecord.reference(), newRecordKey));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //.........................................................................
+
+ 'removeNewRecordWithNoChanges': function (aRecord) {
+ var deferredResult;
+ var recordReference;
+
+ recordReference = aRecord.reference();
+
+ deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.removeNewRecordWithNoChanges", {trace:false});
+
+ deferredResult.addMethod(this.recordsData(), 'removeValue', this.recordsIndex()[recordReference]);
+ deferredResult.addCallback(MochiKit.Base.bind(function () {
+ delete this.recordsIndex()[recordReference];
+ }, this));
+
+ deferredResult.addMethod(this, 'records');
+ deferredResult.addCallback(MochiKit.Base.bind(function (someRecords) {
+ delete someRecords[recordReference];
+ }, this));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //.........................................................................
+
+ 'prepareRemoteDataForChangedRecords': function () {
+ var deferredResult;
+ var result;
+
+ result = {};
+
+ deferredResult = new Clipperz.Async.Deferred("User.Header.RecordIndex.prepareRemoteDataForChangedRecords", {trace:false});
+
+ deferredResult.addMethod(this, 'records');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(Clipperz.Async.deferredFilter, MochiKit.Base.methodcaller('isBrandNewWithNoPendingChanges'));
+ deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'removeNewRecordWithNoChanges'));
+
+ deferredResult.addMethod(this, 'records');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(Clipperz.Async.deferredFilter, MochiKit.Base.methodcaller('hasPendingChanges'));
+ deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.method(this, 'updateRecordKeyAndPrepareRemoteData'));
+ deferredResult.addCallback(Clipperz.Async.collectAll);
+
+ deferredResult.addCallback(Clipperz.Async.deferredIf("updated records != null", [
+ MochiKit.Base.operator.identity
+ ], [
+ MochiKit.Base.partial(MochiKit.Async.succeed, [])
+ ]));
+ deferredResult.addCallback(Clipperz.Async.setItem, result, 'updated');
+
+ deferredResult.addMethod(this.transientState(), 'getValue', 'deleteRecordsReferences');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(Clipperz.Async.deferredIf("deleted records != null", [
+ MochiKit.Base.operator.identity
+ ], [
+ MochiKit.Base.partial(MochiKit.Async.succeed, [])
+ ]));
+ deferredResult.addCallback(Clipperz.Async.setItem, result, 'deleted');
+
+ deferredResult.addCallback(MochiKit.Async.succeed, result);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+
+
+Clipperz.PM.DataModel.User.Header.RecordIndex.invertIndex = function (anIndex) {
+ var result;
+ var key;
+
+ result = {};
+
+ for (key in anIndex) {
+ result[anIndex[key]] = key;
+ }
+
+ return result;
+}; \ No newline at end of file
diff --git a/frontend/gamma/js/Clipperz/PM/DataModel/User.js b/frontend/gamma/js/Clipperz/PM/DataModel/User.js
new file mode 100644
index 0000000..e8afa97
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/DataModel/User.js
@@ -0,0 +1,817 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+if (typeof(Clipperz.PM.DataModel) == 'undefined') { Clipperz.PM.DataModel = {}; }
+
+
+//#############################################################################
+
+Clipperz.PM.DataModel.User = function (args) {
+ args = args || {};
+
+ Clipperz.PM.DataModel.User.superclass.constructor.apply(this, arguments);
+
+ this._username = args.username || null;
+ this._getPassphraseFunction = args.getPassphraseFunction || null;
+
+ this._data = null;
+
+ this._connection = null;
+ this._connectionVersion = 'current';
+
+ this._serverData = null;
+ this._serverLockValue = null;
+ this._transientState = null;
+
+ this._deferredLocks = {
+ 'passphrase': new MochiKit.Async.DeferredLock(),
+ 'serverData': new MochiKit.Async.DeferredLock(),
+// 'recordsIndex': new MochiKit.Async.DeferredLock(),
+// 'directLoginsIndex': new MochiKit.Async.DeferredLock()
+// 'preferences': new MochiKit.Async.DeferredLock()
+// 'oneTimePasswords': new MochiKit.Async.DeferredLock()
+ '__syntaxFix__': 'syntax fix'
+ };
+
+ return this;
+}
+
+Clipperz.Base.extend(Clipperz.PM.DataModel.User, Object, {
+
+ 'toString': function () {
+ return "Clipperz.PM.DataModel.User - " + this.username();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'username': function () {
+ return this._username;
+ },
+
+ 'setUsername': function (aValue) {
+ this._username = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'displayName': function() {
+ return "" + this.username() + "";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'data': function () {
+ if (this._data == null) {
+ this._data = new Clipperz.KeyValueObjectStore(/*{'name':'User.data [1]'}*/);
+ };
+
+ return this._data;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'serverLockValue': function () {
+ return this._serverLockValue;
+ },
+
+ 'setServerLockValue': function (aValue) {
+ this._serverLockValue = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'transientState': function () {
+ if (this._transientState == null) {
+ this._transientState = {}
+ }
+
+ return this._transientState;
+ },
+
+ 'resetTransientState': function (isCommitting) {
+ this._transientState = null;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredLockForSection': function(aSectionName) {
+ return this._deferredLocks[aSectionName];
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getPassphrase': function() {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("User.getPassphrase", {trace:false});
+ deferredResult.acquireLock(this.deferredLockForSection('passphrase'));
+ deferredResult.addMethod(this.data(), 'deferredGetOrSet', 'passphrase', this.getPassphraseFunction());
+ deferredResult.releaseLock(this.deferredLockForSection('passphrase'));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ 'getPassphraseFunction': function () {
+ return this._getPassphraseFunction;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getCredentials': function () {
+ return Clipperz.Async.collectResults("User; get username and passphrase", {
+ 'username': MochiKit.Base.method(this, 'username'),
+ 'password': MochiKit.Base.method(this, 'getPassphrase')
+ }, {trace:false})();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'changePassphrase': function (aNewValue) {
+ return this.updateCredentials(this.username(), aNewValue);
+ },
+
+ //.........................................................................
+
+ 'updateCredentials': function (aUsername, aPassphrase) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("User.updateCredentials", {trace:false});
+// deferredResult.addMethod(this, 'getPassphrase');
+// deferredResult.setValue('currentPassphrase');
+ deferredResult.addMethod(this.connection(), 'ping');
+ deferredResult.addMethod(this, 'setUsername', aUsername)
+ deferredResult.acquireLock(this.deferredLockForSection('passphrase'));
+ deferredResult.addMethod(this.data(), 'deferredGetOrSet', 'passphrase', aPassphrase);
+ deferredResult.releaseLock(this.deferredLockForSection('passphrase'));
+// deferredResult.getValue('currentPassphrase');
+ deferredResult.addMethod(this, 'prepareRemoteDataWithKey', aPassphrase);
+ deferredResult.addMethod(this.connection(), 'updateCredentials', aUsername, aPassphrase);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'initialSetupWithNoData': function () {
+ this._serverData = {
+ 'version': '0.1',
+ 'statistics': "",
+ 'header': {
+ 'data': null,
+ 'version': Clipperz.PM.Crypto.encryptingFunctions.currentVersion,
+
+ 'recordsIndex': new Clipperz.PM.DataModel.User.Header.RecordIndex({
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
+ 'recordsData': {'data':null, 'index':{}},
+ 'recordsStats': null,
+ 'directLoginsData': {'data':null, 'index':{}},
+ 'encryptedDataVersion': Clipperz.PM.Crypto.encryptingFunctions.currentVersion,
+ 'retrieveRecordDetailFunction': MochiKit.Base.method(this, 'getRecordDetail')
+ }),
+ 'preferences': new Clipperz.PM.DataModel.User.Header.Preferences({
+ 'name': 'preferences',
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
+ }),
+ 'oneTimePasswords': new Clipperz.PM.DataModel.User.Header.OneTimePasswords({
+ 'name': 'preferences',
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
+ })
+ }
+ };
+
+// this._serverLockValue = Clipperz.PM.Crypto.randomKey();
+ },
+
+ //.........................................................................
+
+ 'registerAsNewAccount': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("User.registerAsNewAccount", {trace:false});
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3});
+ deferredResult.addMethod(this, 'initialSetupWithNoData')
+ deferredResult.addMethod(this, 'getPassphrase');
+ deferredResult.addMethod(this, 'prepareRemoteDataWithKey');
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ deferredResult.addMethod(this.connection(), 'register');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('lock'));
+ deferredResult.addMethod(this, 'setServerLockValue');
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userSuccessfullyRegistered');
+
+// deferredResult.addErrback (MochiKit.Base.method(this, 'handleRegistrationFailure'));
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'login': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("User.login", {trace:false});
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':3});
+ deferredResult.addMethod(this, 'getPassphrase');
+ deferredResult.addCallback(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue);
+ deferredResult.addCallback(Clipperz.Async.deferredIf("Is the passphrase an OTP", [
+ MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'updateProgress', {'extraSteps':1}),
+ MochiKit.Base.method(this, 'getCredentials'),
+ MochiKit.Base.method(this.connection(), 'redeemOneTimePassword'),
+ MochiKit.Base.method(this.data(), 'setValue', 'passphrase')
+ ], []));
+ deferredResult.addErrback(MochiKit.Base.method(this, 'getPassphrase'));
+ deferredResult.addMethod(this.connection(), 'login');
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userSuccessfullyLoggedIn');
+ deferredResult.addErrback (MochiKit.Base.method(this, 'handleConnectionFallback'));
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //.........................................................................
+
+ 'handleConnectionFallback': function(aValue) {
+ var result;
+
+ if (aValue instanceof MochiKit.Async.CancelledError) {
+ result = aValue;
+ } else {
+ this.setConnectionVersion(Clipperz.PM.Connection.communicationProtocol.fallbackVersions[this.connectionVersion()]);
+
+ if (this.connectionVersion() != null) {
+ result = new Clipperz.Async.Deferred("User.handleConnectionFallback - retry");
+
+ result.addMethod(this, 'login');
+ result.callback();
+ } else {
+ result = Clipperz.Async.callbacks("User.handleConnectionFallback - failed", [
+ MochiKit.Base.method(this.data(), 'removeValue', 'passphrase'),
+ MochiKit.Base.method(this, 'setConnectionVersion', 'current'),
+ MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userLoginFailed'),
+ MochiKit.Base.partial(MochiKit.Async.fail, Clipperz.PM.DataModel.User.exception.LoginFailed)
+ ], {trace:false});
+ }
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'lock': function () {
+ return Clipperz.Async.callbacks("User.lock", [
+ MochiKit.Base.method(this, 'deleteAllCleanTextData')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'logout': function () {
+ return Clipperz.Async.callbacks("User.logout", [
+ MochiKit.Base.method(this, 'deleteAllCleanTextData'),
+ MochiKit.Base.method(this.connection(), 'logout')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'headerFormatVersion': function(anHeader) {
+ var result;
+
+ if (anHeader.charAt(0) == '{') {
+ var headerData;
+
+ headerData = Clipperz.Base.evalJSON(anHeader);
+ result = headerData['version'];
+ } else {
+ result = 'LEGACY';
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'unpackServerData': function (someServerData) {
+ var unpackedData;
+ var headerVersion;
+
+ var recordsIndex;
+ var preferences;
+ var oneTimePasswords;
+
+//console.log(">>> ***************** user.unpackServerData", someServerData);
+ this.setServerLockValue(someServerData['lock']);
+
+ headerVersion = this.headerFormatVersion(someServerData['header']);
+
+ switch (headerVersion) {
+ case 'LEGACY':
+ var legacyHeader;
+
+ legacyHeader = new Clipperz.PM.DataModel.User.Header.Legacy({
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
+ 'remoteData': {
+ 'data': someServerData['header'],
+ 'version': someServerData['version'],
+ 'recordsStats': someServerData['recordsStats']
+ },
+// 'encryptedDataKeypath': 'data',
+// 'encryptedVersionKeypath': 'version',
+ 'retrieveRecordDetailFunction': MochiKit.Base.method(this, 'getRecordDetail')
+ });
+
+ recordsIndex = legacyHeader;
+ preferences = legacyHeader;
+ oneTimePasswords = legacyHeader;
+ break;
+ case '0.1':
+ var headerData;
+
+ headerData = Clipperz.Base.evalJSON(someServerData['header']);
+
+ recordsIndex = new Clipperz.PM.DataModel.User.Header.RecordIndex({
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
+ 'recordsData': headerData['records'],
+ 'recordsStats': someServerData['recordsStats'],
+ 'directLoginsData': headerData['directLogins'],
+ 'encryptedDataVersion': someServerData['version'],
+ 'retrieveRecordDetailFunction': MochiKit.Base.method(this, 'getRecordDetail')
+ });
+
+ // Still missing a test case that actually fais with the old version of the code, where the check for undefined was missing
+ if (typeof(headerData['preferences']) != 'undefined') {
+ preferences = new Clipperz.PM.DataModel.User.Header.Preferences({
+ 'name': 'preferences',
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
+ 'remoteData': {
+ 'data': headerData['preferences']['data'],
+ 'version': someServerData['version']
+ }
+ });
+ } else {
+ preferences = new Clipperz.PM.DataModel.User.Header.Preferences({
+ 'name': 'preferences',
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
+ });
+ }
+
+ if (typeof(headerData['oneTimePasswords']) != 'undefined') {
+ oneTimePasswords = new Clipperz.PM.DataModel.User.Header.OneTimePasswords({
+ 'name': 'preferences',
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase'),
+ 'remoteData': {
+ 'data': headerData['oneTimePasswords']['data'],
+ 'version': someServerData['version']
+ }
+ });
+ } else {
+ oneTimePasswords = new Clipperz.PM.DataModel.User.Header.OneTimePasswords({
+ 'name': 'preferences',
+ 'retrieveKeyFunction': MochiKit.Base.method(this, 'getPassphrase')
+ });
+ }
+
+ break;
+ }
+
+ unpackedData = {
+ 'version': someServerData['version'],
+ 'statistics': someServerData['statistics'],
+ 'header': {
+ 'data': someServerData['header'],
+ 'version': headerVersion,
+
+ 'recordsIndex': recordsIndex,
+ 'preferences': preferences,
+ 'oneTimePasswords': oneTimePasswords
+ }
+ };
+
+ this._serverData = unpackedData;
+//console.log("<<< ***************** user.unpackServerData", this._serverData);
+
+ return this._serverData;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getServerData': function() {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("User.getServerData", {trace:false});
+ deferredResult.acquireLock(this.deferredLockForSection('serverData'));
+ deferredResult.addCallback(MochiKit.Base.bind(function(aResult) {
+ var innerDeferredResult;
+
+ innerDeferredResult = new Clipperz.Async.Deferred("User.getUserDetails.innerDeferred", {trace:false});
+ if (this._serverData == null) {
+ innerDeferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'loadingUserDetails');
+ innerDeferredResult.addMethod(this.connection(), 'message', 'getUserDetails');
+ innerDeferredResult.addMethod(this, 'unpackServerData');
+ innerDeferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'loadedUserDetails');
+ }
+
+ innerDeferredResult.addCallback(MochiKit.Base.bind(function () {
+ return this._serverData;
+ },this));
+ innerDeferredResult.callback();
+
+ return innerDeferredResult;
+ }, this));
+ deferredResult.releaseLock(this.deferredLockForSection('serverData'));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'connectionVersion': function() {
+ return this._connectionVersion;
+ },
+
+ 'setConnectionVersion': function(aValue) {
+ if (this._connectionVersion != aValue) {
+ this.resetConnection();
+ }
+ this._connectionVersion = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'connection': function() {
+ if ((this._connection == null) && (this.connectionVersion() != null) ){
+ this._connection = new Clipperz.PM.Connection.communicationProtocol.versions[this.connectionVersion()]({
+ getCredentialsFunction: MochiKit.Base.method(this, 'getCredentials')
+ });
+ }
+
+ return this._connection;
+ },
+
+ 'resetConnection': function(aValue) {
+ if (this._connection != null) {
+ this._connection.reset();
+ }
+
+ this._connection = null;
+ },
+
+ //=========================================================================
+
+ 'getHeaderIndex': function (aKey) {
+ return Clipperz.Async.callbacks("User.getHeaderIndex", [
+ MochiKit.Base.method(this, 'getServerData'),
+ MochiKit.Base.itemgetter('header'),
+ MochiKit.Base.itemgetter(aKey)
+ ], {trace:false})
+ },
+
+ //=========================================================================
+
+ 'getRecords': function () {
+ return Clipperz.Async.callbacks("User.getRecords", [
+ MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
+ MochiKit.Base.methodcaller('records'),
+ MochiKit.Base.values
+ ], {trace:false});
+ },
+
+ 'recordWithLabel': function (aLabel) {
+ return Clipperz.Async.callbacks("User.recordWithLabel", [
+ MochiKit.Base.method(this, 'getRecords'),
+ MochiKit.Base.partial(Clipperz.Async.deferredFilter, function (aRecord) {
+ return Clipperz.Async.callbacks("User.recordWithLabel - check record label", [
+ MochiKit.Base.methodcaller('label'),
+ MochiKit.Base.partial(MochiKit.Base.operator.eq, aLabel)
+ ], {trace:false}, aRecord);
+ }),
+ function (someFilteredResults) {
+ var result;
+
+ switch (someFilteredResults.length) {
+ case 0:
+ result = null;
+ break;
+ case 1:
+ result = someFilteredResults[0];
+ break;
+ default:
+ WTF = TODO;
+ break;
+ }
+
+ return result;
+ }
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getRecord': function (aRecordReference) {
+ return Clipperz.Async.callbacks("User.getRecord", [
+ MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
+ MochiKit.Base.methodcaller('records'),
+ MochiKit.Base.itemgetter(aRecordReference),
+
+ Clipperz.Async.deferredIf("record != null", [
+ MochiKit.Base.operator.identity
+ ], [
+ function () { throw "Record does not exists"}
+ ])
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getRecordDetail': function (aRecordReference) {
+ return this.connection().message('getRecordDetail', {reference: aRecordReference});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deleteRecord': function (aRecord) {
+ return Clipperz.Async.callbacks("User.deleteRecord", [
+ MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
+ MochiKit.Base.methodcaller('deleteRecord', aRecord)
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'createNewRecord': function () {
+ return Clipperz.Async.callbacks("User.createNewRecord", [
+ MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
+ MochiKit.Base.methodcaller('createNewRecord')
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'getDirectLogins': function() {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("User.getDirectLogins", {trace:false});
+ deferredResult.addMethod(this, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.compose(MochiKit.Base.values, MochiKit.Base.methodcaller('directLogins')));
+ deferredResult.addCallback(MochiKit.Base.flattenArray);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'getOneTimePasswords': function () {
+ return Clipperz.Async.callbacks("User.getOneTimePasswords", [
+ MochiKit.Base.method(this, 'getHeaderIndex', 'oneTimePasswords'),
+ MochiKit.Base.methodcaller('oneTimePasswords'),
+ MochiKit.Base.values
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'invokeMethodNamedOnHeader': function (aMethodName, aValue) {
+ return Clipperz.Async.collectResults("User.invokeMethodNamedOnHeader [" + aMethodName + "]", {
+ 'recordIndex': [
+ MochiKit.Base.method(this, 'getHeaderIndex', 'recordsIndex'),
+ MochiKit.Base.methodcaller(aMethodName, aValue)
+ ],
+ 'preferences': [
+ MochiKit.Base.method(this, 'getHeaderIndex', 'preferences'),
+ MochiKit.Base.methodcaller(aMethodName, aValue)
+ ],
+ 'oneTimePasswords': [
+ MochiKit.Base.method(this, 'getHeaderIndex', 'oneTimePasswords'),
+ MochiKit.Base.methodcaller(aMethodName, aValue)
+ ]//,
+// 'statistics': [
+// MochiKit.Base.method(this, 'getStatistics'),
+// MochiKit.Base.methodcaller(aMethodName, aValue)
+// ]
+ }, {trace:false})();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'invokeMethodNamedOnRecords': function (aMethodName, aValue) {
+ return Clipperz.Async.callbacks("User.invokeMethodNamedOnRecords[" + aMethodName + "]", [
+ MochiKit.Base.method(this, 'getRecords'),
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.methodcaller(aMethodName, aValue)),
+ Clipperz.Async.collectAll
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'hasPendingChanges': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("User.hasPendingChanges", {trace:false});
+ deferredResult.collectResults({
+ 'header': [
+ MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasPendingChanges'),
+ MochiKit.Base.values
+ ],
+ 'records': MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasPendingChanges')
+ });
+ deferredResult.addCallback(Clipperz.Async.or);
+ deferredResult.callback();
+// recordsIndex = legacyHeader;
+// preferences = legacyHeader;
+// oneTimePasswords = legacyHeader;
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'commitTransientState': function () {
+ return Clipperz.Async.callbacks("User.commitTransientState", [
+ MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'commitTransientState'),
+ MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'commitTransientState'),
+
+ MochiKit.Base.method(this, 'transientState'),
+ MochiKit.Base.itemgetter('lock'),
+ MochiKit.Base.method(this, 'setServerLockValue'),
+ MochiKit.Base.method(this, 'resetTransientState', true)
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'revertChanges': function () {
+ return Clipperz.Async.callbacks("User.revertChanges", [
+ MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'revertChanges'),
+ MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'revertChanges'),
+ MochiKit.Base.method(this, 'resetTransientState', false)
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'deleteAllCleanTextData': function () {
+ return Clipperz.Async.callbacks("User.deleteAllCleanTextData", [
+ MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'deleteAllCleanTextData'),
+ MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'deleteAllCleanTextData'),
+
+ MochiKit.Base.method(this.data(), 'removeAllData'),
+ MochiKit.Base.method(this, 'resetTransientState', false)
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hasAnyCleanTextData': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("User.hasAnyCleanTextData", {trace:false});
+ deferredResult.collectResults({
+ 'header': [
+ MochiKit.Base.method(this, 'invokeMethodNamedOnHeader', 'hasAnyCleanTextData'),
+ MochiKit.Base.values
+ ],
+ 'records': MochiKit.Base.method(this, 'invokeMethodNamedOnRecords', 'hasAnyCleanTextData'),
+ 'data': MochiKit.Base.bind(function () {
+ return MochiKit.Async.succeed(! this.data().isEmpty());
+ }, this),
+ 'transientState': MochiKit.Base.bind(function () {
+ return MochiKit.Async.succeed(MochiKit.Base.keys(this.transientState()).length != 0);
+ }, this)
+ });
+ deferredResult.addCallback(Clipperz.Async.or);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'prepareRemoteDataWithKey': function (aKey /*, aCurrentKey*/) {
+ var deferredResult;
+ var result;
+
+ result = {};
+ deferredResult = new Clipperz.Async.Deferred("User.prepareRemoteDataWithKey", {trace:false});
+ deferredResult.addMethod(this, 'invokeMethodNamedOnHeader', 'prepareRemoteDataWithKey', aKey /*, aCurrentKey*/);
+ deferredResult.addCallback(MochiKit.Base.bind(function (aResult, someHeaderPackedData) {
+ var header;
+
+ header = {};
+ header['records'] = someHeaderPackedData['recordIndex']['records'];
+ header['directLogins'] = someHeaderPackedData['recordIndex']['directLogins'];
+ header['preferences'] = {'data': someHeaderPackedData['preferences']['data']}; // this._serverData['header']['preferences']; // Clipperz.Base.evalJSON(this._serverData['header']['data'])['preferences']; // ???????????
+ header['oneTimePasswords'] = {'data': someHeaderPackedData['oneTimePasswords']['data']}; // this._serverData['header']['oneTimePasswords']; // Clipperz.Base.evalJSON(this._serverData['header']['data'])['oneTimePasswords']; // ???????????
+ header['version'] = '0.1';
+
+ aResult['header'] = Clipperz.Base.serializeJSON(header);
+ aResult['statistics'] = this._serverData['statistics']; // "someHeaderPackedData['statistics']['data']";
+
+ return aResult;
+ }, this), result);
+ deferredResult.addCallback(Clipperz.Async.setItem, result, 'version', Clipperz.PM.Crypto.encryptingFunctions.currentVersion);
+ deferredResult.addCallback(Clipperz.Async.setItem, result, 'lock', this.serverLockValue());
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'saveChanges': function () {
+ var deferredResult;
+ var messageParameters;
+
+ messageParameters = {};
+
+ deferredResult = new Clipperz.Async.Deferred("User.saveChangaes", {trace:false});
+
+ deferredResult.addMethod(this, 'getHeaderIndex', 'recordsIndex');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('prepareRemoteDataForChangedRecords'));
+ deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'records');
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+
+ deferredResult.addMethod(this, 'getPassphrase');
+ deferredResult.addMethod(this, 'prepareRemoteDataWithKey');
+ deferredResult.addCallback(Clipperz.Async.setItem, messageParameters, 'user');
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+
+ deferredResult.addCallback(MochiKit.Async.succeed, messageParameters);
+ deferredResult.addMethod(this.connection(), 'message', 'saveChanges');
+ deferredResult.addCallback(MochiKit.Base.update, this.transientState())
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+
+ deferredResult.addMethod(this, 'commitTransientState');
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'userDataSuccessfullySaved');
+
+ deferredResult.addErrbackPass(MochiKit.Base.method(this, 'revertChanges'));
+ deferredResult.addErrbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'failureWhileSavingUserData');
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+//-----------------------------------------------------------------------------
+
+Clipperz.PM.DataModel.User.registerNewAccount = function (anUsername, aPassphraseFunction) {
+ var deferredResult;
+ var user;
+
+ user = new Clipperz.PM.DataModel.User({'username':anUsername, 'getPassphraseFunction':aPassphraseFunction});
+
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.PM.DataModel.User.registerNewAccount", {trace:false});
+ deferredResult.addMethod(user, 'registerAsNewAccount');
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addCallback(MochiKit.Async.succeed, user);
+ deferredResult.callback();
+
+ return deferredResult;
+}
+
+//-----------------------------------------------------------------------------
+
+Clipperz.PM.DataModel.User.exception = {
+ LoginFailed: new MochiKit.Base.NamedError("Clipperz.PM.DataModel.User.exception.LoginFailed"),
+ CredentialUpgradeFailed: new MochiKit.Base.NamedError("Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed")
+};
+
+//-----------------------------------------------------------------------------
diff --git a/frontend/gamma/js/Clipperz/PM/Date.js b/frontend/gamma/js/Clipperz/PM/Date.js
new file mode 100644
index 0000000..a131357
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/Date.js
@@ -0,0 +1,201 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+if (typeof(Clipperz.PM.Date) == 'undefined') { Clipperz.PM.Date = {}; }
+
+Clipperz.PM.Date.VERSION = "0.1";
+Clipperz.PM.Date.NAME = "Clipperz.PM.Date";
+
+MochiKit.Base.update(Clipperz.PM.Date, {
+
+ '__repr__': function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return this.__repr__();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'locale': function() {
+ return {
+ 'amDesignation': Clipperz.PM.Strings.getValue('calendarStrings.amDesignation'),
+ 'pmDesignation': Clipperz.PM.Strings.getValue('calendarStrings.pmDesignation'),
+ 'days': Clipperz.PM.Strings.getValue('calendarStrings.days'),
+ 'shortDays': Clipperz.PM.Strings.getValue('calendarStrings.shortDays'),
+ 'shortMonths': Clipperz.PM.Strings.getValue('calendarStrings.shortMonths'),
+ 'months': Clipperz.PM.Strings.getValue('calendarStrings.months')
+ }
+ },
+
+ //=========================================================================
+/*
+ 'formatDateWithPHPLikeTemplate': function(aDate, aTemplate) {
+ return Clipperz.Date.formatDateWithPHPLikeTemplateAndLocale(aDate, aTemplate, Clipperz.PM.Date.locale());
+ },
+
+ 'parseDateWithPHPLikeTemplate': function(aDate, aTemplate) {
+ return Clipperz.Date.parseDateWithPHPTemplateAndLocale(aDate, aTemplate, Clipperz.PM.Date.locale());
+ },
+
+ //=========================================================================
+
+ 'formatDateWithJavaLikeTemplate': function(aDate, aTemplate) {
+ return Clipperz.Date.formatDateWithJavaLikeTemplateAndLocale(aDate, aTemplate, Clipperz.PM.Date.locale());
+ },
+
+ 'parseDateWithJavaLikeTemplate': function(aDate, aTemplate) {
+ return Clipperz.Date.parseDateWithJavaLikeTemplateAndLocale(aDate, aTemplate, Clipperz.PM.Date.locale());
+ },
+*/
+ //=========================================================================
+
+ 'formatWithTemplate': function (aTemplate, aDate) {
+ return Clipperz.PM.Date.formatDateWithTemplate(aDate, aTemplate);
+ },
+
+ 'formatDateWithTemplate': function(aDate, aTemplate) {
+ var result;
+
+ if (aDate == null) {
+ result = ""
+ } else {
+ result = Clipperz.Date.formatDateWithPHPLikeTemplateAndLocale(aDate, aTemplate, Clipperz.PM.Date.locale());
+ };
+
+ return result;
+ },
+
+ 'parseDateWithTemplate': function(aValue, aTemplate) {
+ return Clipperz.Date.parseDateWithPHPTemplateAndLocale(aValue, aTemplate, Clipperz.PM.Date.locale());
+ },
+
+ //=========================================================================
+
+ 'formatDateWithUTCFormat': function(aDate) {
+ return Clipperz.Date.formatDateWithUTCFormatAndLocale(aDate, Clipperz.PM.Date.locale());
+ },
+
+ 'parseDateWithUTCFormat': function(aValue) {
+ var result;
+
+ if (aValue == null) {
+ result = null;
+ } else {
+ result = Clipperz.Date.parseDateWithUTCFormatAndLocale(aValue, Clipperz.PM.Date.locale());
+ }
+
+ return result;
+ },
+
+ //=========================================================================
+
+ 'getElapsedTimeDescription': function(aDate) {
+ var result;
+
+ result = ""
+
+ if (aDate != null) {
+ var now;
+ var elapsedTime;
+
+ var millisencondsInAMinute;
+ var millisencondsInAnHour;
+ var millisencondsInADay;
+ var millisencondsInAWeek;
+ var millisencondsInAMonth;
+
+ now = new Date();
+ elapsedTime = now.getTime() - aDate.getTime();
+
+ millisencondsInAMinute = 60 * 1000;
+ millisencondsInAnHour = millisencondsInAMinute * 60;
+ millisencondsInADay = millisencondsInAnHour * 24;
+ millisencondsInAWeek = millisencondsInADay * 7;
+ millisencondsInAMonth = millisencondsInAWeek * 5;
+
+ if ((elapsedTime / millisencondsInAMonth) > 1) {
+ result = Clipperz.PM.Strings.getValue('elapsedTimeDescriptions.MORE_THAN_A_MONTH_AGO');
+ } else if ((elapsedTime / millisencondsInAWeek) > 1) {
+ var elapsedWeeks;
+
+ elapsedWeeks = Math.floor((elapsedTime / millisencondsInAWeek));
+ if (elapsedWeeks == 1) {
+ result = Clipperz.PM.Strings.getValue('elapsedTimeDescriptions.MORE_THAN_A_WEEK_AGO');
+ } else {
+ result = Clipperz.PM.Strings.getValue('elapsedTimeDescriptions.MORE_THAN_*_WEEKS_AGO').replace(/__elapsed__/, elapsedWeeks);
+ }
+ } else if ((elapsedTime / millisencondsInADay) > 1) {
+ var elapsedDays;
+
+ elapsedDays = Math.floor((elapsedTime / millisencondsInADay));
+ if (elapsedDays == 1) {
+ result = Clipperz.PM.Strings.getValue('elapsedTimeDescriptions.YESTERDAY');
+ } else {
+ result = Clipperz.PM.Strings.getValue('elapsedTimeDescriptions.*_DAYS_AGO').replace(/__elapsed__/, elapsedDays);
+ }
+ } else if ((elapsedTime / millisencondsInAnHour) > 1) {
+ var elapsedHours;
+
+ elapsedHours = Math.floor((elapsedTime / millisencondsInAnHour));
+ if (elapsedHours == 1) {
+ result = Clipperz.PM.Strings.getValue('elapsedTimeDescriptions.ABOUT_AN_HOUR_AGO');
+ } else {
+ result = Clipperz.PM.Strings.getValue('elapsedTimeDescriptions.*_HOURS_AGO').replace(/__elapsed__/, elapsedHours);
+ }
+ } else {
+ var elapsed10Minutes;
+
+ elapsed10Minutes = (Math.floor((elapsedTime / millisencondsInAMinute) / 10)) * 10;
+ if (elapsed10Minutes == 0) {
+ result = Clipperz.PM.Strings.getValue('elapsedTimeDescriptions.JUST_A_FEW_MINUTES_AGO');
+ } else {
+ result = Clipperz.PM.Strings.getValue('elapsedTimeDescriptions.ABOUT_*_MINUTES_AGO').replace(/__elapsed__/, elapsed10Minutes+"");
+ }
+ }
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'parse': function (aValue) {
+ return Clipperz.PM.Date.parseDateWithUTCFormat(aValue);
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
diff --git a/frontend/gamma/js/Clipperz/PM/Proxy.js b/frontend/gamma/js/Clipperz/PM/Proxy.js
new file mode 100644
index 0000000..d90bcb7
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/Proxy.js
@@ -0,0 +1,172 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+
+//=============================================================================
+
+Clipperz.PM.Proxy = function(args) {
+ args = args || {};
+
+ this._shouldPayTolls = args.shouldPayTolls || false;
+
+ this._tolls = {
+ 'CONNECT': [],
+ 'REGISTER': [],
+ 'MESSAGE': []
+ };
+
+ if (args.isDefault === true) {
+ Clipperz.PM.Proxy.defaultProxy = this;
+ }
+
+ return this;
+}
+
+Clipperz.PM.Proxy.prototype = MochiKit.Base.update(null, {
+
+ 'toString': function() {
+ return "Clipperz.PM.Proxy";
+ },
+
+ //=========================================================================
+
+ 'shouldPayTolls': function() {
+ return this._shouldPayTolls;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'tolls': function() {
+ return this._tolls;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'payToll': function(aRequestType, someParameters) {
+ var deferredResult;
+
+//console.log(">>> Proxy.payToll", aRequestType, someParameters);
+ if (this.shouldPayTolls()) {
+ deferredResult = new Clipperz.Async.Deferred("Proxy.payToll", {trace:false});
+
+ if (this.tolls()[aRequestType].length == 0) {
+ deferredResult.addMethod(this, 'sendMessage', 'knock', {requestType:aRequestType});
+ deferredResult.addMethod(this, 'setTollCallback');
+ }
+ deferredResult.addMethod(this.tolls()[aRequestType], 'pop');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('deferredPay'));
+ deferredResult.addCallback(function(aToll) {
+ var result;
+
+ result = {
+ parameters: someParameters,
+ toll: aToll
+ }
+
+ return result;
+ });
+
+ deferredResult.callback();
+ } else {
+ deferredResult = MochiKit.Async.succeed({parameters:someParameters});
+ }
+//console.log("<<< Proxy.payToll");
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addToll': function(aToll) {
+//console.log(">>> Proxy.addToll", aToll);
+ this.tolls()[aToll.requestType()].push(aToll);
+//console.log("<<< Proxy.addToll");
+ },
+
+ //=========================================================================
+
+ 'setTollCallback': function(someParameters) {
+//console.log(">>> Proxy.setTollCallback", someParameters);
+ if (typeof(someParameters['toll']) != 'undefined') {
+//console.log("added a new toll", someParameters['toll']);
+ this.addToll(new Clipperz.PM.Toll(someParameters['toll']));
+ }
+//console.log("<<< Proxy.setTallCallback", someParameters['result']);
+ return someParameters['result'];
+ },
+
+ //=========================================================================
+
+ 'registration': function (someParameters) {
+ return this.processMessage('registration', someParameters, 'REGISTER');
+ },
+
+ 'handshake': function (someParameters) {
+ return this.processMessage('handshake', someParameters, 'CONNECT');
+ },
+
+ 'message': function (someParameters) {
+ return this.processMessage('message', someParameters, 'MESSAGE');
+ },
+
+ 'logout': function (someParameters) {
+ return this.processMessage('logout', someParameters, 'MESSAGE');
+ },
+
+ //=========================================================================
+
+ 'processMessage': function (aFunctionName, someParameters, aRequestType) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("Proxy.processMessage", {trace:false});
+ deferredResult.addMethod(this, 'payToll', aRequestType);
+ deferredResult.addMethod(this, 'sendMessage', aFunctionName);
+ deferredResult.addMethod(this, 'setTollCallback');
+ deferredResult.callback(someParameters);
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'sendMessage': function () {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //=========================================================================
+
+ 'isReadOnly': function () {
+ return false;
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+
+});
diff --git a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.JSON.js b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.JSON.js
new file mode 100755
index 0000000..65b46de
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.JSON.js
@@ -0,0 +1,94 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+
+//=============================================================================
+
+Clipperz.PM.Proxy.JSON = function(args) {
+ Clipperz.PM.Proxy.JSON.superclass.constructor.call(this, args);
+
+ this._url = args.url || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ return this;
+}
+
+Clipperz.Base.extend(Clipperz.PM.Proxy.JSON, Clipperz.PM.Proxy, {
+
+ 'toString': function() {
+ return "Clipperz.PM.Proxy.JSON";
+ },
+
+ //=========================================================================
+
+ 'url': function () {
+ return this._url;
+ },
+
+ //=========================================================================
+
+ 'sendMessage': function(aFunctionName, someParameters) {
+ var deferredResult;
+ var parameters;
+
+ parameters = {
+ method: aFunctionName,
+// version: someParameters['version'],
+// message: someParameters['message'],
+ parameters: Clipperz.Base.serializeJSON(someParameters)
+ };
+
+ deferredResult = new Clipperz.Async.Deferred("Proxy.JSON.sendMessage", {trace:false});
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'remoteRequestSent');
+ deferredResult.addCallback(MochiKit.Async.doXHR, this.url(), {
+ method:'POST',
+ sendContent:MochiKit.Base.queryString(parameters),
+ headers:{"Content-Type":"application/x-www-form-urlencoded"}
+ });
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'remoteRequestReceived');
+// deferredResult.addCallback(MochiKit.Async.evalJSONRequest);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('responseText'));
+ deferredResult.addCallback(Clipperz.Base.evalJSON);
+ deferredResult.addCallback(function (someValues) {
+ if (someValues['result'] == 'EXCEPTION') {
+ throw someValues['message'];
+ }
+
+ return someValues;
+ })
+// return MochiKit.Base.evalJSON(req.responseText);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+
+});
diff --git a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
new file mode 100644
index 0000000..de8e7f6
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js
@@ -0,0 +1,811 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try { if (typeof(Clipperz.PM.Proxy.Offline) == 'undefined') { throw ""; }} catch (e) {
+ throw "Clipperz.PM.Proxy.Offline.DataStore depends on Clipperz.PM.Proxy.Offline!";
+}
+
+//=============================================================================
+
+Clipperz.PM.Proxy.Offline.DataStore = function(args) {
+ args = args || {};
+
+ this._data = args.data || (typeof(_clipperz_dump_data_) != 'undefined' ? _clipperz_dump_data_ : null);
+ this._isReadOnly = (typeof(args.readOnly) == 'undefined' ? true : args.readOnly);
+ this._shouldPayTolls = args.shouldPayTolls || false;
+
+ this._tolls = {};
+ this._currentStaticConnection = null;
+
+ return this;
+}
+
+Clipperz.Base.extend(Clipperz.PM.Proxy.Offline.DataStore, Object, {
+
+ //-------------------------------------------------------------------------
+
+ 'isReadOnly': function () {
+ return this._isReadOnly;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'shouldPayTolls': function() {
+ return this._shouldPayTolls;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'data': function () {
+ return this._data;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'tolls': function () {
+ return this._tolls;
+ },
+
+ //=========================================================================
+
+ 'resetData': function() {
+ this._data = {
+ 'users': {
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ }
+ }
+ };
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setupWithEncryptedData': function(someData) {
+ this._data = Clipperz.Base.deepClone(someData);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setupWithData': function(someData) {
+ var deferredResult;
+ var resultData;
+ var i, c;
+
+//Clipperz.log(">>> Proxy.Test.setupWithData");
+ resultData = this._data;
+
+ deferredResult = new Clipperz.Async.Deferred("Proxy.Test.seupWithData", {trace:false});
+ c = someData['users'].length;
+
+ for (i=0; i<c; i++) {
+ var newConnection;
+ var recordConfiguration;
+
+ deferredResult.addMethod(this, 'userSerializedEncryptedData', someData['users'][i]);
+ deferredResult.addCallback(MochiKit.Base.bind(function(aUserSerializationContext) {
+//console.log("SERIALIZED USER", aUserSerializationContext);
+ resultData['users'][aUserSerializationContext['credentials']['C']] = {
+ 's': aUserSerializationContext['credentials']['s'],
+ 'v': aUserSerializationContext['credentials']['v'],
+ 'version': aUserSerializationContext['data']['connectionVersion'],
+ 'userDetails': aUserSerializationContext['encryptedData']['user']['header'],
+ 'userDetailsVersion': aUserSerializationContext['encryptedData']['user']['version'],
+ 'statistics': aUserSerializationContext['encryptedData']['user']['statistics'],
+ 'lock': aUserSerializationContext['encryptedData']['user']['lock'],
+ 'records': this.rearrangeRecordsData(aUserSerializationContext['encryptedData']['records'])
+ }
+ }, this));
+ }
+
+ deferredResult.addCallback(MochiKit.Base.bind(function() {
+//console.log("this._data", resultData);
+ this._data = resultData;
+ }, this));
+
+ deferredResult.callback();
+//Clipperz.log("<<< Proxy.Test.setupWithData");
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'getTollForRequestType': function (aRequestType) {
+ var result;
+ var targetValue;
+ var cost;
+
+ targetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
+ switch (aRequestType) {
+ case 'REGISTER':
+ cost = 5;
+ break;
+ case 'CONNECT':
+ cost = 5;
+ break;
+ case 'MESSAGE':
+ cost = 2;
+ break;
+ }
+
+ result = {
+ requestType: aRequestType,
+ targetValue: targetValue,
+ cost: cost
+ }
+
+ if (this.shouldPayTolls()) {
+ this.tolls()[targetValue] = result;
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'checkToll': function (aFunctionName, someParameters) {
+ if (this.shouldPayTolls()) {
+ var localToll;
+ var tollParameters;
+
+ tollParameters = someParameters['toll'];
+ localToll = this.tolls()[tollParameters['targetValue']];
+
+ if (localToll != null) {
+ if (! Clipperz.PM.Toll.validate(tollParameters['targetValue'], tollParameters['toll'], localToll['cost'])) {
+ throw "Toll value too low.";
+ };
+ } else {
+ throw "Missing toll";
+ }
+ }
+ },
+
+ //=========================================================================
+
+ 'currentStaticConnection': function () {
+ if (this._currentStaticConnection == null) {
+ this._currentStaticConnection = {};
+ }
+
+ return this._currentStaticConnection;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getConnectionForRequest': function (aFunctionName, someParameters) {
+ var result;
+
+ if (this.shouldPayTolls()) {
+ if ((typeof(someParameters['toll']) != 'undefined') && (typeof(someParameters['toll']['targetValue']) != 'undefined')) {
+ result = this.tolls()[someParameters['toll']['targetValue']]['connection'];
+ if (typeof(result) == 'undefined') {
+ result = {};
+ }
+ } else {
+ result = {};
+ }
+ } else {
+ result = this.currentStaticConnection();
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'storeConnectionForRequestWithConnectionAndResponse': function (aFunctionName, someParameters, aConnection, aResponse) {
+ if (this.shouldPayTolls()) {
+ if ((typeof(aResponse['toll']) != 'undefined')
+ && (typeof(aResponse['toll']['targetValue']) != 'undefined')
+ && (typeof(this.tolls()[aResponse['toll']['targetValue']]) != 'undefined')
+ ) {
+ this.tolls()[aResponse['toll']['targetValue']]['connection'] = aConnection;
+ }
+ }
+ },
+
+ //=========================================================================
+
+ 'processMessage': function (aFunctionName, someParameters) {
+ var result;
+ var connection;
+
+ connection = this.getConnectionForRequest(aFunctionName, someParameters);
+
+ switch(aFunctionName) {
+ case 'knock':
+ result = this._knock(connection, someParameters);
+ break;
+ case 'registration':
+ this.checkToll(aFunctionName, someParameters);
+ result = this._registration(connection, someParameters.parameters);
+ break;
+ case 'handshake':
+ this.checkToll(aFunctionName, someParameters);
+ result = this._handshake(connection, someParameters.parameters);
+ break;
+ case 'message':
+ this.checkToll(aFunctionName, someParameters);
+ result = this._message(connection, someParameters.parameters);
+ break;
+ case 'logout':
+ this._currentStaticConnection = null;
+ result = this._logout(connection, someParameters.parameters);
+ break;
+ }
+
+ this.storeConnectionForRequestWithConnectionAndResponse(aFunctionName, someParameters, connection, result);
+
+ return MochiKit.Async.succeed(result);
+ },
+
+ //=========================================================================
+
+ '_knock': function(aConnection, someParameters) {
+ var result;
+
+ result = {
+ toll: this.getTollForRequestType(someParameters['requestType'])
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ '_registration': function(aConnection, someParameters) {
+ if (this.isReadOnly() == false) {
+ if (typeof(this.data()['users'][someParameters['credentials']['C']]) == 'undefined') {
+ this.data()['users'][someParameters['credentials']['C']] = {
+ 's': someParameters['credentials']['s'],
+ 'v': someParameters['credentials']['v'],
+ 'version': someParameters['credentials']['version'],
+ 'lock': Clipperz.Crypto.Base.generateRandomSeed(),
+ 'userDetails': someParameters['user']['header'],
+ 'statistics': someParameters['user']['statistics'],
+ 'userDetailsVersion': someParameters['user']['version'],
+ 'records': {}
+ }
+ } else {
+ throw "user already exists";
+ }
+ } else {
+ throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
+ }
+
+ result = {
+ result: {
+ 'lock': this.data()['users'][someParameters['credentials']['C']]['lock'],
+ 'result': 'done'
+ },
+ toll: this.getTollForRequestType('CONNECT')
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ '_handshake': function(aConnection, someParameters) {
+ var result;
+ var nextTollRequestType;
+
+ result = {};
+ if (someParameters.message == "connect") {
+ var userData;
+ var randomBytes;
+ var v;
+
+ userData = this.data()['users'][someParameters.parameters.C];
+
+ if ((typeof(userData) != 'undefined') && (userData['version'] == someParameters.version)) {
+ aConnection['userData'] = userData;
+ aConnection['C'] = someParameters.parameters.C;
+ } else {
+ aConnection['userData'] = this.data()['users']['catchAllUser'];
+ }
+
+ randomBytes = Clipperz.Crypto.Base.generateRandomSeed();
+ aConnection['b'] = new Clipperz.Crypto.BigInt(randomBytes, 16);
+ v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
+ aConnection['B'] = v.add(Clipperz.Crypto.SRP.g().powerModule(aConnection['b'], Clipperz.Crypto.SRP.n()));
+
+ aConnection['A'] = someParameters.parameters.A;
+
+ result['s'] = aConnection['userData']['s'];
+ result['B'] = aConnection['B'].asString(16);
+
+ nextTollRequestType = 'CONNECT';
+ } else if (someParameters.message == "credentialCheck") {
+ var v, u, S, A, K, M1;
+
+ v = new Clipperz.Crypto.BigInt(aConnection['userData']['v'], 16);
+ u = new Clipperz.Crypto.BigInt(Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(aConnection['B'].asString(10))).toHexString(), 16);
+ A = new Clipperz.Crypto.BigInt(aConnection['A'], 16);
+ S = (A.multiply(v.powerModule(u, Clipperz.Crypto.SRP.n()))).powerModule(aConnection['b'], Clipperz.Crypto.SRP.n());
+
+ K = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(S.asString(10))).toHexString().slice(2);
+
+ M1 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + aConnection['B'].asString(10) + K)).toHexString().slice(2);
+ if (someParameters.parameters.M1 == M1) {
+ var M2;
+
+ M2 = Clipperz.PM.Crypto.encryptingFunctions.versions[someParameters.version].hash(new Clipperz.ByteArray(A.asString(10) + someParameters.parameters.M1 + K)).toHexString().slice(2);
+ result['M2'] = M2;
+ } else {
+ throw new Error("Client checksum verification failed! Expected <" + M1 + ">, received <" + someParameters.parameters.M1 + ">.", "Error");
+ }
+
+ nextTollRequestType = 'MESSAGE';
+ } else if (someParameters.message == "oneTimePassword") {
+ var otpData;
+
+ otpData = this.data()['onetimePasswords'][someParameters.parameters.oneTimePasswordKey];
+
+ try {
+ if (typeof(otpData) != 'undefined') {
+ if (otpData['status'] == 'ACTIVE') {
+ if (otpData['key_checksum'] == someParameters.parameters.oneTimePasswordKeyChecksum) {
+ result = {
+ 'data': otpData['data'],
+ 'version': otpData['version']
+ }
+
+ otpData['status'] = 'REQUESTED';
+ } else {
+ otpData['status'] = 'DISABLED';
+ throw "The requested One Time Password has been disabled, due to a wrong keyChecksum";
+ }
+ } else {
+ throw "The requested One Time Password was not active";
+ }
+ } else {
+ throw "The requested One Time Password has not been found"
+ }
+ } catch (exception) {
+ result = {
+ 'data': Clipperz.PM.Crypto.randomKey(),
+ 'version': Clipperz.PM.Connection.communicationProtocol.currentVersion
+ }
+ }
+ nextTollRequestType = 'CONNECT';
+ } else {
+ MochiKit.Logging.logError("Clipperz.PM.Proxy.Test.handshake - unhandled message: " + someParameters.message);
+ }
+
+ result = {
+ result: result,
+ toll: this.getTollForRequestType(nextTollRequestType)
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ '_message': function(aConnection, someParameters) {
+ var result;
+
+ result = {};
+
+ //=====================================================================
+ //
+ // R E A D - O N L Y M e t h o d s
+ //
+ //=====================================================================
+ if (someParameters.message == 'getUserDetails') {
+ var recordsStats;
+ var recordReference;
+
+ recordsStats = {};
+ for (recordReference in aConnection['userData']['records']) {
+ recordsStats[recordReference] = {
+ 'updateDate': aConnection['userData']['records'][recordReference]['updateDate']
+ }
+ }
+
+ result['header'] = this.userDetails(aConnection);
+ result['statistics'] = this.statistics(aConnection);
+ result['maxNumberOfRecords'] = aConnection['userData']['maxNumberOfRecords'];
+ result['version'] = aConnection['userData']['userDetailsVersion'];
+ result['recordsStats'] = recordsStats;
+
+ if (this.isReadOnly() == false) {
+ var lock;
+
+ if (typeof(aConnection['userData']['lock']) == 'undefined') {
+ aConnection['userData']['lock'] = "<<LOCK>>";
+ }
+
+ result['lock'] = aConnection['userData']['lock'];
+ }
+
+ //=====================================================================
+ } else if (someParameters.message == 'getRecordDetail') {
+/*
+ var recordData;
+ var currentVersionData;
+
+ recordData = this.userData()['records'][someParameters['parameters']['reference']];
+ result['reference'] = someParameters['parameters']['reference'];
+ result['data'] = recordData['data'];
+ result['version'] = recordData['version'];
+ result['creationData'] = recordData['creationDate'];
+ result['updateDate'] = recordData['updateDate'];
+ result['accessDate'] = recordData['accessDate'];
+
+ currentVersionData = recordData['versions'][recordData['currentVersion']];
+
+ result['currentVersion'] = {};
+ result['currentVersion']['reference'] = recordData['currentVersion'];
+ result['currentVersion']['version'] = currentVersionData['version'];
+ result['currentVersion']['header'] = currentVersionData['header'];
+ result['currentVersion']['data'] = currentVersionData['data'];
+ result['currentVersion']['creationData'] = currentVersionData['creationDate'];
+ result['currentVersion']['updateDate'] = currentVersionData['updateDate'];
+ result['currentVersion']['accessDate'] = currentVersionData['accessDate'];
+ if (typeof(currentVersionData['previousVersion']) != 'undefined') {
+ result['currentVersion']['previousVersionKey'] = currentVersionData['previousVersionKey'];
+ result['currentVersion']['previousVersion'] = currentVersionData['previousVersion'];
+ }
+*/
+ MochiKit.Base.update(result, aConnection['userData']['records'][someParameters['parameters']['reference']]);
+ result['reference'] = someParameters['parameters']['reference'];
+
+ //=====================================================================
+ //
+ // R E A D - W R I T E M e t h o d s
+ //
+ //=====================================================================
+ } else if (someParameters.message == 'upgradeUserCredentials') {
+ if (this.isReadOnly() == false) {
+ var parameters;
+ var credentials;
+
+ parameters = someParameters['parameters'];
+ credentials = parameters['credentials'];
+
+ if ((credentials['C'] == null)
+ || (credentials['s'] == null)
+ || (credentials['v'] == null)
+ || (credentials['version'] != Clipperz.PM.Connection.communicationProtocol.currentVersion)
+ ) {
+ result = Clipperz.PM.DataModel.User.exception.CredentialUpgradeFailed;
+ } else {
+ var oldCValue;
+ oldCValue = aConnection['C'];
+
+ this.data()['users'][credentials['C']] = aConnection['userData'];
+ aConnection['C'] = credentials['C'];
+
+ aConnection['userData']['s'] = credentials['s'];
+ aConnection['userData']['v'] = credentials['v'];
+ aConnection['userData']['version'] = credentials['version'];
+
+ aConnection['userData']['userDetails'] = parameters['user']['header'];
+ aConnection['userData']['userDetailsVersion'] = parameters['user']['version'];
+ aConnection['userData']['statistics'] = parameters['user']['statistics'];
+
+ aConnection['userData']['lock'] = parameters['user']['lock'];
+
+ delete this.data()['users'][oldCValue];
+
+ result = {result:"done", parameters:parameters};
+ }
+ } else {
+ throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
+ }
+ //=====================================================================
+/* } else if (someParameters.message == 'updateData') {
+ if (this.isReadOnly() == false) {
+ var i, c;
+
+//console.log("###===============================================================");
+//console.log("###>>>", Clipperz.Base.serializeJSON(someParameters));
+//console.log("###--- userData", Clipperz.Base.serializeJSON(this.userData()));
+ if (this.userData()['lock'] != someParameters['parameters']['user']['lock']) {
+ throw "the lock attribute is not processed correctly"
+ }
+
+ this.userData()['userDetails'] = someParameters['parameters']['user']['header'];
+ this.userData()['statistics'] = someParameters['parameters']['user']['statistics'];
+ this.userData()['userDetailsVersions'] = someParameters['parameters']['user']['version'];
+
+ c = someParameters['parameters']['records'].length;
+ for (i=0; i<c; i++) {
+ var currentRecord;
+ var currentRecordData;
+
+ currentRecordData = someParameters['parameters']['records'][i];
+ currentRecord = this.userData()['records'][currentRecordData['record']['reference']];
+
+ if (currentRecord == null) {
+ }
+
+ currentRecord['data'] = currentRecordData['record']['data'];
+ currentRecord['version'] = currentRecordData['record']['version'];
+ currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference'];
+
+ currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = {
+ 'data': currentRecordData['currentRecordVersion']['data'],
+ 'version': currentRecordData['currentRecordVersion']['version'],
+ 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'],
+ 'previousVersionKey': currentRecordData['currentRecordVersion']['previousVersionKey']
+ }
+ }
+
+ this.userData()['lock'] = Clipperz.PM.Crypto.randomKey();
+ result['lock'] = this.userData()['lock'];
+ result['result'] = 'done';
+//console.log("###<<< userData", Clipperz.Base.serializeJSON(this.userData()));
+ } else {
+ throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
+ }
+*/ //=====================================================================
+ } else if (someParameters.message == 'saveChanges') {
+ if (this.isReadOnly() == false) {
+ var i, c;
+
+//console.log("###===============================================================");
+//console.log("###>>>", someParameters);
+//console.log("###>>>", Clipperz.Base.serializeJSON(someParameters));
+//console.log("###--- userData", Clipperz.Base.serializeJSON(this.userData()));
+//console.log("###===============================================================");
+//console.log("--- userData.lock ", this.userData()['lock']);
+//console.log("--- parameters.lock", someParameters['parameters']['user']['lock']);
+ if (aConnection['userData']['lock'] != someParameters['parameters']['user']['lock']) {
+ throw "the lock attribute is not processed correctly"
+ }
+
+ aConnection['userData']['userDetails'] = someParameters['parameters']['user']['header'];
+ aConnection['userData']['statistics'] = someParameters['parameters']['user']['statistics'];
+ aConnection['userData']['userDetailsVersions'] = someParameters['parameters']['user']['version'];
+
+ c = someParameters['parameters']['records']['updated'].length;
+ for (i=0; i<c; i++) {
+ var currentRecord;
+ var currentRecordData;
+
+ currentRecordData = someParameters['parameters']['records']['updated'][i];
+ currentRecord = aConnection['userData']['records'][currentRecordData['record']['reference']];
+
+ if (
+ (typeof(aConnection['userData']['records'][currentRecordData['record']['reference']]) == 'undefined')
+ &&
+ (typeof(currentRecordData['currentRecordVersion']) == 'undefined')
+ ) {
+//console.log("######## SHIT HAPPENS");
+ throw "Record added without a recordVersion";
+ }
+
+ if (currentRecord == null) {
+ currentRecord = {};
+ currentRecord['versions'] = {};
+ currentRecord['creationDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
+ currentRecord['accessDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
+
+ aConnection['userData']['records'][currentRecordData['record']['reference']] = currentRecord;
+ }
+
+ currentRecord['data'] = currentRecordData['record']['data'];
+ currentRecord['version'] = currentRecordData['record']['version'];
+ currentRecord['updateDate'] = Clipperz.PM.Date.formatDateWithUTCFormat(new Date());
+
+ if (typeof(currentRecordData['currentRecordVersion']) != 'undefined') {
+ currentRecord['currentVersion'] = currentRecordData['currentRecordVersion']['reference'];
+ currentRecord['versions'][currentRecordData['currentRecordVersion']['reference']] = {
+ 'data': currentRecordData['currentRecordVersion']['data'],
+ 'version': currentRecordData['currentRecordVersion']['version'],
+ 'previousVersion': currentRecordData['currentRecordVersion']['previousVersion'],
+ 'previousVersionKey': currentRecordData['currentRecordVersion']['previousVersionKey'],
+ 'creationDate': Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
+ 'updateDate': Clipperz.PM.Date.formatDateWithUTCFormat(new Date()),
+ 'accessDate': Clipperz.PM.Date.formatDateWithUTCFormat(new Date())
+ }
+ }
+ }
+
+ c = someParameters['parameters']['records']['deleted'].length;
+ for (i=0; i<c; i++) {
+ var currentRecordReference;
+
+ currentRecordReference = someParameters['parameters']['records']['deleted'][i];
+//console.log("DELETING records", currentRecordReference);
+ delete aConnection['userData']['records'][currentRecordReference];
+ }
+
+ aConnection['userData']['lock'] = Clipperz.PM.Crypto.randomKey();
+ result['lock'] = aConnection['userData']['lock'];
+ result['result'] = 'done';
+//console.log("###<<< userData", Clipperz.Base.serializeJSON(this.userData()));
+ } else {
+ throw Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly;
+ }
+
+ //=====================================================================
+ //
+ // U N H A N D L E D M e t h o d
+ //
+ //=====================================================================
+ } else {
+ MochiKit.Logging.logError("Clipperz.PM.Proxy.Test.message - unhandled message: " + someParameters.message);
+ }
+
+ result = {
+ result: result,
+ toll: this.getTollForRequestType('MESSAGE')
+ }
+
+// return MochiKit.Async.succeed(result);
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ '_logout': function(someParameters) {
+// return MochiKit.Async.succeed({result: 'done'});
+ return {result: 'done'};
+ },
+
+ //=========================================================================
+ //#########################################################################
+
+ 'isTestData': function(aConnection) {
+ return (typeof(aConnection['userData']['__masterkey_test_value__']) != 'undefined');
+ },
+
+ 'userDetails': function(aConnection) {
+ var result;
+
+ if (this.isTestData(aConnection)) {
+ var serializedHeader;
+ var version;
+
+//MochiKit.Logging.logDebug("### test data");
+ version = aConnection['userData']['userDetailsVersion'];
+ serializedHeader = Clipperz.Base.serializeJSON(aConnection['userData']['userDetails']);
+ result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedHeader);
+ } else {
+//MochiKit.Logging.logDebug("### NOT test data");
+ result = aConnection['userData']['userDetails'];
+ }
+
+ return result;
+ },
+
+ 'statistics': function(aConnection) {
+ var result;
+
+ if (aConnection['userData']['statistics'] != null) {
+ if (this.isTestData(aConnection)) {
+ var serializedStatistics;
+ var version;
+
+ version = aConnection['userData']['userDetailsVersion'];
+ serializedStatistics = Clipperz.Base.serializeJSON(aConnection['userData']['statistics']);
+ result = Clipperz.PM.Crypto.encryptingFunctions.versions[version].encrypt(aConnection['userData']['__masterkey_test_value__'], serializedStatistics);
+ } else {
+ result = aConnection['userData']['statistics'];
+ }
+ } else {
+ result = null;
+ }
+
+ return result;
+ },
+
+/*
+ 'userSerializedEncryptedData': function(someData) {
+ var deferredResult;
+ var deferredContext;
+
+ deferredContext = { 'data': someData };
+
+ deferredResult = new Clipperz.Async.Deferred('Proxy.Test.serializeUserEncryptedData', {trace:false});
+ deferredResult.addCallback(MochiKit.Base.bind(function(aDeferredContext) {
+ aDeferredContext['user'] = this.createUserUsingConfigurationData(aDeferredContext['data']);
+ return aDeferredContext;
+ }, this));
+ deferredResult.addCallback(function(aDeferredContext) {
+// return aDeferredContext['user'].encryptedDataUsingVersion(aDeferredContext['data']['version']);
+ return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']);
+ });
+ deferredResult.addCallback(function(aUserEncryptedData) {
+ deferredContext['encryptedData'] = aUserEncryptedData;
+ return deferredContext;
+ });
+ deferredResult.addCallback(function(aDeferredContext) {
+ var connection;
+
+ connection = new Clipperz.PM.Connection.communicationProtocol.versions[aDeferredContext['data']['connectionVersion']]()
+ aDeferredContext['credentials'] = connection.serverSideUserCredentials(aDeferredContext['user'].username(),aDeferredContext['user'].passphrase());
+
+ return aDeferredContext;
+ });
+
+// deferredResult.addCallback(function(aDeferredContext) {
+//console.log("#-#-#-#-#", aDeferredContext);
+// return aDeferredContext['user'].serializedDataUsingVersion(MochiKit.Base.values(aDeferredContext['user'].records()), aDeferredContext['data']['version']);
+// }, deferredContext);
+// deferredResult.addCallback(function(aUserSerializedData) {
+//console.log("USER SERIALIZED DATA", aUserSerializedData);
+// });
+//
+// deferredResult.addCallback(MochiKit.Async.succeed, deferredContext);
+ deferredResult.callback(deferredContext);
+
+ return deferredResult;
+ },
+
+ 'createUserUsingConfigurationData': function(someData) {
+ var result;
+ var user;
+ var recordLabel;
+
+ user = new Clipperz.PM.DataModel.User();
+ user.initForTests();
+ user.setUsername(someData['username']);
+ user.setPassphrase(someData['passphrase']);
+
+ for (recordLabel in someData['records']) {
+ var recordData;
+ var record;
+ var i, c;
+
+ recordData = someData['records'][recordLabel];
+ record = new Clipperz.PM.DataModel.Record({user:user, label:recordLabel});
+ record.setNotes(recordData['notes']);
+
+ c = recordData['fields'].length;
+ for (i=0; i<c; i++) {
+ var recordField;
+
+ recordField = new Clipperz.PM.DataModel.RecordField();
+ recordField.setLabel(recordData['fields'][i]['name']);
+ recordField.setValue(recordData['fields'][i]['value']);
+ recordField.setType(recordData['fields'][i]['type']);
+ record.addField(recordField);
+ }
+ user.addRecord(record, true);
+ }
+
+ result = user;
+
+ return result;
+ },
+*/
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+Clipperz.PM.Proxy.Offline.DataStore['exception'] = {
+ 'ReadOnly': new MochiKit.Base.NamedError("Clipperz.PM.Proxy.Offline.DataStore.exception.ReadOnly")
+}; \ No newline at end of file
diff --git a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.js b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.js
new file mode 100644
index 0000000..a15b223
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Offline.js
@@ -0,0 +1,67 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+
+//=============================================================================
+
+Clipperz.PM.Proxy.Offline = function(args) {
+ args = args || {};
+
+ Clipperz.PM.Proxy.Offline.superclass.constructor.call(this, args);
+
+ this._dataStore = args.dataStore || new Clipperz.PM.Proxy.Offline.DataStore(args);
+
+ return this;
+}
+
+Clipperz.Base.extend(Clipperz.PM.Proxy.Offline, Clipperz.PM.Proxy, {
+
+ 'toString': function () {
+ return "Clipperz.PM.Proxy.Offline";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'dataStore': function () {
+ return this._dataStore;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'sendMessage': function(aFunctionName, someParameters) {
+ return this.dataStore().processMessage(aFunctionName, someParameters);
+ },
+
+ //-------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+
+});
+
diff --git a/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Test.js b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Test.js
new file mode 100644
index 0000000..be1c337
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/Proxy/Proxy.Test.js
@@ -0,0 +1,167 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+if (typeof(Clipperz.PM.Proxy) == 'undefined') { Clipperz.PM.Proxy = {}; }
+
+//=============================================================================
+
+Clipperz.PM.Proxy.Test = function(args) {
+ Clipperz.PM.Proxy.Test.superclass.constructor.call(this, args);
+
+ args = args || {};
+
+ this._expectedRequests = (args.shouldCheckExpectedRequests === true) ? [] : null;
+ this._isExpectingRequests = true;
+ this._unexpectedRequests = [];
+
+ this.dataStore().resetData();
+
+ return this;
+}
+
+Clipperz.Base.extend(Clipperz.PM.Proxy.Test, Clipperz.PM.Proxy.Offline, {
+
+ 'toString': function() {
+ return "Clipperz.PM.Proxy.Test";
+ },
+
+ //=========================================================================
+
+ 'expectedRequests': function () {
+ return this._expectedRequests;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'shouldCheckExpectedRequests': function () {
+ return (this._expectedRequests != null);
+ },
+
+ 'setShouldCheckExpectedRequests': function(aValue) {
+ if (aValue) {
+ this._expectedRequests = aValue;
+ } else {
+ this._expectedRequests = null;
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'shouldNotReceiveAnyFurtherRequest': function () {
+ this._isExpectingRequests = false;
+ },
+
+ 'mayReceiveMoreRequests': function () {
+ this._isExpectingRequests = true;
+ this.resetUnexpectedRequests();
+ },
+
+ 'isExpectingRequests': function () {
+ return this._isExpectingRequests;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'unexpectedRequests': function () {
+ return this._unexpectedRequests;
+ },
+
+ 'resetUnexpectedRequests': function () {
+ this._unexpectedRequests = [];
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'testExpectedRequestParameters': function (aPath, anActualRequest, anExpectedRequest) {
+ var aKey;
+//console.log(">>> Proxy.testExpectedRequestParameters [" + aPath + "]", anActualRequest, anExpectedRequest);
+ for (aKey in anExpectedRequest) {
+ if (typeof(anActualRequest[aKey]) == 'undefined') {
+ throw "the expected paramter [" + aKey + "] is missing from the actual request";
+ }
+ if (typeof(anExpectedRequest[aKey]) == 'object') {
+ this.testExpectedRequestParameters(aPath + "." + aKey, anActualRequest[aKey], anExpectedRequest[aKey])
+ } else {
+ if (! anExpectedRequest[aKey](anActualRequest[aKey])) {
+ throw "wrong value for paramter [" + aKey + "]; got '" + anActualRequest[aKey] + "'";
+ }
+ }
+ }
+//console.log("<<< Proxy.testExpectedRequestParameters");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'checkRequest': function(aFunctionName, someParameters) {
+ if (this.shouldCheckExpectedRequests()) {
+ var expectedRequest;
+
+//console.log(">>> Proxy.Test.checkRequest - " + aFunctionName, someParameters);
+ expectedRequest = this.expectedRequests().pop();
+//console.log("--- Proxy.Test.checkRequest - expectedRequest", expectedRequest);
+ if (expectedRequest == null) {
+ throw "Proxy.Test.sentMessage: no expected result specified. Got request '" + aFunctionName + "': " + someParameters;
+ }
+
+ try {
+ if (aFunctionName != expectedRequest.functionName) {
+ throw "wrong function name. Got '" + aFunctionName + "', expected '" + expectedRequest.request.functionName + "'";
+ }
+
+ this.testExpectedRequestParameters("parameters", someParameters, expectedRequest.parameters);
+ } catch(exception) {
+//console.log("EXCEPTION: Proxy.Test.sentMessage[" + expectedRequest.name + "]", exception)
+ throw "Proxy.Test.sentMessage[" + expectedRequest.name + "]: " + exception;
+ }
+ }
+//console.log("<<< Proxy.Test.checkRequest");
+ },
+
+ //=========================================================================
+
+ 'sendMessage': function(aFunctionName, someParameters) {
+ var result;
+
+ if (this.isExpectingRequests() == false) {
+// throw Clipperz.PM.Connection.exception.UnexpectedRequest;
+Clipperz.log("UNEXPECTED REQUEST " + aFunctionName /* + ": " + Clipperz.Base.serializeJSON(someParameters) */);
+ this.unexpectedRequests().push({'functionName':aFunctionName, 'someParameters': someParameters});
+ };
+ this.checkRequest(aFunctionName, someParameters);
+ result = Clipperz.PM.Proxy.Test.superclass.sendMessage.call(this, aFunctionName, someParameters);
+
+ return result;
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+
+});
+
diff --git a/frontend/gamma/js/Clipperz/PM/Strings.js b/frontend/gamma/js/Clipperz/PM/Strings.js
new file mode 100644
index 0000000..43ef21f
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/Strings.js
@@ -0,0 +1,295 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+if (typeof(Clipperz.PM.Strings) == 'undefined') { Clipperz.PM.Strings = {}; }
+if (typeof(Clipperz.PM.Strings.Languages) == 'undefined') { Clipperz.PM.Strings.Languages = {}; }
+
+//-----------------------------------------------------------------------------
+/*
+Clipperz.PM.Strings.standardStrings = {
+ 'loginPanelSwitchLanguageSelectOptions': [
+/ *
+ {tag:'option', html:"Arabic (Oman) (العربية)", value:'ar-OM', disabled:true},
+ {tag:'option', html:"Arabic (Syria) (العربية)", value:'ar-SY', disabled:true},
+ {tag:'option', html:"Bahasa Indonesia", value:'id-ID', disabled:true},
+ {tag:'option', html:"Bulgarian (Български)", value:'bg-BG', disabled:true},
+ {tag:'option', html:"Català", value:'ca-ES', disabled:true},
+ {tag:'option', html:"Chinese (Simplified) (简体中文)", value:'zh-CN', disabled:true},
+ {tag:'option', html:"Chinese (Traditional) (正體中文)", value:'zh-TW', disabled:true},
+ {tag:'option', html:"Czech (Česky)", value:'cs-CZ', disabled:true},
+ {tag:'option', html:"Dansk", value:'da-DK', disabled:true},
+ {tag:'option', html:"Deutsch", value:'de-DE'/ *, disabled:true* /},
+ {tag:'option', html:"English (American)", value:'en-US'/ *, disabled:true* /},
+ {tag:'option', html:"English (British)", value:'en-GB'/ *, disabled:true* /},
+ {tag:'option', html:"English (Canadian)", value:'en-CA'/ *, disabled:true* /},
+ {tag:'option', html:"Español", value:'es-ES', disabled:true},
+ {tag:'option', html:"Eesti", value:'et-EE', disabled:true},
+ {tag:'option', html:"Français", value:'fr-FR', disabled:true},
+ {tag:'option', html:"Galego", value:'gl-ES', disabled:true},
+ {tag:'option', html:"Greek (Ελληνικά)", value:'el-GR', disabled:true},
+ {tag:'option', html:"Íslenska", value:'is-IS', disabled:true},
+ {tag:'option', html:"Italiano", value:'it-IT'/ *, disabled:true* /},
+ {tag:'option', html:"Japanese (日本語)", value:'ja-JP', disabled:true},
+ {tag:'option', html:"Korean (한국어)", value:'ko-KR', disabled:true},
+ {tag:'option', html:"Latviešu", value:'lv-LV', disabled:true},
+ {tag:'option', html:"Lietuvių", value:'lt-LT', disabled:true},
+ {tag:'option', html:"Macedonian (Македонски)", value:'mk-MK', disabled:true},
+ {tag:'option', html:"Magyar", value:'hu-HU', disabled:true},
+ {tag:'option', html:"Nederlands", value:'nl-NL', disabled:true},
+ {tag:'option', html:"Norsk bokmål", value:'nb-NO', disabled:true},
+ {tag:'option', html:"Norsk nynorsk", value:'nn-NO', disabled:true},
+ {tag:'option', html:"Persian (Western) (فارسى)", value:'fa-IR', disabled:true},
+ {tag:'option', html:"Polski", value:'pl-PL', disabled:true},
+ {tag:'option', html:"Português", value:'pt-PT'/ *, disabled:true* /},
+ {tag:'option', html:"Português Brasileiro", value:'pt-BR'/ *, disabled:true* /},
+ {tag:'option', html:"Românä", value:'ro-RO', disabled:true},
+ {tag:'option', html:"Russian (Русский)", value:'ru-RU', disabled:true},
+ {tag:'option', html:"Slovak (Slovenčina)", value:'sk-SK', disabled:true},
+ {tag:'option', html:"Slovenian (Slovenščina)", value:'sl-SI', disabled:true},
+ {tag:'option', html:"Suomi", value:'fi-FI', disabled:true},
+ {tag:'option', html:"Svenska", value:'sv-SE', disabled:true},
+ {tag:'option', html:"Thai (ไทย)", value:'th-TH', disabled:true},
+ {tag:'option', html:"Türkçe", value:'tr-TR', disabled:true},
+ {tag:'option', html:"Ukrainian (Українська)", value:'uk-UA', disabled:true}
+* /
+ {tag:'option', html:"Arabic (العربية)", value:"ar", disabled:true, cls:'disabledOption'},
+// {tag:'option', html:"Chinese (中文)", value:"zh", disabled:true},
+ {tag:'option', html:"Chinese (Simplified) (简体中文)", value:'zh-CN'},
+ {tag:'option', html:"Dutch (Nederlands)", value:"nl-NL", disabled:true, cls:'disabledOption'},
+ {tag:'option', html:"English", value:"en-US"},
+ {tag:'option', html:"French (Français)", value:"fr-FR"},
+ {tag:'option', html:"German (Deutsch)", value:"de-DE", disabled:true, cls:'disabledOption'},
+ {tag:'option', html:"Greek (Ελληνικά)", value:"el-GR", disabled:true, cls:'disabledOption'},
+ {tag:'option', html:"Hebrew (עברית)", value:"he-IL", disabled:true, cls:'disabledOption'},
+ {tag:'option', html:"Italian (Italiano)", value:"it-IT"},
+ {tag:'option', html:"Japanese (日本語)", value:"ja-JP"},
+ {tag:'option', html:"Korean (한국어)", value:"ko-KR", disabled:true, cls:'disabledOption'},
+ {tag:'option', html:"Norwegian (Norsk)", value:"no", disabled:true, cls:'disabledOption'},
+ {tag:'option', html:"Persian (فارسی)", value:"fa-IR", disabled:true, cls:'disabledOption'},
+ {tag:'option', html:"Polish (Polski)", value:"pl-PL", disabled:true, cls:'disabledOption'},
+ {tag:'option', html:"Portuguese (Português)", value:"pt-BR"},
+ {tag:'option', html:"Russian (Русский)", value:"ru-RU", disabled:true, cls:'disabledOption'},
+ {tag:'option', html:"Spanish (Español)", value:"es-ES"},
+ {tag:'option', html:"Swedish (Svenska)", value:"sv-SE", disabled:true, cls:'disabledOption'},
+ {tag:'option', html:"Turkish (Türkçe)", value:"tr-TR", disabled:true, cls:'disabledOption'},
+ {tag:'option', html:"Vietnamese (Tiếng Việt)", value:"vi-VN", disabled:true, cls:'disabledOption'}
+ ]
+}
+*/
+
+Clipperz.PM.Strings.GeneralSettings = {
+ 'defaults': {
+// 'loginFormAarghThatsBadUrl': "http://www.clipperz.com/support/faq/account_faq",
+// 'loginFormVerifyTheCodeUrl': "http://www.clipperz.com/learn_more/reviewing_the_code",
+
+// 'donateHeaderLinkUrl': "http://www.clipperz.com/donations",
+// 'creditsHeaderLinkUrl': "http://www.clipperz.com/credits",
+// 'feedbackHeaderLinkUrl': "http://www.clipperz.com/contact",
+// 'helpHeaderLinkUrl': "http://www.clipperz.com/support/user_guide",
+// 'forumHeaderLinkUrl': "http://www.clipperz.com/forum",
+
+// 'httpAuthBookmarkletConfiguration': {tag:'textarea', id:'httpAuthDefaultConfiguration', html:"" +
+// "{ \"page\":{\"title\":\"HTTP authentication\"}," + "\n" +
+// " \"form\":{\"attributes\": {" + "\n" +
+// " \"action\":\"\"," + "\n" +
+// " \"type\":\"http_auth\"" + "\n" +
+// " }, \"inputs\": [" + "\n" +
+// " {\"type\":\"text\",\"name\":\"url\",\"value\":\"\"}," + "\n" +
+// " {\"type\":\"text\",\"name\":\"username\",\"value\":\"\"}," + "\n" +
+// " {\"type\":\"password\",\"name\":\"password\",\"value\":\"\"}" + "\n" +
+// " ]}, \"version\":\"0.2.3\"}"
+// },
+
+ 'directLoginJumpPageUrl': "",
+ 'defaultFaviconUrl': "data:application/octet-stream;charset=utf-8;base64,AAABAAEAFxcAAAEAGAD8BgAAFgAAACgAAAAXAAAALgAAAAEAGAAAAAAAAAAAABIXAAASFwAAAAAAAAAAAAD///////////////////////////////////////////////////////////////////////////////////////////9zAC////////////////////////////////////////////////////////////////////////////////////////////9pAG////////////////////////////////////////////////////////////////////////////////////////////9rAC////////////////////////////////////////////////////////////////////////////////////////////9yAHP////////////////////////IyMizs7O6urrq6ur////////////Ozs6zs7Ozs7Pq6ur///////////////////////8AAAD////////////////////V1dWXl5eXl5eXl5elpaX4+Pj////Ozs6Xl5eXl5eXl5eenp7///////////////////////8AAAD////////////////////Ozs6Xl5eXl5eXl5eXl5fBwcHq6uqenp6Xl5eXl5eXl5eXl5f///////////////////////8AAAD////////////////////j4+OXl5eXl5eXl5eXl5eXl5elpaWXl5eXl5eXl5eXl5ezs7P///////////////////////8AAAD////////////////////////IyMiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eenp7x8fH////////////////////////////////////////////////////4+PilpaWXl5eXl5eXl5eXl5eXl5eXl5eXl5fOzs7////////////////////////////////////////////////////////q6uq6urqXl5eXl5eXl5eXl5eXl5eXl5eenp7V1dX4+Pj///////////////////////8AAAD////////////4+PjOzs6lpaWXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5e6urrj4+P///////////////8AAAD////////////BwcGXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5fx8fH///////////8AAAD///////////+zs7OXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5fj4+P///////////8AAAD////////////IyMiXl5eXl5eXl5eXl5e6urqXl5eXl5eXl5eXl5esrKylpaWXl5eXl5eXl5eenp7x8fH///////////8AAAD////////////////Ozs7Ozs7V1dX4+Pj///+Xl5eXl5eXl5eXl5fOzs7////q6urOzs7Ozs7q6ur///////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD////////////////////////////////////IyMiXl5eXl5eenp7x8fH///////////////////////////////////8AAAD////////////////////////////////////////j4+Pj4+Px8fH///////////////////////////////////////8AAAD///////////////////////////////////////////////////////////////////////////////////////////8AAAD///////////////////////////////////////////////////////////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo=",
+ 'defaultFaviconUrl_IE': "https://www.clipperz.com/images/icons/misc/favicon.ico",
+
+// 'icons_baseUrl': "https://www.clipperz.com/images/icons",
+
+// 'passwordGeneratorLowercaseCharset': "abcdefghijklmnopqrstuvwxyz",
+// 'passwordGeneratorUppercaseCharset': "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+// 'passwordGeneratorNumberCharset': "0123456789",
+// 'passwordGeneratorSymbolCharset': "!@#$%^&*+?[]{}/|\\<>,.;:~=-_",
+
+// 'passwordGenerator': {
+// 'lowercaseCharset': "abcdefghijklmnopqrstuvwxyz",
+// 'uppercaseCharset': "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+// 'numberCharset': "0123456789",
+// 'symbolCharset': "!@#$%^&*+?[]{}/|\\<>,.;:~=-_",
+// },
+
+ '_': ""
+ }
+}
+
+Clipperz.PM.Strings.defaultLanguages = {
+ 'default': "en-us",
+
+// 'de': "de-de",
+// 'el': "el-gr",
+// 'he': "he-il",
+// 'ru': "ru-ru",
+
+ 'fr': "fr-fr",
+ 'es': "es-es",
+ 'zh': "zh-cn",
+ 'ja': "ja-jp",
+ 'pt': "pt-br",
+ 'it': "it-it",
+ 'en': "en-us"
+}
+
+Clipperz.PM.Strings.inputTypeToRecordFieldType = {
+ 'text': 'TXT',
+ 'password': 'PWD',
+ 'checkbox': 'CHECK',
+ 'radio': 'RADIO',
+ 'select': 'SELECT'
+};
+
+//-----------------------------------------------------------------------------
+
+Clipperz.PM.Strings.translateBookmarklet = function (aBookmarkletString) {
+ var result;
+
+ result = aBookmarkletString;
+
+ result = result.replace(/@BOOKMARKLET_NO_EXCEPTION_MESSAGE@/, Clipperz.PM.Strings.getValue('bookmarkletCopy.noExceptionMessage'));
+ result = result.replace(/@BOOKMARKLET_EXCEPTION_MESSAGE@/, Clipperz.PM.Strings.getValue('bookmarkletCopy.exceptionMessage'));
+ result = result.replace(/@BOOKMARKLET_COPY@/, Clipperz.PM.Strings.getValue('bookmarkletCopy.copy'));
+ result = result.replace(/@BOOKMARKLET_SUCCESSFUL_MESSAGE@/, Clipperz.PM.Strings.getValue('bookmarkletCopy.successfulMessage'));
+ result = result.replace(/@BOOKMARKLET_FAIL_MESSAGE@/, Clipperz.PM.Strings.getValue('bookmarkletCopy.failMessage'));
+
+ return result;
+}
+
+//-----------------------------------------------------------------------------
+
+Clipperz.PM.Strings.Languages.setSelectedLanguage = function(aLanguage) {
+ var language;
+ var selectedLanguage;
+
+ language = (aLanguage || Clipperz.PM.Strings.preferredLanguage || 'default').toLowerCase();
+ if (typeof(Clipperz.PM.Strings.defaultLanguages[language]) != 'undefined') {
+ language = Clipperz.PM.Strings.defaultLanguages[language];
+ }
+
+ if (typeof(Clipperz.PM.Strings.Languages[language]) != 'undefined') {
+ selectedLanguage = language;
+ } else if (typeof(Clipperz.PM.Strings.defaultLanguages[language.substr(0,2)]) != 'undefined') {
+ selectedLanguage = Clipperz.PM.Strings.defaultLanguages[language.substr(0,2)];
+ } else {
+ selectedLanguage = Clipperz.PM.Strings.defaultLanguages['default'];
+ }
+
+ if (selectedLanguage != Clipperz.PM.Strings.selectedLanguage) {
+ var translations;
+
+ Clipperz.PM.Strings.selectedLanguage = selectedLanguage;
+
+ translations = {};
+// MochiKit.Base.update(translations, Clipperz.PM.Strings.standardStrings)
+
+ MochiKit.Base.updatetree(translations, Clipperz.PM.Strings.Languages['defaults']);
+ MochiKit.Base.updatetree(translations, Clipperz.PM.Strings.GeneralSettings['defaults']);
+
+ MochiKit.Base.updatetree(translations, Clipperz.PM.Strings.Languages[Clipperz.PM.Strings.defaultLanguages['default']]);
+ MochiKit.Base.updatetree(translations, Clipperz.PM.Strings.GeneralSettings[Clipperz.PM.Strings.defaultLanguages['default']]);
+
+ MochiKit.Base.updatetree(translations, Clipperz.PM.Strings.Languages[selectedLanguage]);
+ MochiKit.Base.updatetree(translations, Clipperz.PM.Strings.GeneralSettings[selectedLanguage]);
+
+ Clipperz.PM.Strings.stringsObjectStore = new Clipperz.KeyValueObjectStore(/*{'name':'String.stringsObjectStore [1]'}*/);
+ Clipperz.PM.Strings.stringsObjectStore.initWithValues(translations);
+
+ if (typeof(bookmarklet) != 'undefined') {
+ Clipperz.PM.Strings.stringsObjectStore.setValue('bookmarklet', Clipperz.PM.Strings.translateBookmarklet(bookmarklet));
+ }
+
+ MochiKit.Signal.signal(Clipperz.PM.Strings.Languages, 'switchLanguage', selectedLanguage);
+ }
+}
+
+//-----------------------------------------------------------------------------
+
+Clipperz.PM.Strings.getValue = function (aKeyPath, someKeyValues) {
+ var result;
+
+ result = Clipperz.PM.Strings.stringsObjectStore.getValue(aKeyPath);
+
+//try {
+ if (typeof(result) == 'string') {
+ if (typeof (someKeyValues) != 'undefined') {
+ var key;
+
+ for (key in someKeyValues) {
+ result = result.replace( new RegExp(key), someKeyValues[key]);
+ // result.replace(, '');
+ }
+ }
+
+ result = result.replace(new RegExp('\n'), '<br>');
+ }
+//} catch (exception) {
+// console.log("####", result, aKeyPath, someKeyValues, exception);
+//}
+
+ return result;
+}
+
+Clipperz.PM.Strings.errorDescriptionForException = function (anException) {
+ var result;
+
+ result = Clipperz.PM.Strings.getValue('exceptionsMessages' + '.' + anException.name);
+
+ if (result == null) {
+ result = anException.message;
+ }
+
+ return result;
+},
+
+//-----------------------------------------------------------------------------
+
+Clipperz.PM.Strings.Languages.initSetup = function() {
+ var language;
+ var languageParser;
+
+ language = navigator.language || navigator.userLanguage; // en, en-US, .... "de", "nb-no"
+ languageParser = new RegExp("language=([a-z]{2}(?:\-[a-z]{2})?)(\&|$)", "i");
+ if (languageParser.test(window.location.search)) {
+ language = RegExp.$1;
+ }
+
+ Clipperz.PM.Strings.preferredLanguage = language.toLowerCase();
+ Clipperz.PM.Strings.Languages.setSelectedLanguage(Clipperz.PM.Strings.preferredLanguage);
+}
+
+//-----------------------------------------------------------------------------
diff --git a/frontend/gamma/js/Clipperz/PM/Strings/MessagePanelConfigurations.js b/frontend/gamma/js/Clipperz/PM/Strings/MessagePanelConfigurations.js
new file mode 100644
index 0000000..446e96c
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/Strings/MessagePanelConfigurations.js
@@ -0,0 +1,389 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+if (typeof(Clipperz.PM.Strings) == 'undefined') { Clipperz.PM.Strings = {}; }
+
+Clipperz.PM.Strings.messagePanelConfigurations = {
+
+
+ //-------------------------------------------------------------------------
+ //
+ // Registration - connection
+ //
+ 'registration_verify': function() {
+ return {
+ 'title': null,
+ 'text': Clipperz.PM.Strings['connectionRegistrationSendingRequestMessageText']
+ }
+ },
+
+ 'registration_sendingCredentials': function() {
+ return {
+ 'title': null,
+ 'text': Clipperz.PM.Strings['connectionRegistrationSendingCredentialsMessageText']
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ //
+ // One Time Password login message panel
+ //
+
+ 'OTP_login_start': function() {
+ return {
+ 'title': Clipperz.PM.Strings['OTPloginMessagePanelInitialTitle'],
+ 'text': Clipperz.PM.Strings['OTPloginMessagePanelInitialText'],
+ 'steps': '+3',
+ 'buttons': {}
+ }
+ },
+
+ 'OTP_login_loadingOTP': function() {
+ return {
+ 'title': Clipperz.PM.Strings['OTPloginMessagePanelLoadingTitle'],
+ 'text': Clipperz.PM.Strings['OTPloginMessagePanelLoadingText']
+ }
+ },
+
+ 'OTP_login_extractingPassphrase': function() {
+ return {
+ 'title': Clipperz.PM.Strings['OTPloginMessagePanelProcessingTitle'],
+ 'text': Clipperz.PM.Strings['OTPloginMessagePanelProcessingText']
+ }
+ },
+
+
+ //-------------------------------------------------------------------------
+ //
+ // Login message panel
+ //
+ 'login_start': function() {
+ return {
+ 'title': Clipperz.PM.Strings['loginMessagePanelInitialTitle'],
+ 'text': Clipperz.PM.Strings['loginMessagePanelInitialText'],
+ 'steps': '+7',
+ 'buttons': {
+ 'ok': Clipperz.PM.Strings['loginMessagePanelInitialButtonLabel']
+ }
+ }
+ },
+
+ 'login_connected': function() {
+ return {
+ 'title': Clipperz.PM.Strings['loginMessagePanelConnectedTitle'],
+ 'text': Clipperz.PM.Strings['loginMessagePanelConnectedText'],
+ 'buttons': {}
+ }
+ },
+
+ 'login_failed': function() {
+ return {
+ 'title': Clipperz.PM.Strings['loginMessagePanelFailureTitle'],
+ 'text': Clipperz.PM.Strings['loginMessagePanelFailureText'],
+ 'button': Clipperz.PM.Strings['loginMessagePanelFailureButtonLabel']
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ //
+ // Login message panel - connection
+ //
+ 'connection_sendingCredentials': function() {
+ return {
+ 'title': Clipperz.PM.Strings['connectionLoginSendingCredentialsMessageTitle'],
+ 'text': Clipperz.PM.Strings['connectionLoginSendingCredentialsMessageText']
+ }
+ },
+
+ 'connection_credentialVerification': function() {
+ return {
+ 'title': Clipperz.PM.Strings['connectionLoginCredentialsVerificationMessageTitle'],
+ 'text': Clipperz.PM.Strings['connectionLoginCredentialsVerificationMessageText']
+ }
+ },
+
+ 'connection_loggedIn': function() {
+ return {
+ 'title': Clipperz.PM.Strings['connectionLoginDoneMessageTitle'],
+ 'text': Clipperz.PM.Strings['connectionLoginDoneMessageText']
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ //
+ // Login message panel - user
+ //
+ 'connection_upgrading': function() {
+ return {
+ 'title': Clipperz.PM.Strings['userLoginPanelUpgradingUserCredentialsMessageTitle'],
+ 'text': Clipperz.PM.Strings['userLoginPanelUpgradingUserCredentialsMessageText'],
+ 'steps': '+1'
+ }
+ },
+
+ 'connection_done': function() {
+ return {
+ 'title': Clipperz.PM.Strings['userLoginPanelConnectedMessageTitle'],
+ 'text': Clipperz.PM.Strings['userLoginPanelConnectedMessageText']
+ }
+ },
+
+ 'connection_tryOlderSchema': function() {
+ return {
+ 'title': Clipperz.PM.Strings['userLoginPanelTryingAnOlderConnectionSchemaMessageTitle'],
+ 'text': Clipperz.PM.Strings['userLoginPanelTryingAnOlderConnectionSchemaMessageText'],
+ 'steps': '+4'
+ }
+ },
+
+ 'connection_loadingUserData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['userLoginPanelLoadingUserDataMessageTitle'],
+ 'text': Clipperz.PM.Strings['userLoginPanelLoadingUserDataMessageText']
+ }
+ },
+
+ 'connection_decryptingUserData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['userLoginPanelDecryptingUserDataMessageTitle'],
+ 'text': Clipperz.PM.Strings['userLoginPanelDecryptingUserDataMessageText'],
+ 'steps': '+1'
+ }
+ },
+
+ 'connection_decryptingUserStatistics': function() {
+ return {
+ 'title': Clipperz.PM.Strings['userLoginPanelDecryptingUserStatisticsMessageTitle'],
+ 'text': Clipperz.PM.Strings['userLoginPanelDecryptingUserStatisticsMessageText']
+ }
+ },
+
+ 'collectingEntropy': function() {
+ return {
+ 'text': Clipperz.PM.Strings['panelCollectingEntryopyMessageText'],
+ 'steps': '+1'
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ //
+ // Cards block - delete card panel
+ //
+ 'deleteRecord_collectData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['deleteRecordPanelCollectRecordDataMessageTitle'],
+ 'text': Clipperz.PM.Strings['deleteRecordPanelCollectRecordDataMessageText']
+ }
+ },
+
+ 'deleteRecord_encryptData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['deleteRecordPanelEncryptUserDataMessageTitle'],
+ 'text': Clipperz.PM.Strings['deleteRecordPanelEncryptUserDataMessageText']
+ }
+ },
+
+ 'deleteRecord_sendingData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['deleteRecordPanelSendingDataToTheServerMessageTitle'],
+ 'text': Clipperz.PM.Strings['deleteRecordPanelSendingDataToTheServerMessageText']
+ }
+ },
+
+ 'deleteRecord_updatingInterface': function() {
+ return {
+ 'title': Clipperz.PM.Strings['deleteRecordPanelUpdatingTheInterfaceMessageTitle'],
+ 'text': Clipperz.PM.Strings['deleteRecordPanelUpdatingTheInterfaceMessageText']
+ }
+ },
+
+
+ //-------------------------------------------------------------------------
+ //
+ // Cards block - save card panel
+ //
+ 'saveCard_collectRecordInfo': function() {
+ return {
+ 'title': Clipperz.PM.Strings['recordSaveChangesPanelCollectRecordInfoMessageTitle'],
+ 'text': Clipperz.PM.Strings['recordSaveChangesPanelCollectRecordInfoMessageText']
+ }
+ },
+
+ 'saveCard_encryptUserData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['recordSaveChangesPanelEncryptUserDataMessageTitle'],
+ 'text': Clipperz.PM.Strings['recordSaveChangesPanelEncryptUserDataMessageText']
+ }
+ },
+
+ 'saveCard_encryptRecordData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['recordSaveChangesPanelEncryptRecordDataMessageTitle'],
+ 'text': Clipperz.PM.Strings['recordSaveChangesPanelEncryptRecordDataMessageText']
+ }
+ },
+
+ 'saveCard_encryptRecordVersions': function() {
+ return {
+ 'title': Clipperz.PM.Strings['recordSaveChangesPanelEncryptRecordVersionDataMessageTitle'],
+ 'text': Clipperz.PM.Strings['recordSaveChangesPanelEncryptRecordVersionDataMessageText']
+ }
+ },
+
+ 'saveCard_sendingData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['recordSaveChangesPanelSendingDataToTheServerMessageTitle'],
+ 'text': Clipperz.PM.Strings['recordSaveChangesPanelSendingDataToTheServerMessageText']
+ }
+ },
+
+ 'saveCard_updatingInterface': function() {
+ return {
+ 'title': Clipperz.PM.Strings['recordSaveChangesPanelUpdatingTheInterfaceMessageTitle'],
+ 'text': Clipperz.PM.Strings['recordSaveChangesPanelUpdatingTheInterfaceMessageText']
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ //
+ // Account panel - user preferences
+ //
+ 'account_savingPreferences_1': function() {
+ return {
+ 'title': Clipperz.PM.Strings['accountPreferencesSavingPanelTitle_Step1'],
+ 'text': Clipperz.PM.Strings['accountPreferencesSavingPanelText_Step1'],
+ 'steps': '+3'
+ }
+ },
+
+ 'account_savingPreferences_2': function() {
+ return {
+ 'title': Clipperz.PM.Strings['accountPreferencesSavingPanelTitle_Step2'],
+ 'text': Clipperz.PM.Strings['accountPreferencesSavingPanelText_Step2']
+ }
+ },
+
+
+ //-------------------------------------------------------------------------
+ //
+ // Account panel - change credentials
+ //
+ 'changeCredentials_encryptingData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['changeCredentialsPanelEncryptingDataMessageTitle'],
+ 'text': Clipperz.PM.Strings['changeCredentialsPanelEncryptingDataMessageText']
+ }
+ },
+
+ 'changeCredentials_creatingNewCredentials': function() {
+ return {
+ 'title': Clipperz.PM.Strings['changeCredentialsPanelCreatingNewCredentialsMessageTitle'],
+ 'text': Clipperz.PM.Strings['changeCredentialsPanelCreatingNewCredentialsMessageText']
+ }
+ },
+
+ 'changeCredentials_sendingCredentials': function() {
+ return {
+ 'title': Clipperz.PM.Strings['changeCredentialsPanelSendingNewCredentialsToTheServerMessageTitle'],
+ 'text': Clipperz.PM.Strings['changeCredentialsPanelSendingNewCredentialsToTheServerMessageText']
+ }
+ },
+
+ 'changeCredentials_done': function() {
+ return {
+ 'title': Clipperz.PM.Strings['changeCredentialsPanelDoneMessageTitle'],
+ 'text': Clipperz.PM.Strings['changeCredentialsPanelDoneMessageText']
+ }
+ },
+
+
+ //-------------------------------------------------------------------------
+ //
+ // Account panel - change credentials
+ //
+ 'saveOTP_encryptUserData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['saveOTP_encryptUserDataTitle'],
+ 'text': Clipperz.PM.Strings['saveOTP_encryptUserDataText'],
+ 'steps': '+4'
+ }
+ },
+
+ 'saveOTP_encryptOTPData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['saveOTP_encryptOTPDataTitle'],
+ 'text': Clipperz.PM.Strings['saveOTP_encryptOTPDataText']
+ }
+ },
+
+ 'saveOTP_sendingData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['saveOTP_sendingDataTitle'],
+ 'text': Clipperz.PM.Strings['saveOTP_sendingDataText']
+ }
+ },
+
+ 'saveOTP_updatingInterface': function() {
+ return {
+ 'title': Clipperz.PM.Strings['saveOTP_updatingInterfaceTitle'],
+ 'text': Clipperz.PM.Strings['saveOTP_updatingInterfaceText']
+ }
+ },
+
+
+ //-------------------------------------------------------------------------
+ //
+ // Data panel - processingImportData
+ //
+ 'parseImportData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['importData_parsingDataTitle'],
+ 'text': Clipperz.PM.Strings['importData_parsingDataText']
+ }
+ },
+
+ 'previewImportData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['importData_previewingDataTitle'],
+ 'text': Clipperz.PM.Strings['importData_previewingDataText']
+ }
+ },
+
+ 'processingImportData': function() {
+ return {
+ 'title': Clipperz.PM.Strings['importData_processingDataTitle'],
+ 'text': Clipperz.PM.Strings['importData_processingDataText']
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+}
diff --git a/frontend/gamma/js/Clipperz/PM/Strings/Strings_defaults.js b/frontend/gamma/js/Clipperz/PM/Strings/Strings_defaults.js
new file mode 100644
index 0000000..1ad2696
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/Strings/Strings_defaults.js
@@ -0,0 +1,390 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+if (typeof(Clipperz.PM.Strings) == 'undefined') { Clipperz.PM.Strings = {}; }
+if (typeof(Clipperz.PM.Strings.Languages) == 'undefined') { Clipperz.PM.Strings.Languages = {}; }
+
+//=============================================================================
+//
+// D E F A U L T S ( defaults )
+//
+//=============================================================================
+
+Clipperz.PM.Strings.Languages['defaults'] = {
+
+'elapsedTimeDescriptions': {
+ 'MORE_THAN_A_MONTH_AGO': "more than a month ago",
+ 'MORE_THAN_A_WEEK_AGO': "more than a week ago",
+ 'MORE_THAN_*_WEEKS_AGO': "more than __elapsed__ weeks ago",
+ 'YESTERDAY': "yesterday",
+ '*_DAYS_AGO': "__elapsed__ days ago",
+ 'ABOUT_AN_HOUR_AGO': "about an hour ago",
+ '*_HOURS_AGO': "__elapsed__ hours ago",
+ 'JUST_A_FEW_MINUTES_AGO': "just a few minutes ago",
+ 'ABOUT_*_MINUTES_AGO': "about __elapsed__ minutes ago"
+},
+/*
+'unknown_ip': "unknown",
+
+'countries': {
+ '--': "unknown",
+ 'AD': "Andorra",
+ 'AE': "United Arab Emirates",
+ 'AF': "Afghanistan",
+ 'AG': "Antigua and Barbuda",
+ 'AI': "Anguilla",
+ 'AL': "Albania",
+ 'AM': "Armenia",
+ 'AN': "Netherlands Antilles",
+ 'AO': "Angola",
+ 'AP': "Non-Spec Asia Pas Location",
+ 'AR': "Argentina",
+ 'AS': "American Samoa",
+ 'AT': "Austria",
+ 'AU': "Australia",
+ 'AW': "Aruba",
+ 'AX': "Aland Islands",
+ 'AZ': "Azerbaijan",
+ 'BA': "Bosnia and Herzegowina",
+ 'BB': "Barbados",
+ 'BD': "Bangladesh",
+ 'BE': "Belgium",
+ 'BF': "Burkina Faso",
+ 'BG': "Bulgaria",
+ 'BH': "Bahrain",
+ 'BI': "Burundi",
+ 'BJ': "Benin",
+ 'BM': "Bermuda",
+ 'BN': "Brunei Darussalam",
+ 'BO': "Bolivia",
+ 'BR': "Brazil",
+ 'BS': "Bahamas",
+ 'BT': "Bhutan",
+ 'BW': "Botswana",
+ 'BY': "Belarus",
+ 'BZ': "Belize",
+ 'CA': "Canada",
+ 'CD': "Congo the Democratic Republic of the",
+ 'CF': "Central African Republic",
+ 'CH': "Switzerland",
+ 'CI': "Cote D'ivoire",
+ 'CK': "Cook Islands",
+ 'CL': "Chile",
+ 'CM': "Cameroon",
+ 'CN': "China",
+ 'CO': "Colombia",
+ 'CR': "Costa Rica",
+ 'CS': "Serbia and Montenegro",
+ 'CU': "Cuba",
+ 'CY': "Cyprus",
+ 'CZ': "Czech Republic",
+ 'DE': "Germany",
+ 'DJ': "Djibouti",
+ 'DK': "Denmark",
+ 'DO': "Dominican Republic",
+ 'DZ': "Algeria",
+ 'EC': "Ecuador",
+ 'EE': "Estonia",
+ 'EG': "Egypt",
+ 'ER': "Eritrea",
+ 'ES': "Spain",
+ 'ET': "Ethiopia",
+ 'EU': "European Union",
+ 'FI': "Finland",
+ 'FJ': "Fiji",
+ 'FM': "Micronesia Federated States of",
+ 'FO': "Faroe Islands",
+ 'FR': "France",
+ 'GA': "Gabon",
+ 'GB': "United Kingdom",
+ 'GD': "Grenada",
+ 'GE': "Georgia",
+ 'GF': "French Guiana",
+ 'GG': "Guernsey",
+ 'GH': "Ghana",
+ 'GI': "Gibraltar",
+ 'GL': "Greenland",
+ 'GM': "Gambia",
+ 'GP': "Guadeloupe",
+ 'GR': "Greece",
+ 'GT': "Guatemala",
+ 'GU': "Guam",
+ 'GW': "Guinea-Bissau",
+ 'GY': "Guyana",
+ 'HK': "Hong Kong",
+ 'HN': "Honduras",
+ 'HR': "Croatia (Local Name: Hrvatska)",
+ 'HT': "Haiti",
+ 'HU': "Hungary",
+ 'ID': "Indonesia",
+ 'IE': "Ireland",
+ 'IL': "Israel",
+ 'IM': "Isle of Man",
+ 'IN': "India",
+ 'IO': "British Indian Ocean Territory",
+ 'IQ': "Iraq",
+ 'IR': "Iran (Islamic Republic of)",
+ 'IS': "Iceland",
+ 'IT': "Italy",
+ 'JE': "Jersey",
+ 'JM': "Jamaica",
+ 'JO': "Jordan",
+ 'JP': "Japan",
+ 'KE': "Kenya",
+ 'KG': "Kyrgyzstan",
+ 'KH': "Cambodia",
+ 'KI': "Kiribati",
+ 'KN': "Saint Kitts and Nevis",
+ 'KR': "Korea Republic of",
+ 'KW': "Kuwait",
+ 'KY': "Cayman Islands",
+ 'KZ': "Kazakhstan",
+ 'LA': "Lao People's Democratic Republic",
+ 'LB': "Lebanon",
+ 'LC': "Saint Lucia",
+ 'LI': "Liechtenstein",
+ 'LK': "Sri Lanka",
+ 'LR': "Liberia",
+ 'LS': "Lesotho",
+ 'LT': "Lithuania",
+ 'LU': "Luxembourg",
+ 'LV': "Latvia",
+ 'LY': "Libyan Arab Jamahiriya",
+ 'MA': "Morocco",
+ 'MC': "Monaco",
+ 'MD': "Moldova Republic of",
+ 'MG': "Madagascar",
+ 'MH': "Marshall Islands",
+ 'MK': "Macedonia the Former Yugoslav Republic of",
+ 'ML': "Mali",
+ 'MM': "Myanmar",
+ 'MN': "Mongolia",
+ 'MO': "Macau",
+ 'MP': "Northern Mariana Islands",
+ 'MR': "Mauritania",
+ 'MS': "Montserrat",
+ 'MT': "Malta",
+ 'MU': "Mauritius",
+ 'MV': "Maldives",
+ 'MW': "Malawi",
+ 'MX': "Mexico",
+ 'MY': "Malaysia",
+ 'MZ': "Mozambique",
+ 'NA': "Namibia",
+ 'NC': "New Caledonia",
+ 'NF': "Norfolk Island",
+ 'NG': "Nigeria",
+ 'NI': "Nicaragua",
+ 'NL': "Netherlands",
+ 'NO': "Norway",
+ 'NP': "Nepal",
+ 'NR': "Nauru",
+ 'NU': "Niue",
+ 'NZ': "New Zealand",
+ 'OM': "Oman",
+ 'PA': "Panama",
+ 'PE': "Peru",
+ 'PF': "French Polynesia",
+ 'PG': "Papua New Guinea",
+ 'PH': "Philippines",
+ 'PK': "Pakistan",
+ 'PL': "Poland",
+ 'PR': "Puerto Rico",
+ 'PS': "Palestinian Territory Occupied",
+ 'PT': "Portugal",
+ 'PW': "Palau",
+ 'PY': "Paraguay",
+ 'QA': "Qatar",
+ 'RO': "Romania",
+ 'RS': "Serbia",
+ 'RU': "Russian Federation",
+ 'RW': "Rwanda",
+ 'SA': "Saudi Arabia",
+ 'SB': "Solomon Islands",
+ 'SC': "Seychelles",
+ 'SD': "Sudan",
+ 'SE': "Sweden",
+ 'SG': "Singapore",
+ 'SI': "Slovenia",
+ 'SK': "Slovakia (Slovak Republic)",
+ 'SL': "Sierra Leone",
+ 'SM': "San Marino",
+ 'SN': "Senegal",
+ 'SR': "Suriname",
+ 'SV': "El Salvador",
+ 'SY': "Syrian Arab Republic",
+ 'SZ': "Swaziland",
+ 'TC': "Turks and Caicos Islands",
+ 'TG': "Togo",
+ 'TH': "Thailand",
+ 'TJ': "Tajikistan",
+ 'TM': "Turkmenistan",
+ 'TN': "Tunisia",
+ 'TO': "Tonga",
+ 'TR': "Turkey",
+ 'TT': "Trinidad and Tobago",
+ 'TV': "Tuvalu",
+ 'TW': "Taiwan Province of China",
+ 'TZ': "Tanzania United Republic of",
+ 'UA': "Ukraine",
+ 'UG': "Uganda",
+ 'US': "United States",
+ 'UY': "Uruguay",
+ 'UZ': "Uzbekistan",
+ 'VA': "Holy See (Vatican City State)",
+ 'VE': "Venezuela",
+ 'VG': "Virgin Islands (British)",
+ 'VI': "Virgin Islands (U.S.)",
+ 'VN': "Viet Nam",
+ 'VU': "Vanuatu",
+ 'WF': "Wallis and Futuna Islands",
+ 'WS': "Samoa",
+ 'YE': "Yemen",
+ 'ZA': "South Africa",
+ 'ZM': "Zambia",
+ 'ZW': "Zimbabwe",
+ 'ZZ': "Reserved"
+},
+
+'browsers': {
+ 'UNKNOWN': "Unknown",
+ 'MSIE': "Internet Explorer",
+ 'FIREFOX': "Firefox",
+ 'OPERA': "Opera",
+ 'SAFARI': "Safari",
+ 'OMNIWEB': "OmniWeb",
+ 'CAMINO': "Camino",
+ 'CHROME': "Chrome"
+},
+
+'operatingSystems': {
+ 'UNKNOWN': "Unknown",
+ 'WINDOWS': "Windows",
+ 'MAC': "Mac",
+ 'LINUX': "Linux",
+ 'IPHONE': "iPhone",
+ 'MOBILE': "Mobile",
+ 'OPENBSD': "OpenBSD",
+ 'FREEBSD': "FreeBSD",
+ 'NETBSD': "NetBSD"
+},
+*/
+
+// Calendar texts
+'calendarStrings': {
+ 'months': {
+ '0': "January",
+ '1': "February",
+ '2': "March",
+ '3': "April",
+ '4': "May",
+ '5': "June",
+ '6': "July",
+ '7': "August",
+ '8': "September",
+ '9': "October",
+ '10': "November",
+ '11': "December"
+ },
+ 'shortMonths': {
+ '0': "Jan",
+ '1': "Feb",
+ '2': "Mar",
+ '3': "Apr",
+ '4': "May",
+ '5': "Jun",
+ '6': "Jul",
+ '7': "Aug",
+ '8': "Sep",
+ '9': "Oct",
+ '10': "Nov",
+ '11': "Dec"
+ },
+
+ 'days': {
+ '0': "Sunday",
+ '1': "Monday",
+ '2': "Tuesday",
+ '3': "Wednesday",
+ '4': "Thursday",
+ '5': "Friday",
+ '6': "Saturday"
+ },
+
+ 'shortDays': {
+ '0': "Sun",
+ '1': "Mon",
+ '2': "Tue",
+ '3': "Wed",
+ '4': "Thu",
+ '5': "Fri",
+ '6': "Sat"
+ },
+
+ 'veryShortDays': {
+ '0': "Su",
+ '1': "Mo",
+ '2': "Tu",
+ '3': "We",
+ '4': "Th",
+ '5': "Fr",
+ '6': "Sa"
+ },
+
+ 'amDesignation': "am",
+ 'pmDesignation': "pm"
+
+},
+
+// Date format
+'fullDate_format': "l, F d, Y H:i:s",
+
+//################################################################################
+
+'pageHeader': {
+ 'donation': "donate",
+ 'forum': "forum",
+ 'credits': "credits",
+ 'feedback': "feedback",
+ 'help': "help"
+},
+
+'bookmarkletCopy': {
+ 'noExceptionMessage': "The direct login configuration has been collected.",
+ 'exceptionMessage': "Sorry! There was an error while processing the page.",
+ 'copy': "copy",
+ 'successfulMessage': "DONE!",
+ 'failMessage': "Failed! :("
+},
+
+//################################################################################
+
+__syntaxFix__: "syntax fix"
+}
diff --git a/frontend/gamma/js/Clipperz/PM/Strings/Strings_en-US.js b/frontend/gamma/js/Clipperz/PM/Strings/Strings_en-US.js
new file mode 100644
index 0000000..eebdb16
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/Strings/Strings_en-US.js
@@ -0,0 +1,1341 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//=============================================================================
+//
+// E N G L I S H A M E R I C A N ( en_US )
+//
+//=============================================================================
+
+Clipperz.PM.Strings.Languages['en-us'] = {
+/*
+// Login page - description
+'clipperzServiceDescription': "\
+ <!-- FIX CSS DONE --> \
+ <h2>Keep it to yourself!</h2>\
+ <ul>\
+ <li>\
+ <h3>Clipperz is:</h3>\
+ <ul>\
+ <li><p>a secure and simple password manager</p></li>\
+ <li><p>an effective single sign-on solution</p></li>\
+ <li><p>a digital vault for your personal data</p></li>\
+ </ul>\
+ </li>\
+ <li>\
+ <h3>With Clipperz you can:</h3>\
+ <ul>\
+ <li><p>store and manage your passwords and online credentials</p></li>\
+ <li><p>login to your web services without entering any username or password</p></li>\
+ <li><p>protect all your sensitive data: codes for burglar alarms, PINs, credit card numbers, …</p></li>\
+ <li><p>share secrets with family members and associates (coming soon)</p></li>\
+ </ul>\
+ </li>\
+ <li>\
+ <h3>Clipperz benefits:</h3>\
+ <ul>\
+ <li><p>free and completely anonymous</p></li>\
+ <li><p>access it any time from any computer</p></li>\
+ <li><p>no software to download and nothing to install</p></li>\
+ <li><p>avoid keeping secrets on your PC or on paper</p></li>\
+ </ul>\
+ </li>\
+ <li>\
+ <h3>Clipperz security:</h3>\
+ <ul>\
+ <li><p>your secrets are locally encrypted by your browser before being uploaded to Clipperz</p></li>\
+ <li><p>the encryption key is a passphrase known only to you</p></li>\
+ <li><p>Clipperz hosts your sensitive data in encrypted form and could never actually access the data in its plain form</p></li>\
+ <li><p>Clipperz is built upon standard encryption schemes, nothing fancies or homemade</p></li>\
+ <li><p>you can review the source code anytime you like, but you need to know nothing about cryptography to be an happy user!</p></li>\
+ </ul>\
+ </li>\
+ <li>\
+ <a href=\"http://www.clipperz.com\" target=\"_blank\">Learn more</a>\
+ </li>\
+ </ul>",
+
+
+'loginFormTitle': "login with your Clipperz account",
+'loginFormUsernameLabel': "username",
+'loginFormPassphraseLabel': "passphrase",
+'loginFormDontHaveAnAccountLabel': "don\'t have an account?",
+'loginFormCreateOneLabel': "create one",
+'loginFormForgotYourCredentialsLabel': "forgot your credentials?",
+'loginFormAarghThatsBadLabel': "aargh! that\'s bad!",
+'loginFormAfraidOfMaliciousScriptsLabel': "afraid of malicious scripts?",
+'loginFormVerifyTheCodeLabel': "verify the code",
+'loginFormButtonLabel': "Login",
+'loginFormOneTimePasswordCheckboxLabel': "use a one-time passphrase",
+'loginFormOneTimePasswordCheckboxDescription': "",
+
+// Login page - language selection
+'loginPanelSwithLanguageDescription': "<h5>Switch to your preferred language</h5>",
+
+// Login page - browser compatibility
+'browserCompatibilityDescription': "<p>Have a better and safer Clipperz experience with Firefox. However Clipperz works just fine also with Opera, Safari and MS Internet Explorer!</p>",
+
+// Login with OTP - message panel
+'OTPloginMessagePanelInitialTitle': "Logging in using a one-time passphrase",
+'OTPloginMessagePanelInitialText': "Sending OTP credentials …",
+'OTPloginMessagePanelLoadingTitle': "Logging in using a one-time passphrase",
+'OTPloginMessagePanelLoadingText': "Fetching encrypted authentication data from the server …",
+'OTPloginMessagePanelProcessingTitle': "Logging in using a one-time passphrase",
+'OTPloginMessagePanelProcessingText': "Local decryption of authentication data",
+
+// Regular login - message panel
+'loginMessagePanelInitialTitle': "Logging in …",
+'loginMessagePanelInitialText': "---",
+'loginMessagePanelInitialButtonLabel': "Cancel",
+'loginMessagePanelConnectedTitle': "Connected",
+'loginMessagePanelConnectedText': "Done",
+'loginMessagePanelFailureTitle': "Error",
+'loginMessagePanelFailureText': "Login failed",
+'loginMessagePanelFailureButtonLabel': "Close",
+
+// Regular login - message panel - connection
+'connectionLoginSendingCredentialsMessageTitle': "Verifying credentials",
+'connectionLoginSendingCredentialsMessageText': "Sending credentials",
+'connectionLoginCredentialsVerificationMessageTitle': "Verifying credentials",
+'connectionLoginCredentialsVerificationMessageText': "Performing SRP authentication",
+'connectionLoginDoneMessageTitle': "Verifying credentials",
+'connectionLoginDoneMessageText': "Connected",
+
+// Regular login - message panel - user
+'userLoginPanelUpgradingUserCredentialsMessageTitle': "Verifying credentials",
+'userLoginPanelUpgradingUserCredentialsMessageText': "Upgrading your credentials to a new authentication schema",
+'userLoginPanelConnectedMessageTitle': "User authenticated",
+'userLoginPanelConnectedMessageText': "Successfully logged in",
+'userLoginPanelTryingAnOlderConnectionSchemaMessageTitle': "Verifying credentials",
+'userLoginPanelTryingAnOlderConnectionSchemaMessageText': "Trying an older authentication schema",
+'userLoginPanelLoadingUserDataMessageTitle': "User authenticated",
+'userLoginPanelLoadingUserDataMessageText': "Downloading encrypted card headers from Clipperz",
+'userLoginPanelDecryptingUserDataMessageTitle': "User authenticated",
+'userLoginPanelDecryptingUserDataMessageText': "Local decryption of card headers",
+'userLoginPanelDecryptingUserStatisticsMessageTitle': "User authenticated",
+'userLoginPanelDecryptingUserStatisticsMessageText': "Local decryption of usage statistics",
+
+// Registration page - splash alert
+'splashAlertTitle': "Welcome to Clipperz!",
+'splashAlertText': "\
+ <!-- FIX CSS DONE! --> \
+ <p>Some security advice</p>\
+ <ul>\
+ <li><p>Storing your data at Clipperz is as secure as the passphrase you choose to protect them. Nobody can access them unless they know your passphrase.</p></li>\
+ <li><p>If you are going to use Clipperz for safeguarding sensitive and critical information please make sure to use a strong passphrase. The longer the better!</p></li>\
+ <li><p>Clipperz will not be able to recover a lost passphrase!</p></li>\
+ </ul>\
+ <p>For any further information, please refer to <a href=\"http://www.clipperz.com\" target=\"_blank\">Clipperz</a> website.</p>",
+'splashAlertCloseButtonLabel': "Ok",
+
+// Registration page - form
+'registrationFormTitle': "create your account",
+'registrationFormUsernameLabel': "username",
+'registrationFormPassphraseLabel': "passphrase",
+'registrationFormRetypePassphraseLabel': "re-enter passphrase",
+'registrationFormSafetyCheckLabel': "I understand that Clipperz will not be able to recover a lost passphrase.",
+'registrationFormTermsOfServiceCheckLabel': "I have read and agreed to the <a href='http://www.clipperz.com/terms_of_service' target='_blank'>Terms of Service</a>.",
+'registrationFormDoYouAlreadyHaveAnAccountLabel': "do you already have an account?",
+'registrationFormSimplyLoginLabel': "simply login",
+'registrationFormButtonLabel': "Register",
+
+// Registration page - warning messages
+'registrationFormWarningMessageNotMatchingPassphrases': "Your passphrases don't match, please re-type them.",
+'registrationFormWarningMessageSafetyCheckNotSelected': "Please read and check all the boxes below.",
+'registrationFormWarningMessageTermsOfServiceCheckNotSelected': "You need to agree to the Terms of Service.",
+
+// Registration page - message panel
+'registrationMessagePanelInitialTitle': "Creating account …",
+'registrationMessagePanelInitialText': "---",
+'registrationMessagePanelInitialButtonLabel': "Cancel",
+'registrationMessagePanelRegistrationDoneTitle': "Registration",
+'registrationMessagePanelRegistrationDoneText': "Done",
+'registrationMessagePanelFailureTitle': "Registration failed",
+'registrationMessagePanelFailureButtonLabel': "Close",
+
+// Registration page - message panel - connection
+'connectionRegistrationSendingRequestMessageText': "Verifying credentials",
+'connectionRegistrationSendingCredentialsMessageText': "Sending credentials",
+
+// Registration page - splash panel
+'registrationSplashPanelTitle': "Security advice",
+'registrationSplashPanelDescription': "<p>These are your Clipperz credentials, take good care of them. Clipperz will never display your username and passphrase a second time!</p>",
+'registrationSplashPanelUsernameLabel': "username",
+'registrationSplashPanelPassphraseLabel': "passphrase",
+
+'registrationSplashPanelShowPassphraseButtonLabel': "show passphrase",
+
+// Header links
+'donateHeaderLinkLabel': "donate",
+'creditsHeaderLinkLabel': "credits",
+'feedbackHeaderLinkLabel': "feedback",
+'helpHeaderLinkLabel': "help",
+'forumHeaderLinkLabel': "forum",
+
+// Menu labels
+'recordMenuLabel': "cards",
+'accountMenuLabel': "account",
+'dataMenuLabel': "data",
+'contactsMenuLabel': "contacts",
+'toolsMenuLabel': "tools",
+'logoutMenuLabel': "logout",
+'lockMenuLabel': "lock",
+
+// Lock dialog
+'lockTitle': "The account is locked",
+'lockDescription': "<p>To unlock your account, please enter your passphrase.</p>",
+'unlockButtonLabel': "Unlock",
+
+// Account panel - change passphrase
+'changePasswordTabLabel': "Change your passphrase",
+'changePasswordTabTitle': "Change your passphrase",
+
+'changePasswordFormUsernameLabel': "username",
+'changePasswordFormOldPassphraseLabel': "old passphrase",
+'changePasswordFormNewPassphraseLabel': "new passphrase",
+'changePasswordFormRetypePassphraseLabel': "re-enter new passphrase",
+'changePasswordFormSafetyCheckboxLabel': "I understand that Clipperz will not be able to recover a lost passphrase.",
+'changePasswordFormSubmitLabel': "Change passphrase",
+
+// Account panel - change passphrase - warning messages
+'changePasswordFormWrongUsernameWarning': "Wrong username",
+'changePasswordFormWrongPassphraseWarning': "Wrong passphrase",
+'changePasswordFormWrongRetypePassphraseWarning': "Your passphrases don't match, please re-type them.",
+'changePasswordFormSafetyCheckWarning': "Please read and check the box below.",
+
+// Account panel - change passphrase - progress dialog
+'changePasswordFormProgressDialogTitle': "Changing user credentials",
+'changePasswordFormProgressDialogEmptyText': "---",
+'changePasswordFormProgressDialogConnectedMessageTitle': "Connected",
+'changePasswordFormProgressDialogConnectedMessageText': "Done",
+'changePasswordFormProgressDialogErrorMessageTitle': "Error",
+'changePasswordFormProgressDialogErrorMessageText': "Credentials change failed!",
+
+'changeCredentialsPanelEncryptingDataMessageTitle': "Changing your passphrase",
+'changeCredentialsPanelEncryptingDataMessageText': "Local encryption of card headers",
+'changeCredentialsPanelCreatingNewCredentialsMessageTitle': "Changing your passphrase",
+'changeCredentialsPanelCreatingNewCredentialsMessageText': "Updating your credentials",
+'changeCredentialsPanelSendingNewCredentialsToTheServerMessageTitle': "Changing your passphrase",
+'changeCredentialsPanelSendingNewCredentialsToTheServerMessageText': "Uploading your encrypted credentials to Clipperz",
+'changeCredentialsPanelDoneMessageTitle': "Changing your passphrase",
+'changeCredentialsPanelDoneMessageText': "Done",
+
+// Account panel - OTP
+'manageOTPTabLabel': "Manage your one-time passphrases",
+'manageOTPTabTitle': "Manage your one-time passphrases",
+
+'manageOTPTabDescription': "\
+ <p>A one-time passphrase works like your regular passphrase, but can be used only once.</p>\
+ <p>If the same passphrase is used again at a later stage in a login attempt it will be rejected and the login process will fail.</p>\
+ <p>Immediately after a successful login, your one-time passphrase will be deleted preventing any fraudulent access.</p>\
+ <p>One-time passphrases are an excellent choice if one is concerned about keyloggers or spyware infections that may be collecting data from compromised machines.</p>\
+ <p><b>It's strongly advisable to use one-time passphrases when accessing Clipperz from public terminals, such as Internet cafes and libraries.</b></p>",
+
+// Account panel - OTP - OTP table
+'oneTimePasswordReadOnlyMessage': "\
+ <h6>Sorry!</h6>\
+ <p>You cannot manage your one-time passphrases when using the offline version of Clipperz.</p>",
+
+'oneTimePasswordLoadingMessage': "\
+ <h6>Loading data</h6>\
+ <p>Please wait …</p>",
+
+'oneTimePasswordNoPasswordAvailable': "\
+ <h6>No one-time passphrase available</h6>\
+ <p>Click the “New” button above to add one-time passphrases to your account.</p>",
+
+'createNewOTPButtonLabel': "New",
+'deleteOTPButtonLabel': "Delete",
+'printOTPButtonLabel': "Print",
+
+'disabledOneTimePassword_warning': "disabled",
+
+'oneTimePasswordSelectionLink_selectLabel': "Select:",
+'oneTimePasswordSelectionLink_all': "all",
+'oneTimePasswordSelectionLink_none': "none",
+'oneTimePasswordSelectionLink_used': "used",
+'oneTimePasswordSelectionLink_unused': "unused",
+
+//Account panel - OTP - saving new OTP dialog
+'saveOTP_encryptUserDataTitle': "Saving one-time passphrase",
+'saveOTP_encryptUserDataText': "Processing new OTP credentials …",
+'saveOTP_encryptOTPDataTitle': "Saving one-time passphrase",
+'saveOTP_encryptOTPDataText': "Local encryption of authentication data …",
+'saveOTP_sendingDataTitle': "Saving one-time passphrase",
+'saveOTP_sendingDataText': "Sending authentication data to the server …",
+'saveOTP_updatingInterfaceTitle': "Saving one-time passphrase",
+'saveOTP_updatingInterfaceText': "Updating interface",
+
+// Account panel - preferences
+'accountPreferencesLabel': "Preferences",
+'accountPreferencesTabTitle': "Preferences",
+
+'accountPreferencesLanguageTitle': "Language",
+'accountPreferencesLanguageDescription': "<p>Choose your preferred language from the list below.</p>",
+
+'showDonationReminderPanelTitle': "Donation reminders",
+'showDonationReminderPanelDescription': "<p>Show donation reminders</p>",
+
+'saveUserPreferencesFormSubmitLabel': "Save",
+'cancelUserPreferencesFormSubmitLabel': "Cancel",
+
+// Account panel - preferences - saving dialog
+'accountPreferencesSavingPanelTitle_Step1': "Saving preferences",
+'accountPreferencesSavingPanelText_Step1': "Local encryption of your preferences",
+'accountPreferencesSavingPanelTitle_Step2': "Saving preferences",
+'accountPreferencesSavingPanelText_Step2': "Sending encrypted preferences to Clipperz",
+
+// Account panel - login history
+'accountLoginHistoryLabel': "Login history",
+'loginHistoryTabTitle': "Login history",
+
+'loginHistoryReadOnlyMessage': "\
+ <h6>Sorry!</h6>\
+ <p>The login history is not available while using the offline version of Clipperz.</p>",
+
+'loginHistoryLoadingMessage': "\
+ <h6>Loading data</h6>\
+ <p>Please wait …</p>",
+
+'loginHistoryLoadedMessage': "\
+ <h6>Your latest 10 logins</h6>\
+ <p></p>",
+
+'loginHistoryIPLabel': "IP",
+'loginHistoryTimeLabel': "date",
+'loginHistoryCurrentSessionText': "current session",
+'loginHistoryReloadButtonLabel': "Reload login history",
+
+// Account panel - delete account
+'deleteAccountTabLabel': "Delete your account",
+'deleteAccountTabTitle': "Delete your account",
+
+'deleteAccountFormUsernameLabel': "username",
+'deleteAccountFormPassphraseLabel': "passphrase",
+'deleteAccountFormSafetyCheckboxLabel': "I understand that all my data will be deleted and that this action is irreversible.",
+'deleteAccountFormSubmitLabel': "Delete my account",
+
+//Account panel - delete account - warnings
+'deleteAccountFormWrongUsernameWarning': "Wrong username",
+'deleteAccountFormWrongPassphraseWarning': "Wrong passphrase",
+'deleteAccountFormSafetyCheckWarning': "Please read and check the box below.",
+
+//Account panel - delete account - confirmation
+'accountPanelDeletingAccountPanelConfirmationTitle': "ATTENTION",
+'accountPanelDeleteAccountPanelConfirmationText': "Are your sure you want to delete your account?",
+'accountPanelDeleteAccountPanelConfirmButtonLabel': "Yes",
+'accountPanelDeleteAccountPanelDenyButtonLabel': "No",
+
+//Account panel - delete account - confirmation
+'accountPanelDeletingAccountPanelProgressTitle': "Deleting the account data",
+'accountPanelDeletingAccountPanelProgressText': "The operation could take long, please be patient.",
+
+//Data panel - offline copy
+'offlineCopyTabLabel': "Offline copy",
+'offlineCopyTabTitle': "Offline copy",
+
+'offlineCopyTabDescription': "\
+ <!-- FIX CSS DONE! --> \
+ <p>With just one click you can dump all your encrypted data from Clipperz servers to your hard disk and create a read-only offline version of Clipperz to be used when you are not connected to the Internet.</p>\
+ <p>The read-only version is as secure as the read-and-write one and will not expose your data to higher risks since they both share the same code and security architecture.</p>\
+ <ol>\
+ <li><p>Click the link below to start the download.</p></li>\
+ <li><p>The browser will ask you what to do with the “Clipperz_YYYYMMDD.html” file. Save it on your hard disk.</p></li>\
+ <li><p>Double click on the downloaded file to launch the offline version in your browser.</p></li>\
+ <li><p>Enter the usual username and passphrase.</p></li>\
+ </ol>",
+
+'offlineCopyDownloadLinkLabel': "Download",
+
+// Data panel - offline copy - not updated
+'offlineCopyDownloadWarning': "\
+ <!-- FIX CSS DONE! --> \
+ <h4><a href=\"#\" id=\"offlineCopyDownloadWarningLink\">Update your “offline copy”!</a></h4>\
+ <p>You have recently created or modified one or more cards, it would be wise to download a new copy of the offline version.</p>",
+
+'offlineCopyDownloadOk': "",
+
+// Data panel - sharing
+'sharingTabLabel': "Sharing",
+'sharingTabTitle': "Sharing",
+
+'sharingTabDescription': "\
+ <p>Quite often a confidential piece of information needs to be shared with one or more persons.</p>\
+ <p>This could be as simple as giving your colleague the access code of your voice mailbox when you are out of the office, or as complicated as enabling the entitled heirs to access your safe deposit box at the local bank when you pass on.</p>\
+ <p>Clipperz can make sharing your secrets a secure and straightforward process.</p>\
+ <p></p>\
+ <p><b>Coming soon …</b></p>",
+
+// Data panel - import
+'importTabLabel': "Import",
+'importTabTitle': "Import",
+
+'importTabDescription': "<p>You can bulk import data to your Clipperz account from several file formats.</p>",
+
+// Data panel - export
+'printingTabLabel': "Export",
+'printingTabTitle': "Export",
+
+'printingTabDescription': "\
+ <h5>Printing</h5>\
+ <p>Click on the link below to open a new window displaying all your cards in a printable format.</p>\
+ <p>If you are going to print for backup purposes, please consider the safer option provided by the “offline copy”.</p>",
+
+'printingLinkLabel': "Printable version",
+
+'exportTabDescription': "\
+ <h5>Exporting to JSON</h5>\
+ <p>JSON enables a “lossless” export of your cards. All the information will be preserved, including direct login configurations.</p>\
+ <p>This custom format it’s quite convenient if you need to move some of all of your cards to a different Clipperz account. Or if you want to restore a card that has been accidentally deleted.</p>\
+ <p>Click on the link below to start the export process.</p>",
+
+'exportLinkLabel': "Export to JSON",
+
+'exportDataInProgressDescription': "<h4>Exporting, please wait while your data are being processed …</h4>",
+
+'exportDataDescription': "\
+ <h4>Instructions</h4>\
+ <p>Copy the text below to your favorite editor and save it. (e.g. “clipperz_export_20071217.json”)</p>",
+
+// Contacts panel
+'contactsTabLabel': "Contacts",
+'contactsTabTitle': "Contacts",
+
+//Tools panel - password generator
+'passwordGeneratorTabLabel': "Password generator",
+'bookmarkletTabLabel': "Bookmarklet",
+'compactTabLabel': "Compact edition",
+'httpAuthTabLabel': "HTTP authentication",
+
+'passwordGeneratorTabTitle': "Password generator",
+'bookmarkletTabTitle': "Bookmarklet",
+'compactTabTitle': "Compact edition",
+'httpAuthTabTitle': "HTTP authentication",
+
+
+// Tools panel - password generator - description
+'paswordGeneratorTabDescription': "<p></p>",
+'passwordGeneratorTabButtonLabel': "Generate password",
+
+// Tools panel - bookmarklet
+'bookmarkletTabLabel': "Bookmarklet",
+'bookmarkletTabTitle': "Bookmarklet",
+
+'bookmarkletTabDescription': "\
+ <!-- FIX CSS DONE! --> \
+ <p>A bookmarklet is a simple “one-click” tool that can perform very useful tasks. It can be saved and used like a normal web page bookmark.</p>\
+ <p>The Clipperz bookmarklet will help you to quickly create new cards and new “direct logins” within existing cards.</p>\
+ <p><b>Please note that the bookmarklet does not include any information related to your account (e.g. your username or passphrase), the bookmarklet is a general tool containing the same code for every Clipperz user.</b></p>\
+ <h3>How to install the bookmarklet</h3>\
+ <h>Firefox, Camino, Opera, Safari</h5>\
+ <ol>\
+ <li><p>Make sure that the “Bookmarks Bar” is displayed by selecting “View > Toolbars > Bookmarks”, or similar menu items, from the browser menu.</p></li>\
+ <li><p>Drag and drop the “Add to Clipperz” link below to the bookmark bar.</p></li>\
+ </ol>\
+ \
+ <h5>Internet Explorer</h5>\
+ <ol>\
+ <li><p>Make sure that the “Links” toolbar is displayed by selecting “View > Toolbars > Links” from the browser menu.</p></li>\
+ <li><p>Right-click on the “Add to Clipperz” link below.</p></li>\
+ <li><p>Select “Add to favorites” from the contextual menu.</p></li>\
+ <li><p>Click “Yes” for any security message that pops up.</p></li>\
+ <li><p>Open the “Links” folder and click “OK”</p></li>\
+ </ol>",
+
+'bookmarkletTabBookmarkletTitle': "Add to Clipperz",
+
+// Tools panel - bookmarklet - instructions
+'bookmarkletTabInstructions': "\
+ <!-- FIX CSS DONE! --> \
+ <h3>How to create a new card inclusive of a “direct login” link to an online service</h3>\
+ <ol>\
+ <li><p>Open the web page where the login form is hosted. (this is the page where you usually enter your sign-in credentials)</p></li>\
+ <li><p>Launch the bookmarklet by clicking on it: a pop-up window will appear over the web page.</p></li>\
+ <li><p>Copy to the clipboard the content of the large text area within the pop-up. (ctrl-C)</p></li>\
+ <li><p>Enter your Clipperz account and click on the <b>Add new card</b> button.</p></li>\
+ <li><p>Select the “Direct login” template and paste the content of the clipboard to the large text area in the form. (ctrl-V)</p></li>\
+ <li><p>Press the <b>Create</b> button, complete and review the details, then click <b>Save</b>.</p></li>\
+ </ol>\
+ \
+ <h3>How to add a “direct login” link to an existing card</h3>\
+ <ol>\
+ <li><p>Same as above.</p></li>\
+ <li><p>Same as above.</p></li>\
+ <li><p>Same as above.</p></li>\
+ <li><p>Enter your Clipperz account and select the card containing the credentials for the web service you just visited and click the <b>Edit</b> button.</p></li>\
+ <li><p>Paste the content of the clipboard to the large text area in the “Direct logins” section. (ctrl-V)</p></li>\
+ <li><p>Press the <b>Add direct login</b> button, review the details and then click <b>Save</b>.</p></li>\
+ </ol>\
+ \
+ <p></p>\
+ <p>Further information about the bookmarklet are <a href=\"http://www.clipperz.com/support/user_guide/bookmarklet\" target=\"_blank\">available here</a>.</p>",
+
+// Tools panel - Compact - instructions
+'compactTabDescription': "\
+ <!-- FIX CSS DONE! --> \
+ <p>Clipperz Compact is a special version of Clipperz designed to be opened in the Firefox sidebar.</p>\
+ <p>Its purpose is to keep your collection of “direct logins” always at hand. Read more <a href=\"http://www.clipperz.com/support/user_guide/clipperz_compact\", target=\"blank\">here</a></p>\
+ \
+ <h3>How to launch Clipperz Compact in the sidebar</h3>\
+ <ol>\
+ <li><p>Get Firefox! Sidebars are only available in Firefox and you need to switch to Firefox in order to enjoy the convenience of Clipperz Compact.</p></li>\
+ <li>\
+ <p>Add the following URL to Firefox bookmarks, or even better, drag it to the bookmark bar.</p>\
+ <div id=\"compactLinkBox\"><a href=\"https://www.clipperz.com/beta/index.html?compact\" target=\"_search\">Clipperz Compact</a></div>\
+ </li>\
+ <li><p>Change the properties of the bookmark so that “load this bookmark in the sidebar” is checked.</p></li>\
+ </ol>\
+ \
+ <h5>Added bonus: Clipperz Compact works also in Opera’s panel.</h5>",
+
+// Tools panel - HTTP authentication - instructions
+'httpAuthTabDescription': "\
+ <!-- FIX CSS DONE! --> \
+ <p>HTTP authentication is a method designed to allow a web browser to provide credentials – in the form of a username and password – including them in a website address (HTTP or HTTPS URL).</p>\
+ <p>Nowadays it is rarely used, but it can still be found on small, private websites. You can tell that a website is protected by HTTP authentication when the browser displays a pop-up window to enter username and password.</p>\
+ <p>Unfortunately the Clipperz bookmarklet does not work on websites that use HTTP authentication. However you can still create a “direct login”.</p>\
+ \
+ <h3>How to create a “direct login” for a website that uses HTTP authentication</h3>\
+ <ol>\
+ <li><p>Store website URL, username and password in a new card.</p></li>\
+ <li><p>Copy the configuration below and paste it to the large text area in the “Direct logins” section of the new card.</p></li>\
+ <li><p>Press the <b>Add direct login</b> button, bind URL, username and password fields and then click <b>Save</b>.</p></li>\
+ </ol>\
+ \
+ <h5><a href=\"http://support.microsoft.com/kb/834489\" target=\"_blank\">Warning: Internet Explorer does not support HTTP authentication.</a></h5>",
+
+// Direct logins block
+'mainPanelDirectLoginBlockLabel': "Direct logins",
+'directLinkReferenceShowButtonLabel': "show",
+
+// Direct logins - blank slate
+'mainPanelDirectLoginBlockDescription': "\
+ <!-- FIX CSS DONE! --> \
+ <p>Add “direct logins” to sign in to your web accounts without typing usernames and passwords!</p>\
+ <p>“Direct logins” greatly enhance your password security since you can:</p>\
+ <ul>\
+ <li><p>conveniently adopt and enter complex passwords;</p></li>\
+ <li><p>never re-use the same and easy-to-guess password.</p></li>\
+ </ul>\
+ <p>Simple and quick configuration with the <b>Clipperz bookmarklet</b>.</p>\
+ <a href=\"http://www.clipperz.com/support/user_guide/direct_logins\" target=\"_blank\">Learn more about “direct logins”</a>",
+
+// Cards block
+'mainPanelRecordsBlockLabel': "Cards",
+'mainPanelAddRecordButtonLabel': "Add new card",
+'mainPanelRemoveRecordButtonLabel': "Delete card",
+
+// Cards block - filter tabs
+'mainPanelRecordFilterBlockAllLabel': "all",
+'mainPanelRecordFilterBlockTagsLabel': "tags",
+'mainPanelRecordFilterBlockSearchLabel': "search",
+
+// Cards block - blank slate
+'recordDetailNoRecordAtAllTitle': "Welcome to Clipperz!",
+'recordDetailNoRecordAtAllDescription': "\
+ <h5>Get started by adding cards to your account.</h5>\
+ <p>Cards are simple and flexible forms where you can store your passwords and any other confidential data.</p>\
+ <p>Cards could contain credentials for accessing a web site, the combination of your bicycle lock, details of your credit card, …</p>\
+ \
+ <h5>Don't forget the Clipperz bookmarklet!</h5>\
+ <p>Before you start, install the “Add to Clipperz” bookmarklet: it will make creating cards easier and more fun.</p>\
+ <p>Go to the “Tools” tab to discover how to install it and how it use it.</p>\
+ <p></p>\
+ <p>Then simply click the <b>\"Add new card\"</b> button and enjoy your Clipperz account.</p>\
+ <p></p>\
+ <a href=\"http://www.clipperz.com/support/user_guide/managing_cards\" target=\"_blank\">Learn more about creating and managing cards</a>",
+
+// Cards block - new card wizard - bookmarklet configuration
+'newRecordWizardTitleBox': "\
+ <h5>Please select a template</h5>\
+ <p>Cards are simple and flexible forms where you can store passwords or any other confidential data.</p>\
+ <p>Start choosing one of the templates below. You can always customize your cards later by adding or removing fields.</p>",
+
+'newRecordWizardBookmarkletConfigurationTitle': "Direct login",
+'newRecordWizardBookmarkletConfigurationDescription': "\
+ <p>Paste below the configuration code generated by the Clipperz bookmarklet.</p>\
+ <p>A new card complete with a direct login to your web account will be created.</p>",
+
+'newRecordWizardCreateButtonLabel': "Create",
+'newRecordWizardCancelButtonLabel': "Cancel",
+
+// Create new card - Donation splash
+'donateSplashPanelTitle': "Support Clipperz, make a donation today!",
+'donateSplashPanelDescription': "\
+ <!-- FIX CSS DONE! --> \
+ <p>A few good reasons to make a donation:</p>\
+ <ul>\
+ <li><p>support the development of new features</p></li>\
+ <li><p>keep Clipperz free</p></li>\
+ <li><p>show appreciation for our hard work</p></li>\
+ </ul>\
+ <p>For any further information, please visit our <a href=\"http://www.clipperz.com/donations\" target=\"_blank\">Donations page</a>.</p>\
+ <p><b>Ready to donate?</b></p>",
+
+'donateCloseButtonLabel': "Not yet",
+'donateDonateButtonLabel': "Yes",
+
+// Card templates
+'recordTemplates': {
+
+//Web password
+ 'WebAccount': {
+ 'title': "Web password",
+ 'description': "<p>A simple card to store login credentials for your online services.</p>",
+ 'fields': [
+ {label:"Web address", type:'URL'},
+ {label:"Username or email", type:'TXT'},
+ {label:"Password", type:'PWD'}
+ ]
+ },
+
+//Bank account
+ 'BankAccount': {
+ 'title': "Bank account",
+ 'description': "<p>Safely store your bank account number and online banking credentials.</p>",
+ 'fields': [
+ {label:"Bank", type:'TXT'},
+ {label:"Account number", type:'TXT'},
+ {label:"Bank website", type:'URL'},
+ {label:"Online banking ID", type:'TXT'},
+ {label:"Online banking password", type:'PWD'}
+ ]
+ },
+
+// Credit card
+ 'CreditCard': {
+ 'title': "Credit card",
+ 'description': "<p>Card number, expire date, CVV2 and PIN always at hand with Clipperz.</p>",
+ 'fields': [
+ {label:"Type (Visa, AmEx, …)", type:'TXT'},
+ {label:"Number", type:'TXT'},
+ {label:"Owner name", type:'TXT'},
+ {label:"Expiry date", type:'TXT'},
+ {label:"CVV2", type:'TXT'},
+ {label:"PIN", type:'PWD'},
+ {label:"Card website", type:'URL'},
+ {label:"Username", type:'TXT'},
+ {label:"Password", type:'PWD'}
+ ]
+ },
+
+// Address book entry
+ 'AddressBookEntry': {
+ 'title': "Address book entry",
+ 'description': "<p>Clipperz could also work as your new private address book. Use this template to easily add a new entry.</p>",
+ 'fields': [
+ {label:"Name", type:'TXT'},
+ {label:"Email", type:'TXT'},
+ {label:"Phone", type:'TXT'},
+ {label:"Mobile", type:'TXT'},
+ {label:"Address", type:'ADDR'}
+ ]
+ },
+
+//Custom card
+ 'Custom': {
+ 'title': "Custom card",
+ 'description': "<p>No matter which kind of confidential data you need to protect, create a custom card to match your needs.</p>",
+ 'fields': [
+ {label:"Label 1", type:'TXT'},
+ {label:"Label 2", type:'TXT'},
+ {label:"Label 3", type:'TXT'}
+ ]
+ }
+},
+
+
+'recordFieldTypologies': {
+ 'TXT': {
+ description: "simple text field",
+ shortDescription: "text"
+ },
+ 'PWD': {
+ description: "simple text field, with default status set to hidden",
+ shortDescription: "password"
+ },
+ 'URL': {
+ description: "simple text field in edit mode, that became an active url in view mode",
+ shortDescription: "web address"
+ },
+ 'DATE': {
+ description: "a value set with a calendar helper",
+ shortDescription: "date"
+ },
+ 'ADDR': {
+ description: "just like the URL, but the active link points to Google Maps (or similar service) passing the address value as argument",
+ shortDescription: "street address"
+ },
+ 'CHECK': {
+ description: "check description",
+ shortDescription: "check"
+ },
+ 'RADIO': {
+ description: "radio description",
+ shortDescription: "radio"
+ },
+ 'SELECT': {
+ description: "select description",
+ shortDescription: "select"
+ }
+},
+
+// Cards block - new card - warnings
+'newRecordPanelGeneralExceptionTitle': "Error",
+'newRecordPanelGeneralExceptionMessage': "The configuration text is not valid. Make sure to get your text from the bookmarklet pop-up and retry.",
+'newRecordPanelWrongBookmarkletVersionExceptionTitle': "Error",
+'newRecordPanelWrongBookmarkletVersionExceptionMessage': "The configuration text has been generated by an old version of the bookmarklet. Please update your bookmarklet and retry.",
+'newRecordPanelExceptionPanelCloseButtonLabel': "Cancel",
+
+// Cards block - delete card
+'mainPanelDeletingRecordPanelConfirmationTitle': "Deleting selected card",
+'mainPanelDeleteRecordPanelConfirmationText': "Do your really want to delete the selected card?",
+'mainPanelDeleteRecordPanelConfirmButtonLabel': "Yes",
+'mainPanelDeleteRecordPanelDenyButtonLabel': "No",
+'mainPanelDeletingRecordPanelInitialTitle': "Deleting selected card",
+'mainPanelDeletingRecordPanelInitialText': "---",
+'mainPanelDeletingRecordPanelCompletedText': "Done",
+
+// Cards block - delete card panel
+'deleteRecordPanelCollectRecordDataMessageTitle': "Delete card",
+'deleteRecordPanelCollectRecordDataMessageText': "Updating card list",
+'deleteRecordPanelEncryptUserDataMessageTitle': "Delete card",
+'deleteRecordPanelEncryptUserDataMessageText': "Local encryption of card headers",
+'deleteRecordPanelSendingDataToTheServerMessageTitle': "Delete card",
+'deleteRecordPanelSendingDataToTheServerMessageText': "Uploading encrypted card headers to Clipperz",
+'deleteRecordPanelUpdatingTheInterfaceMessageTitle': "Delete card",
+'deleteRecordPanelUpdatingTheInterfaceMessageText': "Updating the interface",
+
+// Cards block - no record selected
+'recordDetailNoRecordSelectedTitle': "No card selected",
+'recordDetailNoRecordSelectedDescription': "<p>Please select a card from the list on the left.</p>",
+
+// Cards block - loading messages
+'recordDetailLoadingRecordMessage': "Downloading encrypted card from Clipperz",
+'recordDetailDecryptingRecordMessage': "Local decryption of card\'s data",
+'recordDetailLoadingRecordVersionMessage': "Downloading latest card version",
+'recordDetailDecryptingRecordVersionMessage': "Local decryption of latest version",
+'recordDetailLoadingErrorMessageTitle': "Error while downloading the card",
+
+// Cards block - card details
+'recordDetailNotesLabel': "Notes",
+'recordDetailLabelFieldColumnLabel': "Field label",
+'recordDetailDataFieldColumnLabel': "Field data",
+'recordDetailTypeFieldColumnLabel': "Type",
+
+'recordDetailSavingChangesMessagePanelInitialTitle': "Saving card",
+'recordDetailSavingChangesMessagePanelInitialText': "---",
+
+'recordDetailRemoveFieldButtonLabel': "-",
+'recordDetailAddFieldButtonLabel': "Add new field",
+'recordDetailPasswordFieldHelpLabel': "click the stars to select the password and then Ctrl-C to copy",
+
+'recordDetailPasswordFieldScrambleLabel': "scramble",
+'recordDetailPasswordFieldUnscrambleLabel': "unscramble",
+
+'recordDetailDirectLoginBlockTitle': "Direct logins",
+'recordDetailNewDirectLoginDescription': "<p>Direct login configuration</p>",
+
+'recordDetailDirectLoginBlockNoDirectLoginConfiguredDescription': "\
+ <p>Does this card contain credentials to access an online service?</p>\
+ <p>Use the bookmarklet to configure a “direct login” from Clipperz with just one click!</p>",
+
+'recordDetailDeleteDirectLoginButtonLabel': "-",
+'recordDetailAddNewDirectLoginButtonLabel': "Add new direct login",
+
+'recordDetailEditButtonLabel': "Edit",
+'recordDetailSaveButtonLabel': "Save",
+'recordDetailCancelButtonLabel': "Cancel",
+
+'newRecordTitleLabel': "_new card_",
+'newDirectLoginLabelSuffix': "",
+
+// Cards block - save card panel
+'recordSaveChangesPanelCollectRecordInfoMessageTitle': "Save card",
+'recordSaveChangesPanelCollectRecordInfoMessageText': "Updating card headers",
+'recordSaveChangesPanelEncryptUserDataMessageTitle': "Save card",
+'recordSaveChangesPanelEncryptUserDataMessageText': "Local encryption of card headers",
+'recordSaveChangesPanelEncryptRecordDataMessageTitle': "Save card",
+'recordSaveChangesPanelEncryptRecordDataMessageText': "Local encryption of card's data",
+'recordSaveChangesPanelEncryptRecordVersionDataMessageTitle': "Save card",
+'recordSaveChangesPanelEncryptRecordVersionDataMessageText': "Local encryption of card's version data",
+'recordSaveChangesPanelSendingDataToTheServerMessageTitle': "Save card",
+'recordSaveChangesPanelSendingDataToTheServerMessageText': "Uploading encrypted card's header to Clipperz",
+'recordSaveChangesPanelUpdatingTheInterfaceMessageTitle': "Save card",
+'recordSaveChangesPanelUpdatingTheInterfaceMessageText': "Updating the interface",
+
+// Password Generator strings
+'passwordGeneratorPanelTitle': "Password generator",
+'passwordGeneratorPanelOkLabel': "Ok",
+'passwordGeneratorPanelCancelLabel': "Cancel",
+
+'passwordGeneratorLowercaseLabel': "abc",
+'passwordGeneratorUppercaseLabel': "ABC",
+'passwordGeneratorNumberLabel': "012",
+'passwordGeneratorSymbolLabel': "@#$",
+
+'passwordGeneratorLengthLabel': "length:",
+
+
+//Miscellaneous strings
+
+'comingSoon': "coming soon …",
+'panelCollectingEntryopyMessageText': "Collecting entropy",
+'directLoginConfigurationCheckBoxFieldSelectedValue': "Yes",
+'directLoginConfigurationCheckBoxFieldNotSelectedValue': "No",
+
+
+
+// NEW - Import panel
+'importFormats': {
+ 'CSV': {
+ 'label': "CSV",
+ 'description': "<p>A widely recognized file format that stores tabular data. Several password managers can export data to this format.</p>"
+ },
+ 'Excel': {
+ 'label': "Excel",
+ 'description': "<p>The popular spreadsheet from Microsoft. Storing passwords in Excel files is very common but not advisable.</p>"
+ },
+ 'KeePass': {
+ 'label': "KeePass",
+ 'description': "<p>The custom TXT file created by KeePass password manager.</p>"
+ },
+ 'PasswordPlus': {
+ 'label': "Password Plus",
+ 'description': "<p>The custom CSV format produced by Password Plus, a password manager mostly used on mobile devices.</p>"
+ },
+ 'Roboform': {
+ 'label': "RoboForm",
+ 'description': "<p>The special HTML file created by Roboform password manager when displaying Passcard and Safenotes for printing.</p>"
+ },
+ 'ClipperzExport': {
+ 'label': "JSON",
+ 'description': "<p>The file created by Clipperz itself in JSON format. It preserves all information contained in your cards, even direct login configurations.</p>"
+ }
+},
+
+// JSON
+'Clipperz_ImportWizard_Title': "JSON import",
+'importOptions_clipperz_description': "<p>Open the JSON file exported from Clipperz in a text editor. Then copy and paste its content to the text area below.</p>",
+
+// CSV
+'CSV_ImportWizard_Title': "CSV import",
+'importOptions_csv_description_': "\
+ <p>Open the CSV file in a text editor. Then copy and paste its content to the text area below.</p>\
+ <p>Please select the special characters used within your file.</p>",
+
+// Excel
+'Excel_ImportWizard_Title': "Excel import",
+'importOptions_excel_description_': "<p>Open the Excel file and select the cells you want to import. Then copy and paste them to the text area below.</p>",
+
+// KeePass
+'KeePass_ImportWizard_Title': "KeePass import",
+'importOptions_keePass_description_': "<p>Open the TXT file created by Keepass in a text editor. Then copy and paste its content to the text area below.</p>",
+
+// PasswordPlus
+'PasswordPlus_ImportWizard_Title': "Password Plus import",
+'importOptions_passwordPlus_description': "<p>Open the CSV file created by PasswordPlus in a text editor. Then copy and paste its content to the text area below.</p>",
+
+// RoboForm
+'RoboForm_ImportWizard_Title': "RoboForm import",
+'importOptions_roboForm_description': "<p>Open the HTML file created by RoboForm in a text editor. Then copy and paste its content to the text area below.</p>",
+
+
+'importData_parsingDataTitle': "Import",
+'importData_parsingDataText': "Parsing data …",
+
+'importData_previewingDataTitle': "Import",
+'importData_previewingDataText': "Processing data …",
+
+'importData_processingDataTitle': "Import",
+'importData_processingDataText': "Creating new cards …",
+
+'ImportWizard': {
+ 'EDIT': "edit",
+ 'PREVIEW': "preview",
+ 'IMPORT': "import",
+
+ 'KEEPASS_SETTINGS': "settings",
+
+ 'CSV_EDIT': "paste",
+ 'CSV_COLUMNS': "columns",
+ 'CSV_HEADER': "labels",
+ 'CSV_TITLE': "titles",
+ 'CSV_NOTES': "notes",
+ 'CSV_FIELDS': "types",
+
+ 'EXCEL_EDIT': "edit"
+},
+
+'CSV_ImportWizard_Columns': "<p>Select the columns you want to import.</p>",
+'CSV_ImportWizard_Header': "<p>If the first row of the CSV file contains field labels, tick off the checkbox below.</p>",
+'CSV_ImportWizard_Header_Settings_firstRowHeaderLabel': "Use the first row as labels?",
+'CSV_ImportWizard_Title': "<p>Select the column that contains titles of the cards you are importing. (mandatory)</p>",
+'CSV_ImportWizard_Notes': "<p>Select the column that represents a \"notes\" field. (optional)</p>",
+'CSV_ImportWizard_Notes_Settings_noSelectionLabel': "\"notes\" field not present",
+'CSV_ImportWizard_Fields': "<p>Select the correct type for each column from the drop down lists.</p>",
+'CSV_ImportWizard_Fields_MissingLabelWarning': "Missing label",
+
+'importData_importConfirmation_title': "Import",
+'importData_importConfirmation_text': "Do you want to import __numberOfRecords__ cards?",
+
+
+// Vulnerability warning
+'VulnerabilityWarning_Panel_title': "Vulnerability warning",
+'VulnerabilityWarning_Panel_message': "The action as been aborted due to a catched vulnerability",
+'VulnerabilityWarning_Panel_buttonLabel': "Close",
+
+
+
+// All the loginInfo panel infos
+
+'WELCOME_BACK': "Welcome back!",
+
+'currentConnectionText': "You are connected from ip&nbsp;__ip__, apparently from __country__, using __browser__ on __operatingSystem__.",
+'latestConnectionText': "Your latest connection was __elapsedTimeDescription__ (__time__) from ip&nbsp;__ip__, apparently from __country__, using __browser__ on __operatingSystem__.",
+
+'fullLoginHistoryLinkLabel': "show login history",
+
+'elapsedTimeDescriptions': {
+ 'MORE_THAN_A_MONTH_AGO': "more than a month ago",
+ 'MORE_THAN_A_WEEK_AGO': "more than a week ago",
+ 'MORE_THAN_*_WEEKS_AGO': "more than __elapsed__ weeks ago",
+ 'YESTERDAY': "yesterday",
+ '*_DAYS_AGO': "__elapsed__ days ago",
+ 'ABOUT_AN_HOUR_AGO': "about an hour ago",
+ '*_HOURS_AGO': "__elapsed__ hours ago",
+ 'JUST_A_FEW_MINUTES_AGO': "just a few minutes ago",
+ 'ABOUT_*_MINUTES_AGO': "about __elapsed__ minutes ago"
+},
+
+'unknown_ip': "unknown",
+
+'countries': {
+ '--': "unknown",
+ 'AD': "Andorra",
+ 'AE': "United Arab Emirates",
+ 'AF': "Afghanistan",
+ 'AG': "Antigua and Barbuda",
+ 'AI': "Anguilla",
+ 'AL': "Albania",
+ 'AM': "Armenia",
+ 'AN': "Netherlands Antilles",
+ 'AO': "Angola",
+ 'AP': "Non-Spec Asia Pas Location",
+ 'AR': "Argentina",
+ 'AS': "American Samoa",
+ 'AT': "Austria",
+ 'AU': "Australia",
+ 'AW': "Aruba",
+ 'AX': "Aland Islands",
+ 'AZ': "Azerbaijan",
+ 'BA': "Bosnia and Herzegowina",
+ 'BB': "Barbados",
+ 'BD': "Bangladesh",
+ 'BE': "Belgium",
+ 'BF': "Burkina Faso",
+ 'BG': "Bulgaria",
+ 'BH': "Bahrain",
+ 'BI': "Burundi",
+ 'BJ': "Benin",
+ 'BM': "Bermuda",
+ 'BN': "Brunei Darussalam",
+ 'BO': "Bolivia",
+ 'BR': "Brazil",
+ 'BS': "Bahamas",
+ 'BT': "Bhutan",
+ 'BW': "Botswana",
+ 'BY': "Belarus",
+ 'BZ': "Belize",
+ 'CA': "Canada",
+ 'CD': "Congo the Democratic Republic of the",
+ 'CF': "Central African Republic",
+ 'CH': "Switzerland",
+ 'CI': "Cote D'ivoire",
+ 'CK': "Cook Islands",
+ 'CL': "Chile",
+ 'CM': "Cameroon",
+ 'CN': "China",
+ 'CO': "Colombia",
+ 'CR': "Costa Rica",
+ 'CS': "Serbia and Montenegro",
+ 'CU': "Cuba",
+ 'CY': "Cyprus",
+ 'CZ': "Czech Republic",
+ 'DE': "Germany",
+ 'DJ': "Djibouti",
+ 'DK': "Denmark",
+ 'DO': "Dominican Republic",
+ 'DZ': "Algeria",
+ 'EC': "Ecuador",
+ 'EE': "Estonia",
+ 'EG': "Egypt",
+ 'ER': "Eritrea",
+ 'ES': "Spain",
+ 'ET': "Ethiopia",
+ 'EU': "European Union",
+ 'FI': "Finland",
+ 'FJ': "Fiji",
+ 'FM': "Micronesia Federated States of",
+ 'FO': "Faroe Islands",
+ 'FR': "France",
+ 'GA': "Gabon",
+ 'GB': "United Kingdom",
+ 'GD': "Grenada",
+ 'GE': "Georgia",
+ 'GF': "French Guiana",
+ 'GG': "Guernsey",
+ 'GH': "Ghana",
+ 'GI': "Gibraltar",
+ 'GL': "Greenland",
+ 'GM': "Gambia",
+ 'GP': "Guadeloupe",
+ 'GR': "Greece",
+ 'GT': "Guatemala",
+ 'GU': "Guam",
+ 'GW': "Guinea-Bissau",
+ 'GY': "Guyana",
+ 'HK': "Hong Kong",
+ 'HN': "Honduras",
+ 'HR': "Croatia (Local Name: Hrvatska)",
+ 'HT': "Haiti",
+ 'HU': "Hungary",
+ 'ID': "Indonesia",
+ 'IE': "Ireland",
+ 'IL': "Israel",
+ 'IM': "Isle of Man",
+ 'IN': "India",
+ 'IO': "British Indian Ocean Territory",
+ 'IQ': "Iraq",
+ 'IR': "Iran (Islamic Republic of)",
+ 'IS': "Iceland",
+ 'IT': "Italy",
+ 'JE': "Jersey",
+ 'JM': "Jamaica",
+ 'JO': "Jordan",
+ 'JP': "Japan",
+ 'KE': "Kenya",
+ 'KG': "Kyrgyzstan",
+ 'KH': "Cambodia",
+ 'KI': "Kiribati",
+ 'KN': "Saint Kitts and Nevis",
+ 'KR': "Korea Republic of",
+ 'KW': "Kuwait",
+ 'KY': "Cayman Islands",
+ 'KZ': "Kazakhstan",
+ 'LA': "Lao People's Democratic Republic",
+ 'LB': "Lebanon",
+ 'LC': "Saint Lucia",
+ 'LI': "Liechtenstein",
+ 'LK': "Sri Lanka",
+ 'LR': "Liberia",
+ 'LS': "Lesotho",
+ 'LT': "Lithuania",
+ 'LU': "Luxembourg",
+ 'LV': "Latvia",
+ 'LY': "Libyan Arab Jamahiriya",
+ 'MA': "Morocco",
+ 'MC': "Monaco",
+ 'MD': "Moldova Republic of",
+ 'MG': "Madagascar",
+ 'MH': "Marshall Islands",
+ 'MK': "Macedonia the Former Yugoslav Republic of",
+ 'ML': "Mali",
+ 'MM': "Myanmar",
+ 'MN': "Mongolia",
+ 'MO': "Macau",
+ 'MP': "Northern Mariana Islands",
+ 'MR': "Mauritania",
+ 'MS': "Montserrat",
+ 'MT': "Malta",
+ 'MU': "Mauritius",
+ 'MV': "Maldives",
+ 'MW': "Malawi",
+ 'MX': "Mexico",
+ 'MY': "Malaysia",
+ 'MZ': "Mozambique",
+ 'NA': "Namibia",
+ 'NC': "New Caledonia",
+ 'NF': "Norfolk Island",
+ 'NG': "Nigeria",
+ 'NI': "Nicaragua",
+ 'NL': "Netherlands",
+ 'NO': "Norway",
+ 'NP': "Nepal",
+ 'NR': "Nauru",
+ 'NU': "Niue",
+ 'NZ': "New Zealand",
+ 'OM': "Oman",
+ 'PA': "Panama",
+ 'PE': "Peru",
+ 'PF': "French Polynesia",
+ 'PG': "Papua New Guinea",
+ 'PH': "Philippines",
+ 'PK': "Pakistan",
+ 'PL': "Poland",
+ 'PR': "Puerto Rico",
+ 'PS': "Palestinian Territory Occupied",
+ 'PT': "Portugal",
+ 'PW': "Palau",
+ 'PY': "Paraguay",
+ 'QA': "Qatar",
+ 'RO': "Romania",
+ 'RS': "Serbia",
+ 'RU': "Russian Federation",
+ 'RW': "Rwanda",
+ 'SA': "Saudi Arabia",
+ 'SB': "Solomon Islands",
+ 'SC': "Seychelles",
+ 'SD': "Sudan",
+ 'SE': "Sweden",
+ 'SG': "Singapore",
+ 'SI': "Slovenia",
+ 'SK': "Slovakia (Slovak Republic)",
+ 'SL': "Sierra Leone",
+ 'SM': "San Marino",
+ 'SN': "Senegal",
+ 'SR': "Suriname",
+ 'SV': "El Salvador",
+ 'SY': "Syrian Arab Republic",
+ 'SZ': "Swaziland",
+ 'TC': "Turks and Caicos Islands",
+ 'TG': "Togo",
+ 'TH': "Thailand",
+ 'TJ': "Tajikistan",
+ 'TM': "Turkmenistan",
+ 'TN': "Tunisia",
+ 'TO': "Tonga",
+ 'TR': "Turkey",
+ 'TT': "Trinidad and Tobago",
+ 'TV': "Tuvalu",
+ 'TW': "Taiwan Province of China",
+ 'TZ': "Tanzania United Republic of",
+ 'UA': "Ukraine",
+ 'UG': "Uganda",
+ 'US': "United States",
+ 'UY': "Uruguay",
+ 'UZ': "Uzbekistan",
+ 'VA': "Holy See (Vatican City State)",
+ 'VE': "Venezuela",
+ 'VG': "Virgin Islands (British)",
+ 'VI': "Virgin Islands (U.S.)",
+ 'VN': "Viet Nam",
+ 'VU': "Vanuatu",
+ 'WF': "Wallis and Futuna Islands",
+ 'WS': "Samoa",
+ 'YE': "Yemen",
+ 'ZA': "South Africa",
+ 'ZM': "Zambia",
+ 'ZW': "Zimbabwe",
+ 'ZZ': "Reserved"
+},
+
+'browsers': {
+ 'UNKNOWN': "Unknown",
+ 'MSIE': "Internet Explorer",
+ 'FIREFOX': "Firefox",
+ 'OPERA': "Opera",
+ 'SAFARI': "Safari",
+ 'OMNIWEB': "OmniWeb",
+ 'CAMINO': "Camino",
+ 'CHROME': "Chrome"
+},
+
+'operatingSystems': {
+ 'UNKNOWN': "Unknown",
+ 'WINDOWS': "Windows",
+ 'MAC': "Mac",
+ 'LINUX': "Linux",
+ 'IPHONE': "iPhone",
+ 'MOBILE': "Mobile",
+ 'OPENBSD': "OpenBSD",
+ 'FREEBSD': "FreeBSD",
+ 'NETBSD': "NetBSD"
+},
+
+
+// Calendar texts
+'calendarStrings': {
+ 'months': {
+ '0': "January",
+ '1': "February",
+ '2': "March",
+ '3': "April",
+ '4': "May",
+ '5': "June",
+ '6': "July",
+ '7': "August",
+ '8': "September",
+ '9': "October",
+ '10': "November",
+ '11': "December"
+ },
+ 'shortMonths': {
+ '0': "Jan",
+ '1': "Feb",
+ '2': "Mar",
+ '3': "Apr",
+ '4': "May",
+ '5': "Jun",
+ '6': "Jul",
+ '7': "Aug",
+ '8': "Sep",
+ '9': "Oct",
+ '10': "Nov",
+ '11': "Dec"
+ },
+
+ 'days': {
+ '0': "Sunday",
+ '1': "Monday",
+ '2': "Tuesday",
+ '3': "Wednesday",
+ '4': "Thursday",
+ '5': "Friday",
+ '6': "Saturday"
+ },
+
+ 'shortDays': {
+ '0': "Sun",
+ '1': "Mon",
+ '2': "Tue",
+ '3': "Wed",
+ '4': "Thu",
+ '5': "Fri",
+ '6': "Sat"
+ },
+
+ 'veryShortDays': {
+ '0': "Su",
+ '1': "Mo",
+ '2': "Tu",
+ '3': "We",
+ '4': "Th",
+ '5': "Fr",
+ '6': "Sa"
+ },
+
+ 'amDesignation': "am",
+ 'pmDesignation': "pm"
+
+},
+
+// Date format
+'fullDate_format': "l, F d, Y H:i:s",
+*/
+//################################################################################
+/*
+'pageHeader': {
+ 'donation': "donAte",
+ 'forum': "foRum",
+ 'credits': "creDits",
+ 'feedback': "feeDback",
+ 'help': "hElp"
+},
+
+
+'bookmarkletCopy': {
+ 'noExceptionMessage': "The direct login configuration has been collected.",
+ 'exceptionMessage': "Sorry! There was an error while processing the page.",
+ 'copy': "copy",
+ 'successfulMessage': "DONE!",
+ 'failMessage': "Failed! :("
+},
+*/
+//################################################################################
+
+'Wizards': {
+ 'DirectLoginWizard': {
+ 'LABEL': {
+ 'name': "label",
+ 'description': "Enter a name for your new direct login."
+ },
+ 'TYPE': {
+ 'name': "type",
+ 'description': "short description of the different types of direct login available"
+ },
+ 'CONFIGURATION': {
+ 'name': "config", // "bookmarklet config",
+ 'description': "Paste the code collected by the bookmarklet. (To install the bookmarklet drag the link below to the bookmark bar of your browser.)"
+ },
+ 'BINDINGS': {
+ 'name': "bindings",
+ 'description': "Select the right value for each field from the drop down menus."
+ },
+ 'FAVICON': {
+ 'name': "favicon",
+ 'description': "If you are not satisfied with the small icon for this direct login, enter the URL of a new image file (.ico, .png, .jpg)."
+ },
+ 'DONE': {
+ 'name': "done",
+ 'description': "Congratulations! You have created a new direct login using credentials contained in your '__cardName__' card.\nEnjoy 1-clik access to '__directLoginName__'!"
+ }
+ },
+ 'NewUserWizard': {
+ 'CREDENTIALS': {
+ 'name': "credentials",
+ 'description': "[choose you credentials]"
+ },
+ 'CHECK_CREDENTIALS': {
+ 'name': "check credentials",
+ 'description': "[check credentials]"
+ },
+ 'TERMS_OF_SERVICE': {
+ 'name': "terms of service",
+ 'description': "[terms of service]"
+ },
+ 'CREATE_USER': {
+ 'name': "login",
+ 'description': "[create user]"
+ } //,
+/*
+ 'LOGIN': {
+ 'name': "login",
+ 'description': "[enjoy Clipperz]"
+ },
+*/
+ }
+},
+
+
+'exceptionsMessages': {
+ 'Clipperz': {
+ 'Crypto': {
+ 'Base': {
+ 'exception': {
+ 'CorruptedMessage': "Corrupted message"
+ }
+ }
+ }
+ }
+},
+
+
+__syntaxFix__: "syntax fix"
+
+}
diff --git a/frontend/gamma/js/Clipperz/PM/Toll.js b/frontend/gamma/js/Clipperz/PM/Toll.js
new file mode 100644
index 0000000..a533f51
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/Toll.js
@@ -0,0 +1,194 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.PM) == 'undefined') { Clipperz.PM = {}; }
+
+//=============================================================================
+
+Clipperz.PM.Toll = function(args) {
+ args = args || {};
+
+ this._requestType = args.requestType;
+ this._targetValue = args.targetValue;
+ this._cost = args.cost;
+ this._toll = null;
+
+ return this;
+}
+
+Clipperz.PM.Toll.prototype = MochiKit.Base.update(null, {
+
+ 'toString': function() {
+ return "Clipperz.PM.Toll (" + this.requestType() + ": " + this.cost() + " - " + ((this.toll() == null)? 'UNPAID' : 'PAID') + ")";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'requestType': function() {
+ return this._requestType;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'targetValue': function() {
+ return this._targetValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'cost': function() {
+ return this._cost;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toll': function() {
+ return this._toll;
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ '__pay': function() {
+ var result;
+ var targetData;
+ var targetMatchSize;
+ var prefixMatchingBits;
+ var payment;
+ var i;
+
+ if (this.toll() == null) {
+ i = 0;
+ targetData = new Clipperz.ByteArray("0x" + this.targetValue());
+ targetMatchSize = this.cost();
+
+ payment = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32);
+
+ do {
+ var paymentData;
+
+ //payment = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32);
+ payment.increment();
+ paymentData = Clipperz.Crypto.SHA.sha256(payment);
+// prefixMatchingBits = this.prefixMatchingBits(targetData, paymentData);
+ prefixMatchingBits = Clipperz.ByteArray.prefixMatchingBits(targetData, paymentData);
+ i++;
+ } while (prefixMatchingBits < targetMatchSize);
+
+ this._toll = payment.toHexString().substring(2)
+ }
+
+ return this;
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'innerDeferredPay': function (aTargetValue, aCost, aPayment) {
+ var deferredResult;
+ var result;
+ var payment;
+ var i;
+
+ result = null;
+ payment = aPayment;
+ i = 0;
+
+ while ((result == null) && (i < Clipperz.PM.Toll.numberOfCloseLoopIterations)) {
+ if (Clipperz.ByteArray.prefixMatchingBits(aTargetValue, Clipperz.Crypto.SHA.sha256(payment)) > aCost) {
+ result = payment;
+ } else {
+ payment.increment();
+ }
+
+ i ++;
+ }
+
+ if (result == null) {
+ deferredResult = MochiKit.Async.callLater(Clipperz.PM.Toll.pauseBetweenEachCloseLoop, MochiKit.Base.method(this, 'innerDeferredPay', aTargetValue, aCost, aPayment));
+ } else {
+ deferredResult = MochiKit.Async.succeed(result);
+ }
+
+ return deferredResult;
+ },
+
+ 'deferredPay': function () {
+ var deferredResult;
+ var toll;
+
+ toll = this;
+ deferredResult = new Clipperz.Async.Deferred("Toll.deferredPay");
+//deferredResult.addLog("--->>> deferredPay - " + this.cost());
+ deferredResult.addMethod(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'getRandomBytes', 32);
+ deferredResult.addMethod(toll, 'innerDeferredPay', new Clipperz.ByteArray("0x" + this.targetValue()), this.cost());
+ deferredResult.addCallback(MochiKit.Base.bind(function(aPayment) {
+ var result;
+
+ result = {
+ targetValue: this.targetValue(),
+ toll: aPayment.toHexString().substr(2)
+ };
+
+ return result;
+ }, this));
+//deferredResult.addLog("<<<--- deferredPay - " + this.cost());
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+
+});
+
+
+Clipperz.PM.Toll.validate = function(aTargetValue, aToll, aCost) {
+ var result;
+ var tollValue;
+ var targetValue;
+ var hashedTollValue;
+ var payedToll;
+
+ tollValue = new Clipperz.ByteArray("0x" + aToll);
+ targetValue = new Clipperz.ByteArray("0x" + aTargetValue);
+ hashedTollValue = Clipperz.Crypto.SHA.sha256(tollValue);
+
+ payedToll = Clipperz.ByteArray.prefixMatchingBits(targetValue, hashedTollValue);
+
+ if (payedToll < aCost) {
+ result = false;
+ } else {
+ result = true;
+ }
+
+ return result;
+};
+
+Clipperz.PM.Toll.numberOfCloseLoopIterations = 50;
+Clipperz.PM.Toll.pauseBetweenEachCloseLoop = 0.5; \ No newline at end of file
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/CoverActions/download.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/CoverActions/download.js
new file mode 100644
index 0000000..169946a
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/CoverActions/download.js
@@ -0,0 +1,120 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//
+// download.js
+// Download
+//
+// Created by Giulio Cesare Solaroli on 3/15/10
+// Copyright 2010 Clipperz
+// This code was generated by Opacity. You may use or modify it in any way.
+//
+
+var kClipperz_PM_UI_Canvas_CoverActions_downloadWidth = 46.0;
+var kClipperz_PM_UI_Canvas_CoverActions_downloadHeight = 46.0;
+
+function Clipperz_PM_UI_Canvas_CoverActions_download(canvas, aColor, aFillColor, aThickness)
+{
+ var context = canvas.getContext("2d");
+ var alignStroke;
+ var resolution;
+ var stroke;
+ var path;
+ var pointX;
+ var pointY;
+ if (window.devicePixelRatio)
+ resolution = window.devicePixelRatio;
+ else
+ resolution = 1.0;
+ resolution *= 0.5 * (canvas.width / kClipperz_PM_UI_Canvas_CoverActions_downloadWidth + canvas.height / kClipperz_PM_UI_Canvas_CoverActions_downloadHeight);
+
+ context.save();
+ context.scale(canvas.width / kClipperz_PM_UI_Canvas_CoverActions_downloadWidth, canvas.height / kClipperz_PM_UI_Canvas_CoverActions_downloadHeight);
+ context.clearRect(0.0, 0.0, kClipperz_PM_UI_Canvas_CoverActions_downloadWidth, kClipperz_PM_UI_Canvas_CoverActions_downloadHeight);
+
+ // arrow
+
+ stroke = aThickness;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.beginPath();
+ pointX = 16.5;
+ pointY = 22.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 19.5;
+ pointY = 8.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 30.038;
+ pointY = 10.605;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 27.354;
+ pointY = 24.354;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 33.28;
+ pointY = 25.293;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 19.81;
+ pointY = 36.828;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 10.07;
+ pointY = 21.617;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 16.5;
+ pointY = 22.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aFillColor;
+ context.fill();
+ context.strokeStyle = aColor;
+ context.lineWidth = stroke;
+ context.lineCap = "square";
+ context.stroke();
+
+ context.restore();
+}
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/CoverActions/look.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/CoverActions/look.js
new file mode 100644
index 0000000..b8e535b
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/CoverActions/look.js
@@ -0,0 +1,208 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//
+// look.js
+// Look
+//
+// Created by Giulio Cesare Solaroli on 3/15/10
+// Copyright 2010 Clipperz
+// This code was generated by Opacity. You may use or modify it in any way.
+//
+
+var kClipperz_PM_UI_Canvas_CoverActions_lookWidth = 46.0;
+var kClipperz_PM_UI_Canvas_CoverActions_lookHeight = 46.0;
+
+function Clipperz_PM_UI_Canvas_CoverActions_look(canvas, aColor, aFillColor, aThickness)
+{
+ var context = canvas.getContext("2d");
+ var alignStroke;
+ var resolution;
+ var stroke;
+ var path;
+ var pointX;
+ var pointY;
+ if (window.devicePixelRatio)
+ resolution = window.devicePixelRatio;
+ else
+ resolution = 1.0;
+ resolution *= 0.5 * (canvas.width / kClipperz_PM_UI_Canvas_CoverActions_lookWidth + canvas.height / kClipperz_PM_UI_Canvas_CoverActions_lookHeight);
+
+ context.save();
+ context.scale(canvas.width / kClipperz_PM_UI_Canvas_CoverActions_lookWidth, canvas.height / kClipperz_PM_UI_Canvas_CoverActions_lookHeight);
+ context.clearRect(0.0, 0.0, kClipperz_PM_UI_Canvas_CoverActions_lookWidth, kClipperz_PM_UI_Canvas_CoverActions_lookHeight);
+
+ // Layer 6
+
+ stroke = aThickness;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.save();
+ context.translate(17.5, 23.0);
+ context.rotate(-0.503);
+ context.translate(-17.5, -23.0);
+ context.beginPath();
+ pointX = 28.5;
+ pointY = 31.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 28.5;
+ pointY = 14.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 6.5;
+ pointY = 14.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 6.5;
+ pointY = 31.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 28.5;
+ pointY = 31.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aFillColor;
+ context.fill();
+ context.strokeStyle = aColor;
+ context.lineWidth = stroke;
+ context.lineCap = "square";
+ context.stroke();
+ context.restore();
+
+ // Layer 3
+
+ stroke = aThickness;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.save();
+ context.translate(22.5, 20.0);
+ context.rotate(-0.071);
+ context.translate(-22.5, -20.0);
+ context.beginPath();
+ pointX = 33.5;
+ pointY = 28.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 33.5;
+ pointY = 11.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 11.5;
+ pointY = 11.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 11.5;
+ pointY = 28.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 33.5;
+ pointY = 28.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aFillColor;
+ context.fill();
+ context.strokeStyle = aColor;
+ context.lineWidth = stroke;
+ context.lineCap = "square";
+ context.stroke();
+ context.restore();
+
+ // Layer 4
+
+ stroke = aThickness;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.save();
+ context.translate(27.5, 18.0);
+ context.rotate(0.232);
+ context.translate(-27.5, -18.0);
+ context.beginPath();
+ pointX = 38.5;
+ pointY = 26.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 38.5;
+ pointY = 9.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 16.5;
+ pointY = 9.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 16.5;
+ pointY = 26.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 38.5;
+ pointY = 26.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aFillColor;
+ context.fill();
+ context.strokeStyle = aColor;
+ context.lineWidth = stroke;
+ context.lineCap = "square";
+ context.stroke();
+ context.restore();
+
+ context.restore();
+}
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/directLogin.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/directLogin.js
new file mode 100644
index 0000000..9c4e5ba
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/directLogin.js
@@ -0,0 +1,209 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//
+// directLogin.js
+// directLogin
+//
+// Created by Giulio Cesare Solaroli on 3/7/10
+// Copyright 2010 Clipperz
+// This code was generated by Opacity. You may use or modify it in any way.
+//
+
+var kClipperz_PM_UI_Canvas_Features_directLoginWidth = 76.0;
+var kClipperz_PM_UI_Canvas_Features_directLoginHeight = 76.0;
+
+function Clipperz_PM_UI_Canvas_Features_directLogin(canvas, aColor, aBannerColor, aBannerBackgroundColor)
+{
+ var context = canvas.getContext("2d");
+ var alignStroke;
+ var resolution;
+ var stroke;
+ var path;
+ var pointX;
+ var pointY;
+ if (window.devicePixelRatio)
+ resolution = window.devicePixelRatio;
+ else
+ resolution = 1.0;
+ resolution *= 0.5 * (canvas.width / kClipperz_PM_UI_Canvas_Features_directLoginWidth + canvas.height / kClipperz_PM_UI_Canvas_Features_directLoginHeight);
+
+ context.save();
+ context.scale(canvas.width / kClipperz_PM_UI_Canvas_Features_directLoginWidth, canvas.height / kClipperz_PM_UI_Canvas_Features_directLoginHeight);
+ context.clearRect(0.0, 0.0, kClipperz_PM_UI_Canvas_Features_directLoginWidth, kClipperz_PM_UI_Canvas_Features_directLoginHeight);
+
+ // Layer 2
+
+ stroke = 6.0;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.beginPath();
+ pointX = 30.0;
+ pointY = 41.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 45.579;
+ pointY = 25.451;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.strokeStyle = aColor;
+ context.lineWidth = stroke;
+ context.lineCap = "square";
+ context.stroke();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 34.207;
+ pointY = 45.697;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 24.101;
+ pointY = 37.52;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 24.122;
+ pointY = 47.828;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 34.207;
+ pointY = 45.697;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ stroke = 6.0;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.beginPath();
+ pointX = 24.631;
+ pointY = 28.971;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 46.497;
+ pointY = 26.451;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.strokeStyle = aColor;
+ context.stroke();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 25.014;
+ pointY = 35.265;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 22.166;
+ pointY = 22.58;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 15.784;
+ pointY = 30.675;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 25.014;
+ pointY = 35.265;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ stroke = 6.0;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.beginPath();
+ pointX = 42.282;
+ pointY = 47.03;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 47.771;
+ pointY = 25.714;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.strokeStyle = aColor;
+ context.stroke();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 48.294;
+ pointY = 48.929;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 35.432;
+ pointY = 47.039;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 40.7;
+ pointY = 55.899;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 48.294;
+ pointY = 48.929;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ context.restore();
+}
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/protect.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/protect.js
new file mode 100644
index 0000000..501b69b
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/protect.js
@@ -0,0 +1,237 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//
+// protect.js
+// protect
+//
+// Created by Giulio Cesare Solaroli on 3/7/10
+// Copyright 2010 Clipperz
+// This code was generated by Opacity. You may use or modify it in any way.
+//
+
+var kClipperz_PM_UI_Canvas_Features_protectWidth = 76.0;
+var kClipperz_PM_UI_Canvas_Features_protectHeight = 76.0;
+
+function Clipperz_PM_UI_Canvas_Features_protect(canvas, aColor, aBannerColor, aBannerBackgroundColor)
+{
+ var context = canvas.getContext("2d");
+ var alignStroke;
+ var resolution;
+ var path;
+ var pointX;
+ var pointY;
+ var controlPoint1X;
+ var controlPoint1Y;
+ var controlPoint2X;
+ var controlPoint2Y;
+ var stroke;
+ if (window.devicePixelRatio)
+ resolution = window.devicePixelRatio;
+ else
+ resolution = 1.0;
+ resolution *= 0.5 * (canvas.width / kClipperz_PM_UI_Canvas_Features_protectWidth + canvas.height / kClipperz_PM_UI_Canvas_Features_protectHeight);
+
+ context.save();
+ context.scale(canvas.width / kClipperz_PM_UI_Canvas_Features_protectWidth, canvas.height / kClipperz_PM_UI_Canvas_Features_protectHeight);
+ context.clearRect(0.0, 0.0, kClipperz_PM_UI_Canvas_Features_protectWidth, kClipperz_PM_UI_Canvas_Features_protectHeight);
+
+ // Layer 1
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 38.5;
+ pointY = 36.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 37.068;
+ pointY = 38.816;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 37.41;
+ controlPoint1Y = 36.234;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 37.175;
+ controlPoint2Y = 37.907;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 37.031;
+ pointY = 40.802;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 36.991;
+ controlPoint1Y = 39.474;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 36.98;
+ controlPoint2Y = 40.141;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 37.258;
+ pointY = 42.23;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 37.068;
+ controlPoint1Y = 41.283;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 37.139;
+ controlPoint2Y = 41.762;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 38.348;
+ pointY = 43.979;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 37.402;
+ controlPoint1Y = 42.799;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 37.682;
+ controlPoint2Y = 43.798;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 38.5;
+ pointY = 36.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 40.249;
+ controlPoint1Y = 44.497;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 40.723;
+ controlPoint2Y = 36.303;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 38.5;
+ pointY = 36.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 50.0;
+ pointY = 52.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 26.0;
+ pointY = 52.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 26.0;
+ pointY = 33.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 50.0;
+ pointY = 33.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 50.0;
+ pointY = 52.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 47.0;
+ pointY = 32.463;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 38.0;
+ pointY = 52.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 47.0;
+ controlPoint1Y = 52.925;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 38.0;
+ controlPoint2Y = 52.0;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 29.0;
+ pointY = 32.463;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 38.0;
+ controlPoint1Y = 52.0;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 29.0;
+ controlPoint2Y = 52.925;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 47.0;
+ pointY = 32.463;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 29.0;
+ controlPoint1Y = 12.0;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 47.0;
+ controlPoint2Y = 12.0;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ context.closePath();
+ context.strokeStyle = aColor;
+ stroke = 4.0;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ stroke *= 2.0;
+ context.lineWidth = stroke;
+ context.lineCap = "square";
+ context.save();
+ context.clip();
+ context.stroke();
+ context.restore();
+
+ context.restore();
+}
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/share.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/share.js
new file mode 100644
index 0000000..825a17e
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/share.js
@@ -0,0 +1,1719 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//
+// share.js
+// share
+//
+// Created by Giulio Cesare Solaroli on 3/7/10
+// Copyright 2010 Clipperz
+// This code was generated by Opacity. You may use or modify it in any way.
+//
+
+var kClipperz_PM_UI_Canvas_Features_shareWidth = 76.0;
+var kClipperz_PM_UI_Canvas_Features_shareHeight = 76.0;
+
+function Clipperz_PM_UI_Canvas_Features_share(canvas, aColor, aBannerColor, aBannerBackgroundColor)
+{
+ var context = canvas.getContext("2d");
+ var alignStroke;
+ var resolution;
+ var path;
+ var pointX;
+ var pointY;
+ var controlPoint1X;
+ var controlPoint1Y;
+ var controlPoint2X;
+ var controlPoint2Y;
+ var stroke;
+ if (window.devicePixelRatio)
+ resolution = window.devicePixelRatio;
+ else
+ resolution = 1.0;
+ resolution *= 0.5 * (canvas.width / kClipperz_PM_UI_Canvas_Features_shareWidth + canvas.height / kClipperz_PM_UI_Canvas_Features_shareHeight);
+
+ context.save();
+ context.scale(canvas.width / kClipperz_PM_UI_Canvas_Features_shareWidth, canvas.height / kClipperz_PM_UI_Canvas_Features_shareHeight);
+ context.clearRect(0.0, 0.0, kClipperz_PM_UI_Canvas_Features_shareWidth, kClipperz_PM_UI_Canvas_Features_shareHeight);
+
+ // Layer 1
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 43.179;
+ pointY = 18.621;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 37.163;
+ pointY = 12.605;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 43.179;
+ controlPoint1Y = 15.32;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 40.463;
+ controlPoint2Y = 12.605;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 31.147;
+ pointY = 18.621;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 33.863;
+ controlPoint1Y = 12.605;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 31.147;
+ controlPoint2Y = 15.32;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 37.163;
+ pointY = 24.637;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 31.147;
+ controlPoint1Y = 21.921;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 33.863;
+ controlPoint2Y = 24.637;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 43.179;
+ pointY = 18.621;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 40.463;
+ controlPoint1Y = 24.637;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 43.179;
+ controlPoint2Y = 21.921;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 56.548;
+ pointY = 53.379;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 51.2;
+ pointY = 48.032;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 56.548;
+ controlPoint1Y = 50.446;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 54.134;
+ controlPoint2Y = 48.032;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 45.853;
+ pointY = 53.379;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 48.267;
+ controlPoint1Y = 48.032;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 45.853;
+ controlPoint2Y = 50.446;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 51.2;
+ pointY = 58.727;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 45.853;
+ controlPoint1Y = 56.313;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 48.267;
+ controlPoint2Y = 58.727;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 56.548;
+ pointY = 53.379;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 54.134;
+ controlPoint1Y = 58.727;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 56.548;
+ controlPoint2Y = 56.313;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 31.147;
+ pointY = 38.674;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 25.8;
+ pointY = 33.326;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 31.147;
+ controlPoint1Y = 35.74;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 28.733;
+ controlPoint2Y = 33.326;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 20.452;
+ pointY = 38.674;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 22.866;
+ controlPoint1Y = 33.326;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 20.452;
+ controlPoint2Y = 35.74;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 25.8;
+ pointY = 44.021;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 20.452;
+ controlPoint1Y = 41.607;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 22.866;
+ controlPoint2Y = 44.021;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 31.147;
+ pointY = 38.674;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 28.733;
+ controlPoint1Y = 44.021;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 31.147;
+ controlPoint2Y = 41.607;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 39.168;
+ pointY = 48.032;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 33.821;
+ pointY = 42.684;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 39.168;
+ controlPoint1Y = 45.098;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 36.754;
+ controlPoint2Y = 42.684;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 28.473;
+ pointY = 48.032;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 30.887;
+ controlPoint1Y = 42.684;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 28.473;
+ controlPoint2Y = 45.098;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 33.821;
+ pointY = 53.379;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 28.473;
+ controlPoint1Y = 50.965;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 30.887;
+ controlPoint2Y = 53.379;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 39.168;
+ pointY = 48.032;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 36.754;
+ controlPoint1Y = 53.379;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 39.168;
+ controlPoint2Y = 50.965;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 56.548;
+ pointY = 29.984;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 53.206;
+ pointY = 26.642;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 56.548;
+ controlPoint1Y = 28.151;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 55.039;
+ controlPoint2Y = 26.642;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 49.863;
+ pointY = 29.984;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 51.372;
+ controlPoint1Y = 26.642;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 49.863;
+ controlPoint2Y = 28.151;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 53.206;
+ pointY = 33.326;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 49.863;
+ controlPoint1Y = 31.817;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 51.372;
+ controlPoint2Y = 33.326;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 56.548;
+ pointY = 29.984;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 55.039;
+ controlPoint1Y = 33.326;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 56.548;
+ controlPoint2Y = 31.817;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 49.863;
+ pointY = 39.342;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 46.521;
+ pointY = 36.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 49.863;
+ controlPoint1Y = 37.509;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 48.355;
+ controlPoint2Y = 36.0;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 43.179;
+ pointY = 39.342;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 44.688;
+ controlPoint1Y = 36.0;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 43.179;
+ controlPoint2Y = 37.509;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 46.521;
+ pointY = 42.684;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 43.179;
+ controlPoint1Y = 41.176;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 44.688;
+ controlPoint2Y = 42.684;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 49.863;
+ pointY = 39.342;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 48.355;
+ controlPoint1Y = 42.684;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 49.863;
+ controlPoint2Y = 41.176;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ stroke = 1.0;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.beginPath();
+ pointX = 37.163;
+ pointY = 19.289;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 53.206;
+ pointY = 29.984;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.strokeStyle = aColor;
+ context.lineWidth = stroke;
+ context.lineCap = "square";
+ context.stroke();
+
+ stroke = 1.0;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.beginPath();
+ pointX = 50.532;
+ pointY = 54.048;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 37.163;
+ pointY = 48.7;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.strokeStyle = aColor;
+ context.stroke();
+
+ stroke = 1.0;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.beginPath();
+ pointX = 27.805;
+ pointY = 33.995;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 33.153;
+ pointY = 24.637;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.strokeStyle = aColor;
+ context.stroke();
+
+ stroke = 1.0;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.beginPath();
+ pointX = 38.5;
+ pointY = 24.637;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 45.184;
+ pointY = 36.668;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.strokeStyle = aColor;
+ context.stroke();
+
+ stroke = 1.0;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.beginPath();
+ pointX = 37.163;
+ pointY = 19.289;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 34.155;
+ pointY = 44.857;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.strokeStyle = aColor;
+ context.stroke();
+
+ stroke = 1.0;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.beginPath();
+ pointX = 26.468;
+ pointY = 36.668;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 52.871;
+ pointY = 30.151;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.strokeStyle = aColor;
+ context.stroke();
+
+ stroke = 1.0;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.beginPath();
+ pointX = 53.206;
+ pointY = 31.321;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 51.535;
+ pointY = 52.878;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.strokeStyle = aColor;
+ context.stroke();
+
+ stroke = 1.0;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.beginPath();
+ pointX = 26.468;
+ pointY = 38.005;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 46.856;
+ pointY = 39.175;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.strokeStyle = aColor;
+ context.stroke();
+
+ stroke = 1.0;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.beginPath();
+ pointX = 26.468;
+ pointY = 38.005;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 34.489;
+ pointY = 48.7;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.strokeStyle = aColor;
+ context.stroke();
+
+ stroke = 1.0;
+ stroke *= resolution;
+ if (stroke < 1.0)
+ stroke = Math.ceil(stroke);
+ else
+ stroke = Math.round(stroke);
+ stroke /= resolution;
+ alignStroke = (0.5 * stroke * resolution) % 1.0;
+ context.beginPath();
+ pointX = 34.489;
+ pointY = 48.7;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 46.521;
+ pointY = 39.342;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.strokeStyle = aColor;
+ context.stroke();
+
+ // Layer 2
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 38.974;
+ pointY = 0.013;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 53.593;
+ pointY = 3.386;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 44.035;
+ controlPoint1Y = 0.11;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 48.977;
+ controlPoint2Y = 1.35;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 3.386;
+ pointY = 53.593;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 0.011;
+ pointY = 37.17;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 1.013;
+ controlPoint1Y = 48.448;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = -0.062;
+ controlPoint2Y = 42.82;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 37.17;
+ pointY = 0.011;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 38.974;
+ pointY = 0.013;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 38.325;
+ controlPoint1Y = -0.004;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 37.723;
+ controlPoint2Y = -0.004;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 38.974;
+ pointY = 0.013;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aBannerBackgroundColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 6.58;
+ pointY = 36.628;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 7.533;
+ pointY = 34.418;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 6.575;
+ controlPoint1Y = 35.794;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 6.893;
+ controlPoint2Y = 35.058;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 10.253;
+ pointY = 33.382;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 8.389;
+ controlPoint1Y = 33.562;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 9.296;
+ controlPoint2Y = 33.216;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 11.555;
+ pointY = 33.979;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 10.787;
+ controlPoint1Y = 33.479;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 11.221;
+ controlPoint2Y = 33.678;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 10.492;
+ pointY = 35.043;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 9.673;
+ pointY = 34.756;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 10.179;
+ controlPoint1Y = 34.868;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 9.906;
+ controlPoint2Y = 34.772;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 8.482;
+ pointY = 35.285;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 9.259;
+ controlPoint1Y = 34.729;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 8.862;
+ controlPoint2Y = 34.905;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 8.035;
+ pointY = 36.667;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 8.095;
+ controlPoint1Y = 35.671;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 7.946;
+ controlPoint2Y = 36.132;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 9.024;
+ pointY = 38.326;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 8.124;
+ controlPoint1Y = 37.203;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 8.453;
+ controlPoint2Y = 37.756;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 10.661;
+ pointY = 39.255;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 9.595;
+ controlPoint1Y = 38.897;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 10.141;
+ controlPoint2Y = 39.207;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 11.987;
+ pointY = 38.782;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 11.181;
+ controlPoint1Y = 39.304;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 11.623;
+ controlPoint2Y = 39.146;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 12.473;
+ pointY = 37.563;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 12.359;
+ controlPoint1Y = 38.409;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 12.522;
+ controlPoint2Y = 38.003;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 12.152;
+ pointY = 36.704;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 12.45;
+ controlPoint1Y = 37.324;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 12.343;
+ controlPoint2Y = 37.037;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 13.205;
+ pointY = 35.651;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 13.853;
+ pointY = 37.71;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 13.668;
+ controlPoint1Y = 36.297;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 13.884;
+ controlPoint2Y = 36.984;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 12.919;
+ pointY = 39.687;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 13.822;
+ controlPoint1Y = 38.436;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 13.51;
+ controlPoint2Y = 39.095;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 10.488;
+ pointY = 40.709;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 12.187;
+ controlPoint1Y = 40.419;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 11.377;
+ controlPoint2Y = 40.759;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 7.919;
+ pointY = 39.397;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 9.597;
+ controlPoint1Y = 40.656;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 8.741;
+ controlPoint2Y = 40.218;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 6.58;
+ pointY = 36.628;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 7.031;
+ controlPoint1Y = 38.508;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 6.584;
+ controlPoint2Y = 37.585;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 6.58;
+ pointY = 36.628;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 17.778;
+ pointY = 32.093;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 16.824;
+ pointY = 30.396;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 17.715;
+ controlPoint1Y = 31.534;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 17.397;
+ controlPoint2Y = 30.969;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 15.129;
+ pointY = 29.443;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 16.253;
+ controlPoint1Y = 29.825;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 15.688;
+ controlPoint2Y = 29.507;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 13.658;
+ pointY = 29.978;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 14.569;
+ controlPoint1Y = 29.378;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 14.079;
+ controlPoint2Y = 29.557;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 13.116;
+ pointY = 31.452;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 13.236;
+ controlPoint1Y = 30.399;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 13.056;
+ controlPoint2Y = 30.891;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 14.065;
+ pointY = 33.154;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 13.175;
+ controlPoint1Y = 32.014;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 13.492;
+ controlPoint2Y = 32.581;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 15.767;
+ pointY = 34.104;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 14.638;
+ controlPoint1Y = 33.727;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 15.206;
+ controlPoint2Y = 34.044;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 17.242;
+ pointY = 33.562;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 16.329;
+ controlPoint1Y = 34.164;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 16.82;
+ controlPoint2Y = 33.983;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 17.778;
+ pointY = 32.093;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 17.663;
+ controlPoint1Y = 33.14;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 17.842;
+ controlPoint2Y = 32.651;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 17.778;
+ pointY = 32.093;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 19.216;
+ pointY = 32.201;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 18.143;
+ pointY = 34.463;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 19.228;
+ controlPoint1Y = 32.982;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 18.87;
+ controlPoint2Y = 33.736;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 15.881;
+ pointY = 35.537;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 17.415;
+ controlPoint1Y = 35.19;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 16.661;
+ controlPoint2Y = 35.548;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 13.009;
+ pointY = 34.211;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 14.88;
+ controlPoint1Y = 35.567;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 13.922;
+ controlPoint2Y = 35.125;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 11.683;
+ pointY = 31.338;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 12.076;
+ controlPoint1Y = 33.279;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 11.634;
+ controlPoint2Y = 32.321;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 12.757;
+ pointY = 29.077;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 11.671;
+ controlPoint1Y = 30.558;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 12.029;
+ controlPoint2Y = 29.804;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 15.018;
+ pointY = 28.003;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 13.484;
+ controlPoint1Y = 28.349;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 14.238;
+ controlPoint2Y = 27.991;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 17.887;
+ pointY = 29.332;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 15.999;
+ controlPoint1Y = 27.957;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 16.955;
+ controlPoint2Y = 28.4;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 19.216;
+ pointY = 32.201;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 18.801;
+ controlPoint1Y = 30.246;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 19.244;
+ controlPoint2Y = 31.202;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 19.216;
+ pointY = 32.201;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 19.534;
+ pointY = 22.61;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 21.064;
+ pointY = 21.08;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 26.153;
+ pointY = 26.17;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 25.162;
+ pointY = 27.16;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 21.72;
+ pointY = 23.718;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 21.307;
+ pointY = 23.299;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 21.621;
+ controlPoint1Y = 23.619;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 21.483;
+ controlPoint2Y = 23.479;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 20.898;
+ pointY = 22.883;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 21.131;
+ controlPoint1Y = 23.118;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 20.995;
+ controlPoint2Y = 22.979;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 24.206;
+ pointY = 28.117;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 23.173;
+ pointY = 29.149;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 17.946;
+ pointY = 25.835;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 18.362;
+ pointY = 26.244;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 18.043;
+ controlPoint1Y = 25.931;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 18.181;
+ controlPoint2Y = 26.068;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 18.781;
+ pointY = 26.656;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 18.543;
+ controlPoint1Y = 26.42;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 18.682;
+ controlPoint2Y = 26.557;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 22.224;
+ pointY = 30.099;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 21.233;
+ pointY = 31.09;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 16.144;
+ pointY = 26;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 17.69;
+ pointY = 24.454;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 22.617;
+ pointY = 27.53;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 19.534;
+ pointY = 22.61;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 28.114;
+ pointY = 24.208;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 27.057;
+ pointY = 25.265;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 21.968;
+ pointY = 20.176;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 23.025;
+ pointY = 19.119;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 28.114;
+ pointY = 24.208;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 23.998;
+ pointY = 18.146;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 25.114;
+ pointY = 17.03;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 30.693;
+ pointY = 18.556;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 27.14;
+ pointY = 15.004;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 28.131;
+ pointY = 14.013;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 33.22;
+ pointY = 19.102;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 32.157;
+ pointY = 20.165;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 26.464;
+ pointY = 18.629;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 30.079;
+ pointY = 22.244;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 29.088;
+ pointY = 23.235;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 23.998;
+ pointY = 18.146;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 34.132;
+ pointY = 11.188;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 32.813;
+ pointY = 11.05;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 33.704;
+ controlPoint1Y = 10.921;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 33.264;
+ controlPoint2Y = 10.875;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 32.116;
+ pointY = 11.52;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 32.562;
+ controlPoint1Y = 11.149;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 32.33;
+ controlPoint2Y = 11.306;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 31.57;
+ pointY = 12.994;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 31.706;
+ controlPoint1Y = 11.93;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 31.524;
+ controlPoint2Y = 12.421;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 32.571;
+ pointY = 14.786;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 31.616;
+ controlPoint1Y = 13.567;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 31.95;
+ controlPoint2Y = 14.165;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 34.329;
+ pointY = 15.687;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 33.197;
+ controlPoint1Y = 15.412;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 33.783;
+ controlPoint2Y = 15.713;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 35.693;
+ pointY = 15.104;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 34.874;
+ controlPoint1Y = 15.662;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 35.329;
+ controlPoint2Y = 15.467;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 36.261;
+ pointY = 13.918;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 36.049;
+ controlPoint1Y = 14.747;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 36.239;
+ controlPoint2Y = 14.352;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 35.872;
+ pointY = 12.687;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 36.282;
+ controlPoint1Y = 13.484;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 36.153;
+ controlPoint2Y = 13.074;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 34.695;
+ pointY = 13.864;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 33.845;
+ pointY = 13.015;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 35.965;
+ pointY = 10.895;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 38.696;
+ pointY = 13.626;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 37.992;
+ pointY = 14.33;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 37.25;
+ pointY = 13.802;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 37.208;
+ pointY = 14.866;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 37.287;
+ controlPoint1Y = 14.249;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 37.273;
+ controlPoint2Y = 14.603;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 36.431;
+ pointY = 16.16;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 37.1;
+ controlPoint1Y = 15.319;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 36.841;
+ controlPoint2Y = 15.751;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 34.073;
+ pointY = 17.117;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 35.757;
+ controlPoint1Y = 16.835;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 34.971;
+ controlPoint2Y = 17.153;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 31.473;
+ pointY = 15.863;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 33.155;
+ controlPoint1Y = 17.096;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 32.288;
+ controlPoint2Y = 16.678;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 30.172;
+ pointY = 13.201;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 30.649;
+ controlPoint1Y = 15.039;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 30.216;
+ controlPoint2Y = 14.152;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 31.225;
+ pointY = 10.657;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 30.128;
+ controlPoint1Y = 12.251;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 30.479;
+ controlPoint2Y = 11.402;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 33.276;
+ pointY = 9.59;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 31.872;
+ controlPoint1Y = 10.01;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 32.555;
+ controlPoint2Y = 9.654;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 35.178;
+ pointY = 10.142;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 33.996;
+ controlPoint1Y = 9.525;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 34.63;
+ controlPoint2Y = 9.71;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 34.132;
+ pointY = 11.188;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 34.878;
+ pointY = 7.301;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 35.958;
+ pointY = 6.22;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 37.25;
+ pointY = 7.511;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 39.346;
+ pointY = 10.166;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 38.831;
+ pointY = 10.681;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 36.169;
+ pointY = 8.592;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 34.878;
+ pointY = 7.301;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 38.976;
+ pointY = 11.351;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 40.005;
+ pointY = 10.322;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 41.003;
+ pointY = 11.32;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 39.974;
+ pointY = 12.349;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 38.976;
+ pointY = 11.351;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 41.528;
+ pointY = 10.795;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ context.fillStyle = aBannerColor;
+ context.fill();
+
+ context.restore();
+}
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/store.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/store.js
new file mode 100644
index 0000000..eaeb7f1
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Features/store.js
@@ -0,0 +1,310 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//
+// store.js
+// store
+//
+// Created by Giulio Cesare Solaroli on 3/7/10
+// Copyright 2010 Clipperz
+// This code was generated by Opacity. You may use or modify it in any way.
+//
+
+var kClipperz_PM_UI_Canvas_Features_storeWidth = 76.0;
+var kClipperz_PM_UI_Canvas_Features_storeHeight = 76.0;
+
+function Clipperz_PM_UI_Canvas_Features_store(canvas, aColor, aBannerColor, aBannerBackgroundColor)
+{
+ var context = canvas.getContext("2d");
+ var alignStroke;
+ var resolution;
+ var path;
+ var pointX;
+ var pointY;
+ if (window.devicePixelRatio)
+ resolution = window.devicePixelRatio;
+ else
+ resolution = 1.0;
+ resolution *= 0.5 * (canvas.width / kClipperz_PM_UI_Canvas_Features_storeWidth + canvas.height / kClipperz_PM_UI_Canvas_Features_storeHeight);
+
+ context.save();
+ context.scale(canvas.width / kClipperz_PM_UI_Canvas_Features_storeWidth, canvas.height / kClipperz_PM_UI_Canvas_Features_storeHeight);
+ context.clearRect(0.0, 0.0, kClipperz_PM_UI_Canvas_Features_storeWidth, kClipperz_PM_UI_Canvas_Features_storeHeight);
+
+ // Layer 1
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 27.0;
+ pointY = 29.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 27.0;
+ pointY = 24.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 22.0;
+ pointY = 24.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 22.0;
+ pointY = 29.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 27.0;
+ pointY = 29.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 54.0;
+ pointY = 29.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 54.0;
+ pointY = 24.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 29.0;
+ pointY = 24.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 29.0;
+ pointY = 29.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 54.0;
+ pointY = 29.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 43.0;
+ pointY = 37.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 43.0;
+ pointY = 32.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 29.0;
+ pointY = 32.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 29.0;
+ pointY = 37.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 43.0;
+ pointY = 37.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 27.0;
+ pointY = 37.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 27.0;
+ pointY = 32.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 22.0;
+ pointY = 32.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 22.0;
+ pointY = 37.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 27.0;
+ pointY = 37.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 27.0;
+ pointY = 44.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 27.0;
+ pointY = 39.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 22.0;
+ pointY = 39.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 22.0;
+ pointY = 44.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 27.0;
+ pointY = 44.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 46.0;
+ pointY = 44.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 46.0;
+ pointY = 39.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 29.0;
+ pointY = 39.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 29.0;
+ pointY = 44.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 46.0;
+ pointY = 44.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 40.0;
+ pointY = 51.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 40.0;
+ pointY = 46.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 29.0;
+ pointY = 46.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 29.0;
+ pointY = 51.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 40.0;
+ pointY = 51.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 27.0;
+ pointY = 51.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 27.0;
+ pointY = 46.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 22.0;
+ pointY = 46.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 22.0;
+ pointY = 51.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 27.0;
+ pointY = 51.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ context.restore();
+}
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/GraphicFunctions.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/GraphicFunctions.js
new file mode 100644
index 0000000..5de2e96
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/GraphicFunctions.js
@@ -0,0 +1,68 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Canvas');
+
+MochiKit.Base.update(Clipperz.PM.UI.Canvas , {
+ 'marks': {
+ '!': Clipperz_PM_UI_Canvas_Marks_exclamationMark,
+ '?': Clipperz_PM_UI_Canvas_Marks_questionMark,
+ 'i': Clipperz_PM_UI_Canvas_Marks_info
+ },
+
+ 'features': {
+ 'store': Clipperz_PM_UI_Canvas_Features_store,
+ 'protect': Clipperz_PM_UI_Canvas_Features_protect,
+ 'directLogin': Clipperz_PM_UI_Canvas_Features_directLogin,
+ 'share': Clipperz_PM_UI_Canvas_Features_share
+ },
+
+ 'tips': {
+ 'open': Clipperz_PM_UI_Canvas_Tips_open,
+ 'close': Clipperz_PM_UI_Canvas_Tips_close
+ },
+
+ 'star': {
+ 'normal': Clipperz_PM_UI_Canvas_Star_normal
+ },
+
+ 'coverActions': {
+ 'look': Clipperz_PM_UI_Canvas_CoverActions_look,
+ 'download': Clipperz_PM_UI_Canvas_CoverActions_download
+ },
+
+ 'registerButton': {
+ 'normal': Clipperz_PM_UI_Canvas_RegisterButton_normal
+ },
+
+ 'logo': {
+ 'normal': Clipperz_PM_UI_Canvas_Logo_normal
+ },
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/Logo/normal.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Logo/normal.js
new file mode 100644
index 0000000..e0bea36
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Logo/normal.js
@@ -0,0 +1,65 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//
+// normal.js
+// normal
+//
+// Created by Giulio Cesare Solaroli on 3/25/10
+// Copyright 2010 Clipperz
+// This code was generated by Opacity. You may use or modify it in any way.
+//
+
+var kClipperz_PM_UI_Canvas_Logo_normalWidth = 150.0;
+var kClipperz_PM_UI_Canvas_Logo_normalHeight = 39.0;
+
+function Clipperz_PM_UI_Canvas_Logo_normal(canvas, aMainColor, aSecondaryColor)
+{
+ var context = canvas.getContext("2d");
+ var string;
+
+ context.save();
+ context.scale(canvas.width / kClipperz_PM_UI_Canvas_Logo_normalWidth, canvas.height / kClipperz_PM_UI_Canvas_Logo_normalHeight);
+ context.clearRect(0.0, 0.0, kClipperz_PM_UI_Canvas_Logo_normalWidth, kClipperz_PM_UI_Canvas_Logo_normalHeight);
+
+ // clipper…
+
+ string = "clipper";
+ context.font = "38.0pt Helvetica-Bold";
+ context.fillStyle = aMainColor;
+ context.fillText(string, -9.0, -9.0);
+
+ // …z
+
+ string = "z";
+ context.font = "38.0pt Helvetica-Bold";
+ context.fillStyle = aSecondaryColor;
+ context.fillText(string, 125.0, -9.0);
+
+ context.restore();
+}
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/Marks/exclamationMark.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Marks/exclamationMark.js
new file mode 100644
index 0000000..f3ae04d
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Marks/exclamationMark.js
@@ -0,0 +1,280 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//
+// exclamationMark.js
+// !
+//
+// Created by Giulio Cesare Solaroli on 3/7/10
+// Copyright 2010 Clipperz
+// This code was generated by Opacity. You may use or modify it in any way.
+//
+
+var kClipperz_PM_UI_Canvas_Marks_exclamationMarkWidth = 50.0;
+var kClipperz_PM_UI_Canvas_Marks_exclamationMarkHeight = 50.0;
+
+function Clipperz_PM_UI_Canvas_Marks_exclamationMark(canvas, aColor)
+{
+ var context = canvas.getContext("2d");
+ var alignStroke;
+ var resolution;
+ var path;
+ var pointX;
+ var pointY;
+ var controlPoint1X;
+ var controlPoint1Y;
+ var controlPoint2X;
+ var controlPoint2Y;
+ if (window.devicePixelRatio)
+ resolution = window.devicePixelRatio;
+ else
+ resolution = 1.0;
+ resolution *= 0.5 * (canvas.width / kClipperz_PM_UI_Canvas_Marks_exclamationMarkWidth + canvas.height / kClipperz_PM_UI_Canvas_Marks_exclamationMarkHeight);
+
+ context.save();
+ context.scale(canvas.width / kClipperz_PM_UI_Canvas_Marks_exclamationMarkWidth, canvas.height / kClipperz_PM_UI_Canvas_Marks_exclamationMarkHeight);
+ context.clearRect(0.0, 0.0, kClipperz_PM_UI_Canvas_Marks_exclamationMarkWidth, kClipperz_PM_UI_Canvas_Marks_exclamationMarkHeight);
+
+ // Layer 1
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 26.499;
+ pointY = 10.848;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 20.887;
+ pointY = 11.584;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 25.395;
+ controlPoint1Y = 10.802;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 22.175;
+ controlPoint2Y = 11.078;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 20.013;
+ pointY = 13.194;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 20.335;
+ controlPoint1Y = 11.814;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 19.921;
+ controlPoint2Y = 12.826;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 23.049;
+ pointY = 28.788;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 20.243;
+ controlPoint1Y = 15.448;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 22.589;
+ controlPoint2Y = 26.35;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 25.027;
+ pointY = 29.156;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 23.279;
+ controlPoint1Y = 29.018;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 24.705;
+ controlPoint2Y = 29.202;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 27.971;
+ pointY = 11.354;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 25.809;
+ controlPoint1Y = 25.384;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 27.971;
+ controlPoint2Y = 12.826;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 26.499;
+ pointY = 10.848;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 27.557;
+ controlPoint1Y = 11.032;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 26.913;
+ controlPoint2Y = 10.848;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 26.499;
+ pointY = 10.848;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 24.337;
+ pointY = 31.962;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 21.899;
+ pointY = 32.882;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 23.463;
+ controlPoint1Y = 31.962;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 22.589;
+ controlPoint2Y = 32.284;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 20.703;
+ pointY = 35.458;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 21.163;
+ controlPoint1Y = 33.572;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 20.703;
+ controlPoint2Y = 34.538;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 21.669;
+ pointY = 38.08;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 20.703;
+ controlPoint1Y = 36.47;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 20.979;
+ controlPoint2Y = 37.344;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 24.015;
+ pointY = 39.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 22.405;
+ controlPoint1Y = 38.77;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 23.325;
+ controlPoint2Y = 39.0;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 26.821;
+ pointY = 38.034;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 25.073;
+ controlPoint1Y = 39.0;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 26.131;
+ controlPoint2Y = 38.724;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 27.833;
+ pointY = 35.55;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 27.465;
+ controlPoint1Y = 37.344;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 27.833;
+ controlPoint2Y = 36.194;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 26.683;
+ pointY = 32.744;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 27.833;
+ controlPoint1Y = 34.676;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 27.557;
+ controlPoint2Y = 33.572;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 24.337;
+ pointY = 31.962;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 26.085;
+ controlPoint1Y = 32.238;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 25.211;
+ controlPoint2Y = 31.962;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 24.337;
+ pointY = 31.962;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 30.639;
+ pointY = 38.402;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ context.fillStyle = aColor;
+ context.fill();
+
+ context.restore();
+}
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/Marks/info.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Marks/info.js
new file mode 100644
index 0000000..adab74f
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Marks/info.js
@@ -0,0 +1,391 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//
+// info.js
+// i
+//
+// Created by Giulio Cesare Solaroli on 3/7/10
+// Copyright 2010 Clipperz
+// This code was generated by Opacity. You may use or modify it in any way.
+//
+
+var kClipperz_PM_UI_Canvas_Marks_infoWidth = 50.0;
+var kClipperz_PM_UI_Canvas_Marks_infoHeight = 50.0;
+
+function Clipperz_PM_UI_Canvas_Marks_info(canvas, aColor)
+{
+ var context = canvas.getContext("2d");
+ var alignStroke;
+ var resolution;
+ var path;
+ var pointX;
+ var pointY;
+ var controlPoint1X;
+ var controlPoint1Y;
+ var controlPoint2X;
+ var controlPoint2Y;
+ var color;
+ if (window.devicePixelRatio)
+ resolution = window.devicePixelRatio;
+ else
+ resolution = 1.0;
+ resolution *= 0.5 * (canvas.width / kClipperz_PM_UI_Canvas_Marks_infoWidth + canvas.height / kClipperz_PM_UI_Canvas_Marks_infoHeight);
+
+ context.save();
+ context.scale(canvas.width / kClipperz_PM_UI_Canvas_Marks_infoWidth, canvas.height / kClipperz_PM_UI_Canvas_Marks_infoHeight);
+ context.clearRect(0.0, 0.0, kClipperz_PM_UI_Canvas_Marks_infoWidth, kClipperz_PM_UI_Canvas_Marks_infoHeight);
+
+ // Layer 1
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 30.253;
+ pointY = 37.436;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 28.505;
+ pointY = 37.022;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 27.677;
+ pointY = 35.09;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 27.953;
+ controlPoint1Y = 36.792;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 27.677;
+ controlPoint2Y = 36.47;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 27.631;
+ pointY = 27.546;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 27.631;
+ controlPoint1Y = 32.974;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 27.631;
+ controlPoint2Y = 29.892;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 27.677;
+ pointY = 19.726;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 27.631;
+ controlPoint1Y = 24.97;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 27.677;
+ controlPoint2Y = 21.612;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 19.535;
+ pointY = 21.336;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 25.331;
+ controlPoint1Y = 20.692;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 20.593;
+ controlPoint2Y = 21.336;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 19.443;
+ pointY = 22.762;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 19.397;
+ controlPoint1Y = 21.52;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 19.305;
+ controlPoint2Y = 22.532;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 21.283;
+ pointY = 23.82;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 20.639;
+ controlPoint1Y = 23.222;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 20.961;
+ controlPoint2Y = 23.452;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 21.605;
+ pointY = 24.97;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 21.513;
+ controlPoint1Y = 24.05;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 21.605;
+ controlPoint2Y = 24.602;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 21.651;
+ pointY = 29.156;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 21.651;
+ controlPoint1Y = 25.752;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 21.651;
+ controlPoint2Y = 27.592;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 21.605;
+ pointY = 35.228;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 21.651;
+ controlPoint1Y = 31.364;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 21.651;
+ controlPoint2Y = 34.216;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 20.823;
+ pointY = 37.022;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 21.559;
+ controlPoint1Y = 36.332;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 21.467;
+ controlPoint2Y = 36.838;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 19.121;
+ pointY = 37.436;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 20.363;
+ controlPoint1Y = 37.206;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 19.857;
+ controlPoint2Y = 37.298;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 19.121;
+ pointY = 39.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 18.937;
+ controlPoint1Y = 37.62;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 18.983;
+ controlPoint2Y = 38.77;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 24.503;
+ pointY = 38.862;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 20.271;
+ controlPoint1Y = 39.0;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 21.927;
+ controlPoint2Y = 38.862;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 30.023;
+ pointY = 39.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 27.401;
+ controlPoint1Y = 38.862;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 29.149;
+ controlPoint2Y = 39.0;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 30.253;
+ pointY = 37.436;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 30.299;
+ controlPoint1Y = 38.77;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 30.391;
+ controlPoint2Y = 37.62;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 30.253;
+ pointY = 37.436;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 27.493;
+ pointY = 13.976;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 27.125;
+ pointY = 12.228;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 27.493;
+ controlPoint1Y = 13.608;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 27.401;
+ controlPoint2Y = 12.688;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 24.963;
+ pointY = 11.63;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 26.849;
+ controlPoint1Y = 11.998;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 26.113;
+ controlPoint2Y = 11.63;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 21.513;
+ pointY = 12.688;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 23.767;
+ controlPoint1Y = 11.63;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 22.203;
+ controlPoint2Y = 12.09;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 21.283;
+ pointY = 14.942;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 21.145;
+ controlPoint1Y = 13.148;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 21.145;
+ controlPoint2Y = 14.436;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 22.801;
+ pointY = 17.012;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 21.513;
+ controlPoint1Y = 15.908;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 21.973;
+ controlPoint2Y = 16.69;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 26.205;
+ pointY = 16.69;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 23.399;
+ controlPoint1Y = 17.288;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 25.791;
+ controlPoint2Y = 17.058;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 27.493;
+ pointY = 13.976;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 26.941;
+ controlPoint1Y = 16.046;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 27.493;
+ controlPoint2Y = 14.896;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 27.493;
+ pointY = 13.976;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 30.851;
+ pointY = 38.862;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ color = "#FFFFFF";
+ context.fillStyle = color;
+ context.fill();
+
+ context.restore();
+}
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/Marks/questionMark.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Marks/questionMark.js
new file mode 100644
index 0000000..003c4c2
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Marks/questionMark.js
@@ -0,0 +1,438 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//
+// questionMark.js
+// ?
+//
+// Created by Giulio Cesare Solaroli on 3/7/10
+// Copyright 2010 Clipperz
+// This code was generated by Opacity. You may use or modify it in any way.
+//
+
+var kClipperz_PM_UI_Canvas_Marks_questionMarkWidth = 50.0;
+var kClipperz_PM_UI_Canvas_Marks_questionMarkHeight = 50.0;
+
+function Clipperz_PM_UI_Canvas_Marks_questionMark(canvas, aColor)
+{
+ var context = canvas.getContext("2d");
+ var alignStroke;
+ var resolution;
+ var path;
+ var pointX;
+ var pointY;
+ var controlPoint1X;
+ var controlPoint1Y;
+ var controlPoint2X;
+ var controlPoint2Y;
+ var color;
+ if (window.devicePixelRatio)
+ resolution = window.devicePixelRatio;
+ else
+ resolution = 1.0;
+ resolution *= 0.5 * (canvas.width / kClipperz_PM_UI_Canvas_Marks_questionMarkWidth + canvas.height / kClipperz_PM_UI_Canvas_Marks_questionMarkHeight);
+
+ context.save();
+ context.scale(canvas.width / kClipperz_PM_UI_Canvas_Marks_questionMarkWidth, canvas.height / kClipperz_PM_UI_Canvas_Marks_questionMarkHeight);
+ context.clearRect(0.0, 0.0, kClipperz_PM_UI_Canvas_Marks_questionMarkWidth, kClipperz_PM_UI_Canvas_Marks_questionMarkHeight);
+
+ // Layer 1
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 24.118;
+ pointY = 24.464;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 24.854;
+ pointY = 23.406;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 24.118;
+ controlPoint1Y = 24.05;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 24.44;
+ controlPoint2Y = 23.636;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 29.454;
+ pointY = 20.6;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 26.418;
+ controlPoint1Y = 22.532;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 28.534;
+ controlPoint2Y = 21.566;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 30.282;
+ pointY = 17.794;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 29.868;
+ controlPoint1Y = 20.232;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 30.282;
+ controlPoint2Y = 19.082;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 27.2;
+ pointY = 12.688;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 30.282;
+ controlPoint1Y = 16.322;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 29.454;
+ controlPoint2Y = 14.344;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 21.312;
+ pointY = 10.664;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 25.636;
+ controlPoint1Y = 11.492;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 23.382;
+ controlPoint2Y = 10.664;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 19.886;
+ pointY = 11.124;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 20.898;
+ controlPoint1Y = 10.664;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 20.162;
+ controlPoint2Y = 10.894;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 18.0;
+ pointY = 14.666;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 19.104;
+ controlPoint1Y = 11.676;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 18.0;
+ controlPoint2Y = 14.068;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 18.598;
+ pointY = 15.586;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 18.0;
+ controlPoint1Y = 14.896;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 18.138;
+ controlPoint2Y = 15.494;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 19.794;
+ pointY = 15.908;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 19.012;
+ controlPoint1Y = 15.678;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 19.426;
+ controlPoint2Y = 15.77;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 25.36;
+ pointY = 20.002;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 22.508;
+ controlPoint1Y = 16.644;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 25.36;
+ controlPoint2Y = 17.886;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 24.21;
+ pointY = 21.704;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 25.36;
+ controlPoint1Y = 20.738;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 25.084;
+ controlPoint2Y = 21.198;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 19.058;
+ pointY = 24.326;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 23.106;
+ controlPoint1Y = 22.348;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 19.886;
+ controlPoint2Y = 23.774;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 18.506;
+ pointY = 25.936;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 18.736;
+ controlPoint1Y = 24.556;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 18.506;
+ controlPoint2Y = 25.338;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 20.898;
+ pointY = 29.064;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 18.506;
+ controlPoint1Y = 26.948;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 19.334;
+ controlPoint2Y = 28.42;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 22.048;
+ pointY = 29.156;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 21.22;
+ controlPoint1Y = 29.156;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 21.726;
+ controlPoint2Y = 29.202;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 25.268;
+ pointY = 27.592;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 22.508;
+ controlPoint1Y = 29.064;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 24.9;
+ controlPoint2Y = 27.96;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 25.406;
+ pointY = 26.856;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 25.406;
+ controlPoint1Y = 27.454;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 25.544;
+ controlPoint2Y = 26.994;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 24.118;
+ pointY = 24.464;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 24.578;
+ controlPoint1Y = 25.936;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 24.118;
+ controlPoint2Y = 24.786;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 24.118;
+ pointY = 24.464;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 23.06;
+ pointY = 31.962;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 20.53;
+ pointY = 32.928;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 22.186;
+ controlPoint1Y = 31.962;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 21.22;
+ controlPoint2Y = 32.33;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 19.426;
+ pointY = 35.458;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 19.794;
+ controlPoint1Y = 33.618;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 19.426;
+ controlPoint2Y = 34.538;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 20.392;
+ pointY = 38.08;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 19.426;
+ controlPoint1Y = 36.47;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 19.702;
+ controlPoint2Y = 37.344;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 22.738;
+ pointY = 39.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 21.128;
+ controlPoint1Y = 38.77;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 22.048;
+ controlPoint2Y = 39.0;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 25.544;
+ pointY = 38.034;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 23.796;
+ controlPoint1Y = 39.0;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 24.854;
+ controlPoint2Y = 38.724;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 26.556;
+ pointY = 35.55;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 26.188;
+ controlPoint1Y = 37.344;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 26.556;
+ controlPoint2Y = 36.194;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 25.452;
+ pointY = 32.744;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 26.556;
+ controlPoint1Y = 34.676;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 26.326;
+ controlPoint2Y = 33.618;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 23.06;
+ pointY = 31.962;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 24.854;
+ controlPoint1Y = 32.284;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 23.934;
+ controlPoint2Y = 31.962;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 23.06;
+ pointY = 31.962;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 32.214;
+ pointY = 38.402;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ color = "#FFFFFF";
+ context.fillStyle = color;
+ context.fill();
+
+ context.restore();
+}
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/RegisterButton/normal.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/RegisterButton/normal.js
new file mode 100644
index 0000000..288e0be
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/RegisterButton/normal.js
@@ -0,0 +1,403 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//
+// normal.js
+// normal
+//
+// Created by Giulio Cesare Solaroli on 3/24/10
+// Copyright 2010 Clipperz
+// This code was generated by Opacity. You may use or modify it in any way.
+//
+
+var kClipperz_PM_UI_Canvas_RegisterButton_normalWidth = 282.0;
+var kClipperz_PM_UI_Canvas_RegisterButton_normalHeight = 93.0;
+
+function Clipperz_PM_UI_Canvas_RegisterButton_normal(canvas, aBackgroundColor, aDarkBackgroundColor, aLightColor, aDarkColor, aStarColor)
+{
+ var context = canvas.getContext("2d");
+ var alignStroke;
+ var resolution;
+ var path;
+ var pointX;
+ var pointY;
+ var controlPoint1X;
+ var controlPoint1Y;
+ var controlPoint2X;
+ var controlPoint2Y;
+ var gradient;
+ var color;
+ if (window.devicePixelRatio)
+ resolution = window.devicePixelRatio;
+ else
+ resolution = 1.0;
+ resolution *= 0.5 * (canvas.width / kClipperz_PM_UI_Canvas_RegisterButton_normalWidth + canvas.height / kClipperz_PM_UI_Canvas_RegisterButton_normalHeight);
+
+ context.save();
+ context.scale(canvas.width / kClipperz_PM_UI_Canvas_RegisterButton_normalWidth, canvas.height / kClipperz_PM_UI_Canvas_RegisterButton_normalHeight);
+ context.clearRect(0.0, 0.0, kClipperz_PM_UI_Canvas_RegisterButton_normalWidth, kClipperz_PM_UI_Canvas_RegisterButton_normalHeight);
+
+ // background
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 241.0;
+ pointY = 80.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 274.0;
+ pointY = 47.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 259.103;
+ controlPoint1Y = 80.0;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 274.0;
+ controlPoint2Y = 65.103;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 274.0;
+ pointY = 45.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 241.0;
+ pointY = 12.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 274.0;
+ controlPoint1Y = 26.897;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 259.103;
+ controlPoint2Y = 12.0;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 60.0;
+ pointY = 12.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 27.0;
+ pointY = 45.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 41.897;
+ controlPoint1Y = 12.0;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 27.0;
+ controlPoint2Y = 26.897;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 27.0;
+ pointY = 47.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 60.0;
+ pointY = 80.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 27.0;
+ controlPoint1Y = 65.103;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 41.897;
+ controlPoint2Y = 80.0;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 241.0;
+ pointY = 80.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ gradient = context.createLinearGradient(150.5, 12.0, 150.5, 80.0);
+ gradient.addColorStop(0.0, aBackgroundColor);
+ gradient.addColorStop(1.0, aDarkBackgroundColor);
+ context.fillStyle = gradient;
+ context.fill();
+
+ // round
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 44.103;
+ pointY = 4.014;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 65.629;
+ pointY = 10.515;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 51.706;
+ controlPoint1Y = 4.217;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 59.185;
+ controlPoint2Y = 6.475;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 78.65;
+ pointY = 70.918;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 43.0;
+ pointY = 90.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 70.676;
+ controlPoint1Y = 82.788;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 57.23;
+ controlPoint2Y = 89.817;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 0.056;
+ pointY = 44.801;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 18.834;
+ controlPoint1Y = 90.07;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = -1.18;
+ controlPoint2Y = 68.879;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 44.103;
+ pointY = 4.014;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 1.242;
+ controlPoint1Y = 21.708;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 21.202;
+ controlPoint2Y = 3.72;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 44.103;
+ pointY = 4.014;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ gradient = context.createLinearGradient(39.326, 90, 39.326, 4.011);
+ gradient.addColorStop(0.0, aDarkColor);
+ gradient.addColorStop(1.0, aLightColor);
+ context.fillStyle = gradient;
+ context.fill();
+
+ // *
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 23.983;
+ pointY = 35.944;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 37.25;
+ pointY = 40.261;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 37.25;
+ pointY = 24.963;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 48.231;
+ pointY = 24.963;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 48.231;
+ pointY = 40.261;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 61.498;
+ pointY = 35.944;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 64.481;
+ pointY = 45.402;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 50.961;
+ pointY = 49.592;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 59.784;
+ pointY = 62.224;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 51.659;
+ pointY = 68.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 42.836;
+ pointY = 56.066;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 33.759;
+ pointY = 68.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 25.634;
+ pointY = 62.224;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 34.521;
+ pointY = 49.592;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 21.0;
+ pointY = 45.402;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 23.983;
+ pointY = 35.944;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 68.607;
+ pointY = 119.099;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ context.fillStyle = aStarColor;
+ context.fill();
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 212.0;
+ pointY = 125.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 213.0;
+ pointY = 125.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 212.5;
+ pointY = 124.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 212.0;
+ pointY = 125.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ gradient = context.createLinearGradient(212.5, 125.0, 212.5, 124.0);
+ color = "#FFFFFF";
+ gradient.addColorStop(0.0, color);
+ color = "#A9A9A9";
+ gradient.addColorStop(1.0, color);
+ context.fillStyle = gradient;
+ context.fill();
+
+ // flip
+
+ // Setup for Shadow Effect
+ color = "rgba(0.0%, 0.0%, 0.0%, 0.5)";
+ context.save();
+ context.shadowColor = color;
+ context.shadowBlur = 0.0;
+ context.shadowOffsetX = 2.0 * Math.cos(8.377) * resolution;
+ context.shadowOffsetY = 2.0 * Math.sin(8.377) * resolution;
+
+ // round
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 78.506;
+ pointY = 70.251;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 66.155;
+ pointY = 12.954;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 59.899;
+ controlPoint1Y = 57.427;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 54.678;
+ controlPoint2Y = 32.277;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 78.506;
+ pointY = 70.251;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ gradient = context.createLinearGradient(69.301, 70.251, 69.301, 12.954);
+ gradient.addColorStop(0.0, aDarkColor);
+ gradient.addColorStop(1.0, aLightColor);
+ context.fillStyle = gradient;
+ context.fill();
+
+ // Shadow Effect
+ context.restore();
+
+ context.restore();
+}
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/Star/normal.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Star/normal.js
new file mode 100644
index 0000000..e70e3b5
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Star/normal.js
@@ -0,0 +1,153 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//
+// normal.js
+// normal
+//
+// Created by Giulio Cesare Solaroli on 3/15/10
+// Copyright 2010 Clipperz
+// This code was generated by Opacity. You may use or modify it in any way.
+//
+
+var kClipperz_PM_UI_Canvas_Star_normalWidth = 46.0;
+var kClipperz_PM_UI_Canvas_Star_normalHeight = 46.0;
+
+function Clipperz_PM_UI_Canvas_Star_normal(canvas, aColor)
+{
+ var context = canvas.getContext("2d");
+ var alignStroke;
+ var resolution;
+ var path;
+ var pointX;
+ var pointY;
+ if (window.devicePixelRatio)
+ resolution = window.devicePixelRatio;
+ else
+ resolution = 1.0;
+ resolution *= 0.5 * (canvas.width / kClipperz_PM_UI_Canvas_Star_normalWidth + canvas.height / kClipperz_PM_UI_Canvas_Star_normalHeight);
+
+ context.save();
+ context.scale(canvas.width / kClipperz_PM_UI_Canvas_Star_normalWidth, canvas.height / kClipperz_PM_UI_Canvas_Star_normalHeight);
+ context.clearRect(0.0, 0.0, kClipperz_PM_UI_Canvas_Star_normalWidth, kClipperz_PM_UI_Canvas_Star_normalHeight);
+
+ // *
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 8.613;
+ pointY = 15.583;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 18.563;
+ pointY = 18.821;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 18.563;
+ pointY = 7.347;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 26.799;
+ pointY = 7.347;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 26.799;
+ pointY = 18.821;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 36.749;
+ pointY = 15.583;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 38.986;
+ pointY = 22.677;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 28.846;
+ pointY = 25.819;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 35.463;
+ pointY = 35.293;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 29.369;
+ pointY = 39.625;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 22.752;
+ pointY = 30.675;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 15.944;
+ pointY = 39.625;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 9.85;
+ pointY = 35.293;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 16.515;
+ pointY = 25.819;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 6.375;
+ pointY = 22.677;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 8.613;
+ pointY = 15.583;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ pointX = 42.081;
+ pointY = 77.949;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ context.fillStyle = aColor;
+ context.fill();
+
+ context.restore();
+}
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/Tips/close.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Tips/close.js
new file mode 100644
index 0000000..216fd24
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Tips/close.js
@@ -0,0 +1,156 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//
+// close.js
+// close
+//
+// Created by Giulio Cesare Solaroli on 3/14/10
+// Copyright 2010 Clipperz
+// This code was generated by Opacity. You may use or modify it in any way.
+//
+
+var kClipperz_PM_UI_Canvas_Tips_closeWidth = 310.0;
+var kClipperz_PM_UI_Canvas_Tips_closeHeight = 6.0;
+
+function Clipperz_PM_UI_Canvas_Tips_close(canvas, aColor, aBackgroundColor)
+{
+ var context = canvas.getContext("2d");
+ var alignStroke;
+ var resolution;
+ var path;
+ var pointX;
+ var pointY;
+ if (window.devicePixelRatio)
+ resolution = window.devicePixelRatio;
+ else
+ resolution = 1.0;
+ resolution *= 0.5 * (canvas.width / kClipperz_PM_UI_Canvas_Tips_closeWidth + canvas.height / kClipperz_PM_UI_Canvas_Tips_closeHeight);
+
+ context.save();
+ context.scale(canvas.width / kClipperz_PM_UI_Canvas_Tips_closeWidth, canvas.height / kClipperz_PM_UI_Canvas_Tips_closeHeight);
+ context.clearRect(0.0, 0.0, kClipperz_PM_UI_Canvas_Tips_closeWidth, kClipperz_PM_UI_Canvas_Tips_closeHeight);
+
+ // background
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 310.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 310.0;
+ pointY = 0.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 0.0;
+ pointY = 0.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 0.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 310.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aBackgroundColor;
+ context.fill();
+
+ // grid
+
+ // background
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 310.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 310.0;
+ pointY = 0.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 0.0;
+ pointY = 0.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 0.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 310.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aBackgroundColor;
+ context.fill();
+
+ // toggle
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 149.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 161.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 155.0;
+ pointY = 0.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 149.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aColor;
+ context.fill();
+
+ context.restore();
+}
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Canvas/Tips/open.js b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Tips/open.js
new file mode 100644
index 0000000..f1bdaa9
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Canvas/Tips/open.js
@@ -0,0 +1,163 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//
+// open.js
+// open
+//
+// Created by Giulio Cesare Solaroli on 3/14/10
+// Copyright 2010 Clipperz
+// This code was generated by Opacity. You may use or modify it in any way.
+//
+
+var kClipperz_PM_UI_Canvas_Tips_openWidth = 310.0;
+var kClipperz_PM_UI_Canvas_Tips_openHeight = 6.0;
+
+function Clipperz_PM_UI_Canvas_Tips_open(canvas, aColor, aBackgroundColor)
+{
+ var context = canvas.getContext("2d");
+ var alignStroke;
+ var resolution;
+ var path;
+ var pointX;
+ var pointY;
+ var color;
+ if (window.devicePixelRatio)
+ resolution = window.devicePixelRatio;
+ else
+ resolution = 1.0;
+ resolution *= 0.5 * (canvas.width / kClipperz_PM_UI_Canvas_Tips_openWidth + canvas.height / kClipperz_PM_UI_Canvas_Tips_openHeight);
+
+ context.save();
+ context.scale(canvas.width / kClipperz_PM_UI_Canvas_Tips_openWidth, canvas.height / kClipperz_PM_UI_Canvas_Tips_openHeight);
+ context.clearRect(0.0, 0.0, kClipperz_PM_UI_Canvas_Tips_openWidth, kClipperz_PM_UI_Canvas_Tips_openHeight);
+
+ // background
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 310.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 310.0;
+ pointY = 0.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 0.0;
+ pointY = 0.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 0.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 310.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aBackgroundColor;
+ context.fill();
+
+ // grid
+
+ // background
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 310.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 310.0;
+ pointY = 0.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 0.0;
+ pointY = 0.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 0.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 310.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ context.fillStyle = aBackgroundColor;
+ context.fill();
+
+ // Layer 1
+
+ alignStroke = 0.0;
+ context.save();
+ context.translate(155.0, 3.0);
+ context.rotate(-3.142);
+ context.translate(-155.0, -3.0);
+ context.beginPath();
+ pointX = 149.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 161.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 155.0;
+ pointY = 0.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 149.0;
+ pointY = 6.0;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ color = "#FFFFFF";
+ context.fillStyle = color;
+ context.fill();
+ context.restore();
+
+ context.restore();
+}
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/BaseComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/BaseComponent.js
new file mode 100644
index 0000000..26f2fc4
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/BaseComponent.js
@@ -0,0 +1,611 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Common.Components');
+
+//#############################################################################
+
+var _Clipperz_PM_Components_base_id_ = 0;
+
+//#############################################################################
+
+Clipperz.PM.UI.Common.Components.BaseComponent = function(args) {
+ args = args || {};
+ Clipperz.PM.UI.Common.Components.BaseComponent.superclass.constructor.call(this, args);
+
+ this._element = args.element || null;
+ this._ids = {};
+
+ this._slots = {};
+ this._slotComponents = {};
+
+ this._components = {};
+
+ this._cachedSlots = {};
+
+ this._isModal = false;
+
+ this._isActive = false;
+ this._elementUsedToEnterModalState;
+
+ this._isFullyRendered = false;
+ this._renderingWaitingQueue = [];
+
+// this._slots = {
+// 'header': 'header',
+// 'body': 'body',
+// 'footer': 'footer'
+// };
+
+ return this;
+}
+
+//=============================================================================
+
+//TODO get back to MochiKit.Base.update as we are not extending anything
+//MochiKit.Base.update(Clipperz.PM.UI.Common.Components.BaseComponent.prototype, {
+Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.BaseComponent, /*Ext.Component*/ Object, {
+
+ 'isClipperzPMComponent': true,
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Common.Components.BaseComponent component";
+ },
+
+ 'componentId': function () {
+ return this.getId('_id_');
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'slots': function() {
+ return this._slots;
+ },
+*/
+ 'slotComponents': function() {
+ return this._slotComponents;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'components': function () {
+ return this._components;
+ },
+
+ 'addComponent': function (aComponent) {
+ this.components()[aComponent.componentId()] = aComponent;
+ },
+
+ 'removeComponent': function (aComponent) {
+ var componentId;
+
+ componentId = aComponent.componentId();
+ this.components()[componentId].remove();
+ delete this.components()[componentId];
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'domHelper': function() {
+ return Clipperz.YUI.DomHelper;
+ },
+*/
+ //-------------------------------------------------------------------------
+/*
+ 'domHelperAppend': function(aValue) {
+ Clipperz.YUI.DomHelper.append(this.element().dom, aValue);
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'element': function() {
+//MochiKit.Logging.logDebug(">>> BaseComponent.element");
+ return MochiKit.DOM.getElement(this._element);
+ },
+
+ 'setElement': function(aNode) {
+ this._element = aNode;
+ },
+
+ //-----------------------------------------------------
+
+ 'displayElement': function() {
+ return this.element();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderInNode': function(aDomNode) {
+ this.setElement(aDomNode);
+ this.render();
+ },
+
+ 'render': function() {
+ this.clear();
+ this.renderSelf();
+ this.renderComponents();
+ if (this.shouldShowTranslationHints()) {
+ this.renderTranslationHints();
+ }
+ if (this.shouldShowElementWhileRendering()) {
+ MochiKit.Style.showElement(this.displayElement());
+ };
+
+ this._isFullyRendered = true;
+
+ MochiKit.Iter.forEach(this.renderingWaitingQueue(), MochiKit.Base.methodcaller('callback'));
+ this.resetRenderingWaitingQueue();
+ },
+
+ 'renderSelf': function() {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ 'renderComponents': function() {
+ var slotName;
+
+ for (slotName in this.slotComponents()) {
+ this.slotComponents()[slotName].renderInNode(this.elementForSlotNamed(slotName));
+ }
+ },
+
+ //.........................................................................
+
+ 'isFullyRendered': function () {
+ return this._isFullyRendered;
+ },
+
+ //.........................................................................
+
+ 'renderingWaitingQueue': function () {
+ return this._renderingWaitingQueue;
+ },
+
+ 'resetRenderingWaitingQueue': function () {
+ this._renderingWaitingQueue = [];
+ },
+
+ //.........................................................................
+
+ 'waitUntilFullyRendered': function () {
+ var deferredResult;
+
+ if (this.isFullyRendered() == true) {
+ deferredResult = MochiKit.Async.succeed
+ } else {
+ deferredResult = new Clipperz.Async.Deferred("BaseComponent.waitUntilFullyRendered", {trace:false});
+ this.renderingWaitingQueue().push(deferredResult);
+ }
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------
+
+ 'renderTranslationHints': function () {
+ var translatableItems;
+
+ translatableItems = MochiKit.Selector.findChildElements(this.displayElement(), ['[stringID]']);
+ MochiKit.Iter.forEach(translatableItems, MochiKit.Base.method(this, 'enhanceTranslatableElement'))
+ },
+
+ 'enhanceTranslatableElement': function (anElement) {
+//Clipperz.log(">>> enhanceTranslatableElement", anElement);
+// new Clipperz.PM.UI.Common.Components.TranslatorWidget({
+// 'element': anElement
+// });
+
+ MochiKit.Signal.connect(anElement, 'onmouseenter', MochiKit.Base.partial(Clipperz.PM.UI.Common.Components.TranslatorWidget.show, anElement, MochiKit.DOM.getNodeAttribute(anElement, 'stringID')));
+ MochiKit.Signal.connect(anElement, 'onmouseleave', Clipperz.PM.UI.Common.Components.TranslatorWidget.hide);
+//Clipperz.log("<<< enhanceTranslatableElement");
+ },
+
+ //-----------------------------------------------------
+
+ 'update': function(args) {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ 'updateSelf': function(args) {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ 'updateComponents': function(args) {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //-----------------------------------------------------
+
+ 'refresh': function() {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ 'refreshSelf': function() {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ 'refreshComponents': function(args) {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ //-----------------------------------------------------
+
+ 'checkSlotNamed': function(aSlotName) {
+ if (typeof(this._slots[aSlotName]) == 'undefined') {
+ throw new Error("undefined slot");
+ };
+ },
+
+ //-----------------------------------------------------
+
+ 'cachedSlots': function() {
+ return this._cachedSlots;
+ },
+
+ 'slotNamed': function(aSlotName) {
+ var result;
+
+ this.checkSlotNamed(aSlotName);
+ if (typeof(this.cachedSlots()[aSlotName]) == 'undefined') {
+ this.cachedSlots()[aSlotName] = new Clipperz.PM.UI.Common.Components.ComponentSlot(this,aSlotName);
+ }
+
+ result = this.cachedSlots()[aSlotName];
+
+ return result;
+ },
+
+ //-----------------------------------------------------
+
+ 'elementForSlotNamed': function(aSlotName) {
+ return MochiKit.DOM.getElement(this._slots[aSlotName]);
+ },
+
+ //-----------------------------------------------------
+
+ 'componentForSlotNamed': function(aSlotName) {
+ return this.slotComponents()[aSlotName];
+ },
+
+ 'setComponentForSlotNamed': function(aComponent, aSlotName) {
+ var domNode;
+
+ this.checkSlotNamed(aSlotName);
+
+ if (this.slotComponents()[aSlotName] != null) {
+ this.slotComponents()[aSlotName].remove();
+ }
+
+ this.slotComponents()[aSlotName] = aComponent;
+
+// domNode = MochiKit.DOM.getElement(this.slotNamed(aSlotName));
+ domNode = this.elementForSlotNamed(aSlotName);
+
+ if (domNode != null) {
+ aComponent.renderInNode(domNode);
+ }
+ },
+
+ //-----------------------------------------------------
+/*
+ 'purgeListeners': function() {
+//MochiKit.Logging.logDebug(">>> Clipperz.PM.UI.Common.Components.BaseComponent.purgeListeners [" + this + "]");
+//MochiKit.Logging.logDebug("--- " + this + ".purgeListeners");
+ Clipperz.NotificationCenter.unregister(this);
+ MochiKit.Signal.disconnectAllTo(this);
+//MochiKit.Logging.logDebug("<<< Clipperz.PM.UI.Common.Components.BaseComponent.purgeListeners");
+ },
+*/
+ //-----------------------------------------------------
+
+ 'clear': function() {
+ var slotName;
+ var componentId;
+
+ MochiKit.Signal.disconnectAllTo(this);
+
+ for (slotName in this.slotComponents()) {
+ this.slotComponents()[slotName].clear();
+ }
+
+ for (componentId in this.components()) {
+ this.components()[componentId].clear();
+ }
+
+// if (this.element() != null) {
+// this.element().innerHTML = "";
+// }
+
+ if (this.displayElement() != null) {
+ if (this.element() != this.displayElement()) {
+ MochiKit.DOM.removeElement(this.displayElement());
+ } else {
+ this.displayElement().innerHTML = "";
+ }
+ }
+
+ if (this.isModal()) {
+ // TODO: cleanup when the closed element was shown modally.
+ }
+ },
+
+
+ 'remove': function() {
+ var slotName;
+ var componentId;
+
+ for (slotName in this.slotComponents()) {
+ this.slotComponents()[slotName].remove();
+ delete this.slotComponents()[slotName];
+ }
+
+ for (componentId in this.components()) {
+ this.components()[componentId].remove();
+ delete this.components()[componentId];
+ }
+
+ this.clear();
+ MochiKit.Signal.disconnectAll(this);
+ },
+
+ 'append': function(aNode, aValue) {
+ return Clipperz.DOM.Helper.append(aNode, aValue);
+ },
+
+ 'insertBefore': function (aNode, aValue) {
+ return Clipperz.DOM.Helper.insertBefore(aNode, aValue);
+ },
+
+ 'insertAfter': function (aNode, aValue) {
+ return Clipperz.DOM.Helper.insertAfter(aNode, aValue);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getId': function(aValue) {
+ var result;
+
+ if (typeof(aValue) != 'undefined') {
+ result = this._ids[aValue];
+
+ if (typeof(result) == 'undefined') {
+ _Clipperz_PM_Components_base_id_ ++;
+
+ result = "Clipperz_PM_Components_" + aValue + "_" + _Clipperz_PM_Components_base_id_;
+ this._ids[aValue] = result;
+ }
+ } else {
+// result = Clipperz.PM.UI.Common.Components.BaseComponent.superclass.getId.call(this);
+ throw "call to BaseComponent.getId with an undefined value";
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getElement': function(aValue) {
+ return Clipperz.DOM.get(this.getId(aValue));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hideElement': function(anElementName) {
+ MochiKit.Style.hideElement(this.getElement(anElementName));
+ },
+
+ 'showElement': function(anElementName) {
+ MochiKit.Style.showElement(this.getElement(anElementName));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'activate': function () {
+ this._isActive = true;
+ },
+
+ 'deactivate': function () {
+ this._isActive = false;
+ },
+
+ 'isActive': function () {
+ return this._isActive;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hideSlot': function(aSlotName) {
+ if (this.componentForSlotNamed(aSlotName)) {
+ this.componentForSlotNamed(aSlotName).deactivate();
+ }
+ MochiKit.Style.hideElement(this.elementForSlotNamed(aSlotName));
+ },
+
+ 'showSlot': function(aSlotName) {
+ if (this.componentForSlotNamed(aSlotName)) {
+ this.componentForSlotNamed(aSlotName).activate();
+ }
+ MochiKit.Style.showElement(this.elementForSlotNamed(aSlotName));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'shouldShowTranslationHints': function () {
+ return false;
+ },
+
+ 'shouldShowElementWhileRendering': function() {
+ return true;
+ },
+
+// 'shouldRemoveElementWhenClearningUp': function () {
+// return true;
+// },
+
+ //-------------------------------------------------------------------------
+
+ 'isModal': function() {
+ return this._isModal;
+ },
+
+ 'setIsModal': function(aValue) {
+ this._isModal = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'elementUsedToEnterModalState': function () {
+ return this._elementUsedToEnterModalState;
+ },
+
+ 'setElementUsedToEnterModalState': function (aValue) {
+ this._elementUsedToEnterModalState = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'modalDialogMask': function () {
+ return 'modalDialogMask';
+ },
+
+ 'modalDialog': function () {
+ return 'modalDialog';
+ },
+
+ 'modalDialogFrame': function() {
+ return 'modalDialogFrame'
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredShowModal': function(args) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("BaseComponent.deferredShowModal", {trace:false});
+
+ deferredResult.addMethod(this, 'setIsModal', true);
+ deferredResult.addCallback(MochiKit.Style.showElement, this.modalDialogMask());
+ deferredResult.addCallback(MochiKit.Base.bind(function(someArgs) {
+ var result;
+ var duration;
+ var from;
+ var to;
+
+ duration = someArgs.duration || 0.4;
+
+ this.setElementUsedToEnterModalState(someArgs.openFromElement);
+ from = Clipperz.Style.getSizeAndPosition(someArgs.openFromElement);
+ this.renderInNode(this.modalDialog());
+ MochiKit.DOM.addElementClass(this.modalDialog(), 'fixed');
+ to = Clipperz.Style.getSizeAndPosition(this.displayElement());
+ Clipperz.PM.UI.Common.Components.BaseComponent.targetModalDimensionsAndPosition = Clipperz.Base.deepClone(to);
+
+ MochiKit.Style.hideElement(this.displayElement());
+ MochiKit.Style.showElement(this.modalDialogFrame());
+
+ result = {from:from, to:to, duration:duration};
+ return result;
+ }, this, args));
+ deferredResult.addCallback(Clipperz.Visual.deferredResize, this.modalDialogFrame());
+ deferredResult.addCallback(MochiKit.Base.bind(function(someArgs) {
+ MochiKit.Style.hideElement(this.modalDialogFrame());
+ MochiKit.Style.showElement(this.displayElement());
+ }, this));
+ deferredResult.addCallback(MochiKit.Async.succeed, arguments[arguments.length - 1]);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredHideModal': function(args) {
+ var deferredResult;
+
+ args = args || {};
+
+ deferredResult = new Clipperz.Async.Deferred("BaseComponent.deferredHideModal", {trace:false});
+ deferredResult.addCallback(MochiKit.Base.bind(function(someArgs) {
+ var result;
+ var from;
+ var toElement;
+ var to;
+ var duration;
+
+ toElement = args.closeToElement || this.elementUsedToEnterModalState();
+ duration = someArgs.duration || 0.4;
+ from = Clipperz.Style.getSizeAndPosition(this.displayElement());
+ to = Clipperz.Style.getSizeAndPosition(toElement);
+
+ MochiKit.Style.hideElement(this.displayElement());
+ MochiKit.Style.showElement(this.modalDialogFrame());
+
+ result = {from:from, to:to, duration:duration};
+ return result;
+ }, this, args));
+ deferredResult.addCallback(Clipperz.Visual.deferredResize, this.modalDialogFrame());
+ deferredResult.addCallback(MochiKit.Base.bind(function() {
+ MochiKit.Style.hideElement(this.modalDialogFrame());
+ MochiKit.Style.hideElement(this.modalDialogMask());
+ }, this));
+ deferredResult.addMethod(this, 'setIsModal', false);
+ deferredResult.addMethod(this, 'clear'); // ##############
+ deferredResult.addCallback(MochiKit.Async.succeed, arguments[arguments.length - 1]);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+
+});
+
+Clipperz.PM.UI.Common.Components.BaseComponent_modalDialog = function() {
+ Clipperz.DOM.Helper.append(MochiKit.DOM.currentDocument().body,
+ {tag:'div', id:'modalDialogWrapper', cls:'modalDialogWrapper', children:[
+ {tag:'div', id:'modalDialogMask', cls:'modalDialogMask'},
+ {tag:'div', id:'modalDialogFrame', cls:'modalDialogFrame' /*, html:"modal dialog frame"*/},
+ {tag:'div', id:'modalDialog', cls:'modalDialog'}
+// {tag:'div', id:'modalDialog', cls:'modalDialog', children:[{tag:'div'}]}
+ ]}
+ );
+
+// MochiKit.Style.hideElement('modalDialogWrapper');
+ MochiKit.Style.hideElement('modalDialogMask');
+ MochiKit.Style.hideElement('modalDialogFrame');
+// MochiKit.Style.hideElement('modalDialog');
+
+};
+
+//Clipperz.PM.UI.Common.Components.BaseComponent.targetModalDimensionsAndPosition = {'x':'X', 'y':'Y'};
+
+MochiKit.DOM.addLoadEvent(Clipperz.PM.UI.Common.Components.BaseComponent_modalDialog);
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/Button.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/Button.js
new file mode 100644
index 0000000..b2761ea
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/Button.js
@@ -0,0 +1,108 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Common.Components');
+
+Clipperz.PM.UI.Common.Components.Button = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Common.Components.Button.superclass.constructor.apply(this, arguments);
+
+ this._element = args.element || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._text = args.text || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._isDefault = args.isDefault || false;
+
+ this.render();
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.Button, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Common.Components.Button component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'text': function () {
+ return this._text;
+ },
+
+ 'isDefault': function () {
+ return this._isDefault;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function () {
+ this.append(this.element(), {tag:'div', id:this.getId('wrapper'), cls:'button_wrapper', children:[
+ {tag:'div', id:this.getId('bodyWrapper'), cls:'button_bodyWrapper', children:[
+ {tag:'div', id:this.getId('body'), cls:'button_body', children:[
+ {tag:'span', html:this.text()}
+ ]},
+ {tag:'div', id:this.getId('footer'), cls:'button_footer'}
+ ]}
+ ]});
+
+ if (this.isDefault()) {
+ MochiKit.DOM.addElementClass(this.getId('wrapper'), 'default');
+ }
+
+ MochiKit.Signal.connect(this.getId('wrapper'), 'onmouseenter', this, 'handleOnMouseEnter');
+ MochiKit.Signal.connect(this.getId('wrapper'), 'onmouseleave', this, 'handleOnMouseLeave');
+ MochiKit.Signal.connect(this.getId('wrapper'), 'onmousedown', this, 'handleOnMouseDown');
+ MochiKit.Signal.connect(this.getId('wrapper'), 'onclick', this, 'handleOnClick');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleOnMouseEnter': function (anEvent) {
+ MochiKit.DOM.addElementClass(this.getId('wrapper'), 'hover');
+ },
+
+ 'handleOnMouseLeave': function (anEvent) {
+ MochiKit.DOM.removeElementClass(this.getId('wrapper'), 'hover');
+ MochiKit.DOM.removeElementClass(this.getId('wrapper'), 'clicked');
+ },
+
+ 'handleOnMouseDown': function (anEvent) {
+ MochiKit.DOM.addElementClass(this.getId('wrapper'), 'clicked');
+ },
+
+ 'handleOnClick': function (anEvent) {
+ MochiKit.Signal.signal(this, 'onclick', anEvent);
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/ComponentSlot.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/ComponentSlot.js
new file mode 100644
index 0000000..0c6e221
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/ComponentSlot.js
@@ -0,0 +1,64 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Common.Components');
+
+//#############################################################################
+
+
+Clipperz.PM.UI.Common.Components.ComponentSlot = function(aComponent, aSlotName) {
+ this._component = aComponent;
+ this._slotName = aSlotName;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.ComponentSlot, Object, {
+
+ //-------------------------------------------------------------------------
+
+ 'slotName': function() {
+ return this._slotName;
+ },
+
+ 'component': function() {
+ return this._component;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setContent': function(aComponent) {
+ this.component().setComponentForSlotNamed(aComponent, this.slotName());
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/FaviconComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/FaviconComponent.js
new file mode 100644
index 0000000..4735f5c
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/FaviconComponent.js
@@ -0,0 +1,91 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Common.Components');
+
+Clipperz.PM.UI.Common.Components.FaviconComponent = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Common.Components.FaviconComponent.superclass.constructor.apply(this, arguments);
+
+ this.render();
+ this.setSrc(args.src);
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.FaviconComponent, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Common.Components.FaviconComponent component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'src': function () {
+ return this.element().src;
+ },
+
+ 'setSrc': function (aValue) {
+ this.element().src = (aValue || Clipperz.PM.Strings.getValue('defaultFaviconUrl'));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'clear': function () {},
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function () {
+ MochiKit.Signal.connect(this.element(), 'onerror', this, 'setDefaultFavicon');
+ MochiKit.Signal.connect(this.element(), 'onabort', this, 'setDefaultFavicon');
+ MochiKit.Signal.connect(this.element(), 'onload', this, 'handleOnLoad');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setDefaultFavicon': function (anEvent) {
+ MochiKit.Signal.disconnectAll(anEvent.src());
+ this.setSrc(null);
+ },
+
+ 'handleOnLoad': function (anEvent) {
+ MochiKit.Signal.disconnectAll(anEvent.src());
+//console.log("HANDLE ON LOAD", anEvent, anEvent.src().src);
+ if (anEvent.src().complete == false) {
+ this.setSrc(null);
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/MessagePanelWithProgressBar.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/MessagePanelWithProgressBar.js
new file mode 100644
index 0000000..275bbed
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/MessagePanelWithProgressBar.js
@@ -0,0 +1,164 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Common.Components');
+
+Clipperz.PM.UI.Common.Components.MessagePanelWithProgressBar = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Common.Components.MessagePanelWithProgressBar.superclass.constructor.apply(this, arguments);
+
+// this._openFromElement = args.openFromElement || null;
+ this._onOkCloseToElement = args.onOkCloseToElement || null;
+ this._onCancelCloseToElement = args.onCancelCloseToElement || null;
+
+ this._canCancelWhileProcessing = ((typeof(args.canCancelWhileProcessing) == 'undefined') ? true : args.canCancelWhileProcessing);
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.MessagePanelWithProgressBar, Clipperz.PM.UI.Common.Components.SimpleMessagePanel, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Common.Components.MessagePanelWithProgressBar component";
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'openFromElement': function () {
+ return this._openFromElement;
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'onOkCloseToElement': function () {
+ return this._onOkCloseToElement;
+ },
+
+ 'setOnOkCloseToElement': function (anElement) {
+ this._onOkCloseToElement = anElement;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'onCancelCloseToElement': function () {
+ return this._onCancelCloseToElement;
+ },
+
+ 'setOnCancelCloseToElement': function (anElement) {
+ this._onCancelCloseToElement = anElement;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'canCancelWhileProcessing': function () {
+ return this._canCancelWhileProcessing;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredShowModal': function (someArgs, aResult) {
+ if (someArgs['onOkCloseToElement'] != null) {
+ this.setOnOkCloseToElement(someArgs['onOkCloseToElement']);
+ }
+
+ if (someArgs['onCancelCloseToElement'] != null) {
+ this.setOnCancelCloseToElement(someArgs['onCancelCloseToElement']);
+ }
+
+ Clipperz.PM.UI.Common.Components.MessagePanelWithProgressBar.superclass.deferredShowModal.apply(this, arguments);
+ return this.deferred();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'showProgressBar': function () {
+ var progressBarElement;
+
+ this.getElement('container').innerHTML = '';
+
+ progressBarElement = this.append(this.getElement('container'), {tag:'div', cls:'progressBarWrapper'});
+ this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':progressBarElement}));
+
+ if (this.canCancelWhileProcessing() == true) {
+ this.setButtons([{text:"Cancel", result:'CANCEL'}]);
+ } else {
+ this.setButtons([]);
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'showFailure': function (someParameters) {
+// this.setType('ALERT');
+ this.setType(someParameters['type']);
+// this.setTitle("Login failed");
+ this.setTitle(someParameters['title']);
+// this.setText("Wrong passphrase; the unlock has failed.");
+ this.setText(someParameters['text']);
+// this.getElement('container').innerHTML = '';
+ this.getElement('container').innerHTML = '';
+// this.setButtons([{text:"Close", result:'CANCEL', isDefault:true}]);
+ this.setButtons(someParameters['buttons']);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'closeOk': function () {
+//console.log("=== closeOk");
+ this.showProgressBar();
+ MochiKit.Async.callLater(0.5, MochiKit.Base.method(this.deferred(), 'callback'));
+ this._deferred = null;
+ },
+
+ 'closeCancel': function () {
+//console.log("=== closeCancel");
+ this.deferredHideModal({closeToElement:this.onCancelCloseToElement()});
+ this.deferred().cancel();
+ this._deferred = null;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredDone': function () {
+//console.log("=== deferredDone");
+ return this.deferredHideModal({closeToElement:this.onOkCloseToElement()});
+ },
+
+ 'deferredError': function (someParameters) {
+//console.log("=== deferredError");
+ this.showFailure(someParameters);
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js
new file mode 100644
index 0000000..c1b4f13
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js
@@ -0,0 +1,140 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Common.Components');
+
+Clipperz.PM.UI.Common.Components.PasswordEntropyDisplay = function(anElement, args) {
+ args = args || {};
+
+//MochiKit.Logging.logDebug(">>> new TextFormField");
+ Clipperz.PM.UI.Common.Components.PasswordEntropyDisplay.superclass.constructor.call(this, anElement, args);
+
+ this._wrapperElement = null;
+ this._entropyElement = null;
+
+ this.render();
+//MochiKit.Logging.logDebug("<<< new TextFormField");
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.PasswordEntropyDisplay, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Common.Components.PasswordEntropyDisplay";
+ },
+
+ //-----------------------------------------------------
+
+ 'wrapperElement': function() {
+ return this._wrapperElement;
+ },
+
+ 'setWrapperElement': function(aValue) {
+ this._wrapperElement = aValue;
+ },
+
+ //-----------------------------------------------------
+
+ 'passwordElement': function() {
+ return this.element();
+ },
+
+ //-----------------------------------------------------
+
+ 'entropyElement': function() {
+ return this._entropyElement;
+ },
+
+ 'setEntropyElement': function(aValue) {
+ this._entropyElement = aValue;
+ },
+
+ //-----------------------------------------------------
+
+ 'render': function() {
+/*
+ MochiKit.Signal.disconnectAllTo(this);
+
+ this.setWrapperElement(this.element().wrap({tag:'div'}));
+ this.setEntropyElement(Clipperz.DOM.Helper.append(this.wrapperElement().dom, {tag:'div', cls:'passwordEntropy', html:"&nbsp;"}, true));
+// this.setEntropyElement(Clipperz.DOM.Helper.insertBefore(this.element(), {tag:'div', cls:'passwordEntropy', html:"&nbsp;"}, true));
+ this.entropyElement().wrap({tag:'div', cls:'passwordEntropyWrapper'});
+
+ this.updateEntropyElement();
+
+ this.connect('onkeyup', 'updateEntropyElement');
+ this.connect('onchange', 'updateEntropyElement');
+ this.connect('onblur', 'updateEntropyElement');
+*/
+ MochiKit.Signal.disconnectAllTo(this);
+
+ this.setEntropyElement(this.element());
+ this.entropyElement().addClass("entropyLevelIndicator");
+
+ this.updateEntropyElement();
+
+ this.connect('onkeyup', 'updateEntropyElement');
+ this.connect('onchange', 'updateEntropyElement');
+ this.connect('onblur', 'updateEntropyElement');
+ },
+
+ //-----------------------------------------------------
+
+ 'computeEntropyForString': function(aValue) {
+ return Clipperz.PM.Crypto.passwordEntropy(aValue);
+ },
+
+ //-----------------------------------------------------
+
+ 'updateEntropyElement': function(anEvent) {
+/*
+//MochiKit.Logging.logDebug(">>> PasswordEntropyDisplay.updateEntropyElement");
+ var maxExtent;
+ var entropy;
+
+ entropy = Math.min(128, this.computeEntropyForString(this.passwordElement().dom.value));
+//MochiKit.Logging.logDebug("--- PasswordEntropyDisplay.updateEntropyElement - entropy: " + entropy);
+ this.entropyElement().setStyle('background-position', "0px " + -entropy + "px");
+ this.entropyElement().setWidth(this.passwordElement().getWidth() * (entropy/128));
+//MochiKit.Logging.logDebug("<<< PasswordEntropyDisplay.updateEntropyElement");
+*/
+ var entropy;
+
+ entropy = Math.min(128, this.computeEntropyForString(this.passwordElement().dom.value));
+
+ if (entropy == 0) {
+ this.entropyElement().setStyle('background-position', "0px 26px");
+ } else {
+ this.entropyElement().setStyle('background-position', "0px -" + (128-entropy)*26 + "px");
+ }
+ },
+
+ //-----------------------------------------------------
+ __syntaxFix__: '__syntaxFix__'
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/ProgressBar.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/ProgressBar.js
new file mode 100644
index 0000000..7e7f8fe
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/ProgressBar.js
@@ -0,0 +1,73 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Common.Components');
+
+Clipperz.PM.UI.Common.Components.ProgressBar = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Common.Components.ProgressBar.superclass.constructor.apply(this, arguments);
+
+ this._element = args.element || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ this.renderSelf();
+
+ MochiKit.Signal.connect(Clipperz.PM.UI.Common.Controllers.ProgressBarController.defaultController, 'updateProgress', this, 'updateProgressHandler')
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.ProgressBar, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Common.Components.ProgressBar component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function() {
+ this.append(this.element(), {tag:'div', cls:'loadingBar', children:[
+ {tag:'div', cls:'loadingBarProgressBox', children:[
+ {tag:'div', id:this.getId('loadingBarProgress'), cls:'loadingBarProgress'}
+ ]}
+ ]});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateProgressHandler': function (anEvent) {
+ MochiKit.Style.setElementDimensions(this.getId('loadingBarProgress'), {w:anEvent}, '%');
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js
new file mode 100644
index 0000000..b9bb850
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js
@@ -0,0 +1,282 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Common.Components.SimpleMessagePanel = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Common.Components.SimpleMessagePanel.superclass.constructor.apply(this, arguments);
+
+ this._title = args.title || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._text = args.text || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._type = args.type || Clipperz.Base.exception.raise('MandatoryParameter'); // ALERT, INFO, ERROR
+ this._buttons = args.buttons || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ this._buttonComponents = [];
+ this._deferred = null;
+
+ this.renderModalMask();
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.SimpleMessagePanel, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Common.Components.SimpleMessagePanel component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferred': function() {
+ if (this._deferred == null) {
+ this._deferred = new Clipperz.Async.Deferred("SimpleMessagePanel.deferred", {trace:false});
+ }
+
+ return this._deferred;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'title': function () {
+ return this._title;
+ },
+
+ 'setTitle': function (aValue) {
+ this._title = aValue;
+
+ if (this.getElement('title') != null) {
+ this.getElement('title').innerHTML = aValue;
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'text': function () {
+ return this._text;
+ },
+
+ 'setText': function (aValue) {
+ this._text = aValue;
+
+ if (this.getElement('text') != null) {
+ this.getElement('text').innerHTML = aValue;
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'type': function () {
+ return this._type;
+ },
+
+ 'setType': function (aValue) {
+ if (this.getElement('icon') != null) {
+ MochiKit.DOM.removeElementClass(this.getId('icon'), this._type);
+ MochiKit.DOM.addElementClass(this.getId('icon'), aValue);
+ }
+
+ this._type = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'buttons': function () {
+ return this._buttons;
+ },
+
+ 'setButtons': function (someValues) {
+ MochiKit.Iter.forEach(this.buttonComponents(), MochiKit.Base.methodcaller('clear'));
+
+ this._buttons = someValues;
+
+ if (this.getElement('buttonArea') != null) {
+ this.renderButtons();
+ }
+ },
+
+ //.........................................................................
+
+ 'buttonComponents': function () {
+ return this._buttonComponents;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function() {
+ this.append(this.element(), {tag:'div', cls:'SimpleMessagePanel', id:this.getId('panel'), children: [
+ {tag:'div', cls:'header', children:[]},
+ {tag:'div', cls:'body', children:[
+ {tag:'div', id:this.getId('icon'), cls:'img ' + this.type(), children:[{tag:'div'}]},
+ {tag:'h3', id:this.getId('title'), html:this.title()},
+ {tag:'p', id:this.getId('text'), html:this.text()},
+ {tag:'div', id:this.getId('container')},
+ {tag:'div', id:this.getId('buttonArea'), cls:'buttonArea', children:[]}
+ ]},
+ {tag:'div', cls:'footer', children:[]}
+ ]});
+
+ MochiKit.Signal.connect(this.getId('panel'), 'onkeydown', this, 'keyDownHandler');
+
+ this.renderButtons();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderButtons': function () {
+ this.getElement('buttonArea').innerHTML = '';
+
+ MochiKit.Base.map(MochiKit.Base.bind(function (aButton) {
+ var buttonElement;
+ var buttonComponent;
+
+// element = this.append(this.getElement('buttonArea'), {tag:'div', cls:'button' + (aButton['isDefault'] === true ? ' default' : ''), children:[
+// {tag:'a', href:'#'/*, id:this.getId('buttonLink')*/, html:aButton['text']}
+// ]});
+
+ buttonElement = this.append(this.getElement('buttonArea'), {tag:'div'});
+ buttonComponent = new Clipperz.PM.UI.Common.Components.Button({'element':buttonElement, 'text':aButton['text'], 'isDefault':aButton['isDefault']});
+ this.buttonComponents().push(buttonComponent);
+
+ MochiKit.Signal.connect(buttonComponent, 'onclick', MochiKit.Base.method(this, 'buttonEventHandler', aButton));
+ }, this), MochiKit.Iter.reversed(this.buttons()));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'displayElement': function() {
+ return this.getElement('panel');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'closeOk': function () {
+ this.deferred().callback();
+ this._deferred = null;
+ },
+
+ 'closeCancel': function () {
+ this.deferred().cancel();
+ this._deferred = null;
+ },
+
+ 'closeError': function () {
+ this.deferred().errback();
+ this._deferred = null;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'buttonEventHandler': function(aButton, anEvent) {
+ anEvent.preventDefault();
+
+// MochiKit.Signal.signal(this, 'cancelEvent');
+ switch (aButton['result']) {
+ case 'OK':
+//console.log("==> OK");
+ this.closeOk();
+ break;
+ case 'CANCEL':
+//console.log("==> CANCEL");
+ this.closeCancel();
+ break;
+ default:
+//console.log("==> ????");
+ this.closeError();
+ break;
+ }
+//console.log("<==");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredShow': function (someArgs, aResult) {
+ this.deferredShowModal(someArgs);
+
+ this.deferred().addMethod(this, 'deferredHideModal', {closeToElement:someArgs.onOkCloseToElement });
+ this.deferred().addErrback (MochiKit.Base.method(this, 'deferredHideModal', {closeToElement:someArgs.onCancelCloseToElement }));
+ this.deferred().addCallback(MochiKit.Async.succeed, aResult);
+
+ return this.deferred();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'modalDialogMask': function () {
+ return this.getId('modalDialogMask');
+ },
+
+ 'modalDialog': function () {
+ return this.getId('modalDialog');
+ },
+
+ 'modalDialogFrame': function() {
+ return this.getId('modalDialogFrame');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderModalMask': function () {
+ Clipperz.DOM.Helper.append(MochiKit.DOM.currentDocument().body,
+ {tag:'div', id:this.getId('modalDialogWrapper'), cls:'modalDialogWrapper simpleMessagePanelMask', children:[
+ {tag:'div', id:this.getId('modalDialogMask'), cls:'modalDialogMask simpleMessagePanelMask'},
+ {tag:'div', id:this.getId('modalDialogFrame'), cls:'modalDialogFrame simpleMessagePanelMask'},
+ {tag:'div', id:this.getId('modalDialog'), cls:'modalDialog simpleMessagePanelMask'}
+ ]}
+ );
+
+ MochiKit.Style.hideElement(this.getId('modalDialogMask'));
+ MochiKit.Style.hideElement(this.getId('modalDialogFrame'));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'keyDownHandler': function (anEvent) {
+ if (anEvent.key().string == 'KEY_ENTER') {
+ anEvent.preventDefault();
+//console.log("13 - RETURN ?", this);
+ this.closeOk();
+//console.log('<<< 13')
+ }
+
+ if (anEvent.key().string == 'KEY_ESCAPE') {
+ anEvent.preventDefault();
+//console.log("27 - ESC ?", this);
+ this.closeCancel();
+//console.log("<<< 27");
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/TabPanelComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/TabPanelComponent.js
new file mode 100644
index 0000000..afb3bf9
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/TabPanelComponent.js
@@ -0,0 +1,69 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Common.Components');
+
+Clipperz.PM.UI.Common.Components.TabPanelComponent = function(args) {
+ args = args || {};
+ Clipperz.PM.UI.Common.Components.TabPanelComponent.superclass.constructor.call(this, args);
+
+ this._tabPanelController = null;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.TabPanelComponent, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Common.Components.TabPanelComponent component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'tabPanelControllerConfiguration': function() {
+ return this._tabPanelControllerConfiguration;
+ },
+
+ 'tabPanelController': function() {
+ if (this._tabPanelController == null) {
+ this._tabPanelController = new Clipperz.PM.UI.Common.Controllers.TabPanelController({component:this, configuration:this.tabPanelControllerConfiguration()});
+ }
+
+ return this._tabPanelController;
+ },
+
+ 'initiallySelectedTab': function() {
+ return this._initiallySelectedTab;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/Tooltip.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/Tooltip.js
new file mode 100644
index 0000000..7507b86
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/Tooltip.js
@@ -0,0 +1,216 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Common.Components');
+
+Clipperz.PM.UI.Common.Components.Tooltip = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Common.Components.Tooltip.superclass.constructor.apply(this, arguments);
+
+ this._element = args.element || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._text = args.text || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._position = args.position || 'BELOW'; // 'BELOW', 'ABOVE', 'LEFT', 'RIGHT'
+
+ this._boxDimensions = null;
+ this._enabled = (typeof(args.enabled) == 'undefined' ? true : args.enabled);
+ this._isVisible = false;
+
+ this.renderSelf();
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.Tooltip, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Common.Components.Tooltip component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'text': function () {
+ return this._text;
+ },
+
+ 'setText': function (aValue) {
+ this._text = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'position': function () {
+ return this._position;
+ },
+
+ 'setPosition': function (aValue) {
+ this._position = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'enabled': function () {
+ return this._enabled;
+ },
+
+ 'setIsEnabled': function (aValue) {
+ this._enabled = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isVisible': function () {
+ return this._isVisible;
+ },
+
+ 'setIsVisible': function (aValue) {
+ this._isVisible = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function() {
+// this.append(this.element(), {tag:'div', id:this.getId('tooltip'), cls:'tooltip ' + this.position(), children:[
+// this.append(MochiKit.DOM.currentDocument().body, {tag:'div', id:this.getId('tooltip'), cls:'tooltip ' + this.position(), children:[
+ this.append(MochiKit.DOM.getElement('Clipperz_PM_UI_Common_Components_Tooltip_wrapperNode'), {tag:'div', id:this.getId('tooltip'), cls:'tooltip ' + this.position(), children:[
+ {tag:'div', id:this.getId('body'), cls:'tooltip_body', children:[
+ {tag:'div', cls:'tooltip_text', children:[
+ {tag:'span', html:this.text()}
+ ]},
+ {tag:'div', id:this.getId('footer'), cls:'tooltip_footer'}
+ ]},
+ {tag:'div', id:this.getId('arrow'), cls:'tooltip_arrow'}
+ ]});
+
+ this._boxDimensions = MochiKit.Style.getElementDimensions(this.getId('body'));
+// this._boxDimensions.h += MochiKit.Style.getElementDimensions(this.getId('footer')).h;
+
+ MochiKit.Style.hideElement(this.displayElement());
+ MochiKit.Signal.connect(this.element(), 'onmouseenter', this, 'show');
+ MochiKit.Signal.connect(this.element(), 'onmouseleave', this, 'hide');
+ },
+
+ //-----------------------------------------------------
+
+ 'displayElement': function() {
+ return this.getElement('tooltip');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'boxDimensions': function () {
+ return this._boxDimensions;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'show': function () {
+ var elementSizeAndPosition;
+ var arrowPosition;
+ var bodyPosition;
+
+ if (this.isVisible() == false) {
+ arrowPosition = {};
+ bodyPosition = {};
+
+ this.setIsVisible(true);
+ elementSizeAndPosition = Clipperz.Style.getSizeAndPosition(this.element());
+//console.log("ELEMENT SIZE AND POSITION", Clipperz.Base.serializeJSON(elementSizeAndPosition));
+//console.log("BOX DIMENSIONS", Clipperz.Base.serializeJSON(this.boxDimensions()));
+ switch (this.position()) {
+ case 'ABOVE':
+//console.log("ABOVE");
+ MochiKit.Style.setElementDimensions(this.getId('arrow'), {w:36, h:13}, 'px');
+ bodyPosition.x = elementSizeAndPosition.position.x + (elementSizeAndPosition.dimensions.w/2 - this.boxDimensions().w/2);
+ bodyPosition.y = elementSizeAndPosition.position.y - this.boxDimensions().h - 13;
+
+ arrowPosition.x = elementSizeAndPosition.position.x + (elementSizeAndPosition.dimensions.w/2 - 36/2);
+ arrowPosition.y = elementSizeAndPosition.position.y - 13;
+ break;
+ case 'BELOW':
+//console.log("BELOW");
+ MochiKit.Style.setElementDimensions(this.getId('arrow'), {w:36, h:13}, 'px');
+ bodyPosition.x = elementSizeAndPosition.position.x + (elementSizeAndPosition.dimensions.w/2 - this.boxDimensions().w/2);
+ bodyPosition.y = elementSizeAndPosition.position.y + elementSizeAndPosition.dimensions.h + 13;
+
+ arrowPosition.x = elementSizeAndPosition.position.x + (elementSizeAndPosition.dimensions.w/2 - 36/2);
+ arrowPosition.y = elementSizeAndPosition.position.y + elementSizeAndPosition.dimensions.h;
+ break;
+ case 'LEFT':
+//console.log("LEFT");
+ MochiKit.Style.setElementDimensions(this.getId('arrow'), {w:13, h:36}, 'px');
+ bodyPosition.x = elementSizeAndPosition.position.x - this.boxDimensions().w - 13;
+ bodyPosition.y = elementSizeAndPosition.position.y + (elementSizeAndPosition.dimensions.h/2 - this.boxDimensions().h/2);
+
+ arrowPosition.x = elementSizeAndPosition.position.x -13;
+ arrowPosition.y = elementSizeAndPosition.position.y + (elementSizeAndPosition.dimensions.h/2 - 36/2);
+ break;
+ case 'RIGHT':
+//console.log("RIGHT");
+ MochiKit.Style.setElementDimensions(this.getId('arrow'), {w:13, h:36}, 'px');
+ bodyPosition.x = elementSizeAndPosition.position.x + elementSizeAndPosition.dimensions.w + 13;
+ bodyPosition.y = elementSizeAndPosition.position.y + (elementSizeAndPosition.dimensions.h/2 - this.boxDimensions().h/2);
+
+ arrowPosition.x = elementSizeAndPosition.position.x + elementSizeAndPosition.dimensions.w;
+ arrowPosition.y = elementSizeAndPosition.position.y + (elementSizeAndPosition.dimensions.h/2 - 36/2);
+ break;
+ }
+//console.log("X: " + bodyPosition.x + ", Y: " + bodyPosition.y);
+
+ MochiKit.Style.setElementPosition(this.getId('body'), bodyPosition);
+ MochiKit.Style.setElementPosition(this.getId('arrow'), arrowPosition);
+ MochiKit.Visual.appear(this.displayElement(), {duration:0.4});
+ }
+ },
+
+ 'hide': function () {
+ if (this.isVisible() == true) {
+ MochiKit.Visual.fade(this.displayElement(), {duration:0.4});
+ this.setIsVisible(false);
+ }
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'shouldRemoveElementWhenClearningUp': function () {
+ return false;
+ },
+*/
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+Clipperz.PM.UI.Common.Components.Tooltip.initTooltips = function () {
+ Clipperz.DOM.Helper.insertBefore(MochiKit.DOM.currentDocument().body.childNodes[0], {tag:'div', id:'Clipperz_PM_UI_Common_Components_Tooltip_wrapperNode'});
+}
+
+MochiKit.DOM.addLoadEvent(Clipperz.PM.UI.Common.Components.Tooltip.initTooltips);
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Components/TranslatorWidget.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/TranslatorWidget.js
new file mode 100644
index 0000000..c31969e
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Components/TranslatorWidget.js
@@ -0,0 +1,170 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Common.Components');
+
+Clipperz.PM.UI.Common.Components.TranslatorWidget = function(args) {
+Clipperz.log(">>> TranslatorWidget.new");
+ args = args || {};
+
+ Clipperz.PM.UI.Common.Components.TranslatorWidget.superclass.constructor.apply(this, arguments);
+
+// this._element = args.element || Clipperz.Base.exception.raise('MandatoryParameter');
+// this._stringID = args.stringID || MochiKit.DOM.getNodeAttribute(this.element(), 'stringID') || Clipperz.Base.exception.raise('MandatoryParameter');
+
+// MochiKit.Signal.connect(this.element(), 'onmouseenter', this, 'show');
+// MochiKit.Signal.connect(this.element(), 'onmouseleave', this, 'hide');
+
+Clipperz.log("<<< TranslatorWidget.new");
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Common.Components.TranslatorWidget, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Common.Components.TranslatorWidget component";
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'renderSelf': function() {
+ this.append(this.element(), {tag:'div', id:this.getId('tooltip'), cls:'tooltip ' + this.position(), children:[
+ {tag:'div', id:this.getId('body'), cls:'tooltip_body', children:[
+ {tag:'div', cls:'tooltip_text', children:[
+ {tag:'span', html:this.text()}
+ ]},
+ {tag:'div', id:this.getId('footer'), cls:'tooltip_footer'}
+ ]},
+ {tag:'div', id:this.getId('arrow'), cls:'tooltip_arrow'}
+ ]});
+
+ this._boxDimensions = MochiKit.Style.getElementDimensions(this.getId('body'));
+// this._boxDimensions.h += MochiKit.Style.getElementDimensions(this.getId('footer')).h;
+
+ MochiKit.Style.hideElement(this.displayElement());
+ MochiKit.Signal.connect(this.element(), 'onmouseenter', this, 'show');
+ MochiKit.Signal.connect(this.element(), 'onmouseleave', this, 'hide');
+ },
+*/
+ //-----------------------------------------------------
+/*
+ 'displayElement': function() {
+ return this.getElement('tooltip');
+ },
+*/
+ //-------------------------------------------------------------------------
+/*
+ 'boxDimensions': function () {
+ return this._boxDimensions;
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'show': function (anElement, aStringID) {
+ Clipperz.log(">>> Clipperz.PM.UI.Common.Components.TranslatorWidget.show: " + aStringID);
+/*
+ var elementSizeAndPosition;
+ var arrowPosition;
+ var bodyPosition;
+
+ arrowPosition = {};
+ bodyPosition = {};
+
+ elementSizeAndPosition = Clipperz.Style.getSizeAndPosition(this.element());
+ switch (this.position()) {
+ case 'ABOVE':
+ MochiKit.Style.setElementDimensions(this.getId('arrow'), {w:36, h:13}, 'px');
+ bodyPosition.x = elementSizeAndPosition.position.x + (elementSizeAndPosition.dimensions.w/2 - this.boxDimensions().w/2);
+ bodyPosition.y = elementSizeAndPosition.position.y - this.boxDimensions().h - 13;
+
+ arrowPosition.x = elementSizeAndPosition.position.x + (elementSizeAndPosition.dimensions.w/2 - 36/2);
+ arrowPosition.y = elementSizeAndPosition.position.y - 13;
+ break;
+ case 'BELOW':
+ MochiKit.Style.setElementDimensions(this.getId('arrow'), {w:36, h:13}, 'px');
+ bodyPosition.x = elementSizeAndPosition.position.x + (elementSizeAndPosition.dimensions.w/2 - this.boxDimensions().w/2);
+ bodyPosition.y = elementSizeAndPosition.position.y + elementSizeAndPosition.dimensions.h + 13;
+
+ arrowPosition.x = elementSizeAndPosition.position.x + (elementSizeAndPosition.dimensions.w/2 - 36/2);
+ arrowPosition.y = elementSizeAndPosition.position.y + elementSizeAndPosition.dimensions.h;
+ break;
+ case 'LEFT':
+ MochiKit.Style.setElementDimensions(this.getId('arrow'), {w:13, h:36}, 'px');
+ bodyPosition.x = elementSizeAndPosition.position.x - this.boxDimensions().w - 13;
+ bodyPosition.y = elementSizeAndPosition.position.y + (elementSizeAndPosition.dimensions.h/2 - this.boxDimensions().h/2);
+
+ arrowPosition.x = elementSizeAndPosition.position.x -13;
+ arrowPosition.y = elementSizeAndPosition.position.y + (elementSizeAndPosition.dimensions.h/2 - 36/2);
+ break;
+ case 'RIGHT':
+ MochiKit.Style.setElementDimensions(this.getId('arrow'), {w:13, h:36}, 'px');
+ break;
+ }
+
+// MochiKit.Style.setElementPosition(this.getId('body'), bodyPosition);
+ MochiKit.Style.setElementPosition(this.getId('body'), bodyPosition);
+ MochiKit.Style.setElementPosition(this.getId('arrow'), arrowPosition);
+ MochiKit.Visual.appear(this.displayElement(), {duration:0.4});
+*/
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hide': function () {
+ Clipperz.log("<<< Clipperz.PM.UI.Common.Components.TranslatorWidget.hide");
+// MochiKit.Visual.fade(this.displayElement(), {duration:0.4});
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+//#############################################################################
+
+Clipperz.PM.UI.Common.Components.TranslatorWidget._widget = null;
+
+Clipperz.PM.UI.Common.Components.TranslatorWidget.widget = function () {
+ if (Clipperz.PM.UI.Common.Components.TranslatorWidget._widget == null) {
+ Clipperz.PM.UI.Common.Components.TranslatorWidget._widget = new Clipperz.PM.UI.Common.Components.TranslatorWidget();
+ }
+
+ return Clipperz.PM.UI.Common.Components.TranslatorWidget._widget;
+}
+Clipperz.PM.UI.Common.Components.TranslatorWidget.show = function (anElement, aStringID) {
+ Clipperz.PM.UI.Common.Components.TranslatorWidget.widget().show(anElement, aStringID);
+}
+
+Clipperz.PM.UI.Common.Components.TranslatorWidget.hide = function () {
+ Clipperz.PM.UI.Common.Components.TranslatorWidget.widget().hide();
+}
+
+//#############################################################################
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js
new file mode 100644
index 0000000..e534435
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js
@@ -0,0 +1,267 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Common.Controllers');
+
+Clipperz.PM.UI.Common.Controllers.DirectLoginRunner = function(args) {
+ this._directLogin = args['directLogin'] || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._target = Clipperz.PM.Crypto.randomKey();
+
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.Common.Controllers.DirectLoginRunner.prototype, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Common.Controllers.DirectLoginRunner";
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'directLogin': function () {
+ return this._directLogin;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'target': function () {
+ return this._target;
+ },
+
+ //=============================================================================
+
+ 'setWindowTitle': function (aWindow, aTitle) {
+ aWindow.document.title = aTitle;
+ },
+
+ 'setWindowBody': function (aWindow, anHTML) {
+ aWindow.document.body.innerHTML = anHTML;
+ },
+
+ //=============================================================================
+
+ 'initialWindowSetup': function (aWindow) {
+ this.setWindowTitle(aWindow, "Loading Clipperz Direct Login");
+ this.setWindowBody (aWindow, MochiKit.DOM.toHTML(MochiKit.DOM.H3("Loading Clipperz Direct Login ...")));
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'updateWindowWithDirectLoginLabel': function (aWindow, aLabel) {
+ var titleText;
+ var bodyText;
+
+ titleText = "Loading '__label__' Direct Login".replace(/__label__/, aLabel)
+ bodyText = "Loading '__label__' Direct Login... ".replace(/__label__/, aLabel)
+
+ this.setWindowTitle(aWindow, titleText);
+ this.setWindowBody (aWindow, MochiKit.DOM.toHTML(MochiKit.DOM.H3(bodyText)));
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'updateWindowWithHTMLContent': function (aWindow, anHtml) {
+ this.setWindowBody(aWindow, anHtml);
+ },
+
+ //=============================================================================
+
+ 'submitLoginForm': function(aWindow, aSubmitFunction) {
+ MochiKit.DOM.withWindow(aWindow, MochiKit.Base.bind(function () {
+ var formElement;
+ var submitButtons;
+
+ formElement = MochiKit.DOM.getElement('directLoginForm');
+
+ submitButtons = MochiKit.Base.filter(function(anInputElement) {
+ return ((anInputElement.tagName.toLowerCase() == 'input') && (anInputElement.getAttribute('type').toLowerCase() == 'submit'));
+ }, formElement.elements);
+
+ if (submitButtons.length == 0) {
+ if (typeof(formElement.submit) == 'function') {
+ formElement.submit();
+ } else {
+ aSubmitFunction.apply(formElement);
+ }
+/*
+ var formSubmitFunction;
+
+ formSubmitFunction = MochiKit.Base.method(formElement, 'submit');
+ if (Clipperz_IEisBroken == true) {
+ formElement.submit();
+ } else {
+ formSubmitFunction();
+ }
+*/
+ } else {
+ submitButtons[0].click();
+ }
+ }, this));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'runSubmitFormDirectLogin': function (aWindow, someAttributes) {
+ var html;
+ var formElement;
+ var submitFunction;
+
+ formElement = MochiKit.DOM.FORM({
+ 'id':'directLoginForm',
+ 'method':someAttributes['formAttributes']['method'],
+ 'action':someAttributes['formAttributes']['action']
+ });
+
+ submitFunction = formElement.submit;
+
+ MochiKit.DOM.appendChildNodes(formElement, MochiKit.Base.map(function (anInputAttributes) {
+ return MochiKit.DOM.INPUT({'type':'hidden', 'name':anInputAttributes[0], 'value':anInputAttributes[1]});
+ }, MochiKit.Base.items(someAttributes['inputValues'])));
+
+ html = '';
+ html += '<h3>Loading ' + someAttributes['label'] + ' ...</h3>';
+ html += MochiKit.DOM.appendChildNodes(MochiKit.DOM.DIV(), MochiKit.DOM.appendChildNodes(MochiKit.DOM.DIV({style:'display:none; visibility:hidden;'}), formElement)).innerHTML;
+
+ this.updateWindowWithHTMLContent(aWindow, html);
+ this.submitLoginForm(aWindow, submitFunction);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'runHttpAuthDirectLogin': function(aWindow, someAttributes) {
+ var completeUrl;
+ var url;
+
+//console.log("runHttpAuthDirectLogin", someAttributes);
+ url = someAttributes['inputValues']['url'];
+
+ if (/^https?\:\/\//.test(url) == false) {
+ url = 'http://' + url;
+ }
+
+ if (Clipperz_IEisBroken === true) {
+ completeUrl = url;
+ } else {
+ var username;
+ var password;
+
+ username = someAttributes['inputValues']['username'];
+ password = someAttributes['inputValues']['password'];
+ /(^https?\:\/\/)?(.*)/.test(url);
+
+ completeUrl = RegExp.$1 + username + ':' + password + '@' + RegExp.$2;
+ }
+
+ window.open(completeUrl, this.target());
+ },
+
+ //=============================================================================
+
+ 'runDirectLogin': function (aWindow) {
+ var deferredResult;
+
+//console.log(">>> runDirectLogin");
+ deferredResult = new Clipperz.Async.Deferred("DirectLoginRunner.openDirectLogin", {trace:false});
+ deferredResult.addMethod(this, 'initialWindowSetup', aWindow);
+ deferredResult.addMethod(this.directLogin(), 'label');
+ deferredResult.addMethod(this, 'updateWindowWithDirectLoginLabel', aWindow);
+ deferredResult.collectResults({
+ 'type': MochiKit.Base.method(this.directLogin(), 'type'),
+ 'label': MochiKit.Base.method(this.directLogin(), 'label'),
+ 'formAttributes': MochiKit.Base.method(this.directLogin(), 'formAttributes'),
+ 'inputValues': MochiKit.Base.method(this.directLogin(), 'inputValues')
+ });
+//deferredResult.addCallback(function (aValue) { console.log("SOME ATTRIBUTES", aValue); return aValue; });
+ deferredResult.addCallback(MochiKit.Base.bind(function (someAttributes) {
+//console.log("SOME ATTRIBUTES", someAttributes);
+ switch (someAttributes['type']) {
+ case 'http_auth':
+ this.runHttpAuthDirectLogin(aWindow, someAttributes);
+ break;
+ case 'simple_url':
+ this.runSimpleUrlDirectLogin(aWindow, someAttributes);
+ break;
+ default:
+ this.runSubmitFormDirectLogin(aWindow, someAttributes);
+ break;
+ }
+ }, this));
+ deferredResult.callback();
+//console.log("<<< runDirectLogin");
+
+ return deferredResult;
+ },
+
+ //=============================================================================
+
+ 'run': function () {
+ var newWindow;
+
+ newWindow = window.open(Clipperz.PM.Strings.getValue('directLoginJumpPageUrl'), this.target());
+
+ return this.runDirectLogin(newWindow);
+ },
+
+ //=============================================================================
+
+ 'test': function () {
+ var iFrame;
+ var newWindow;
+
+ iFrame = MochiKit.DOM.createDOM('iframe');
+ MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body, iFrame);
+
+ newWindow = iFrame.contentWindow;
+
+ return this.runDirectLogin(newWindow);
+ },
+
+ //=============================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+//-----------------------------------------------------------------------------
+
+Clipperz.PM.UI.Common.Controllers.DirectLoginRunner.openDirectLogin = function (aDirectLogin) {
+ var runner;
+
+ runner = new Clipperz.PM.UI.Common.Controllers.DirectLoginRunner({directLogin:aDirectLogin});
+ return runner.run();
+};
+
+//-----------------------------------------------------------------------------
+
+Clipperz.PM.UI.Common.Controllers.DirectLoginRunner.testDirectLogin = function (aDirectLogin) {
+ var runner;
+
+//console.log(">>>>>> TESTING DIRECT LOGIN");
+ runner = new Clipperz.PM.UI.Common.Controllers.DirectLoginRunner({directLogin:aDirectLogin});
+ return runner.test();
+};
+
+//-----------------------------------------------------------------------------
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/ProgressBarController.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/ProgressBarController.js
new file mode 100644
index 0000000..a4fa400
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/ProgressBarController.js
@@ -0,0 +1,143 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Common.Controllers');
+
+Clipperz.PM.UI.Common.Controllers.ProgressBarController = function(args) {
+ args = args || {};
+
+ this._numberOfSteps = 0;
+ this._currentStep = 0;
+
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'initProgress', this, 'initProgressHandle');
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'updateProgress', this, 'updateProgressHandle');
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'advanceProgress', this, 'advanceProgressHandle');
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'progressDone', this, 'progressDoneHandle');
+
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.Common.Controllers.ProgressBarController.prototype, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Common.Controllers.ProgressBarController";
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'numberOfSteps': function() {
+ return this._numberOfSteps;
+ },
+
+ 'setNumberOfSteps': function (aValue) {
+ this._numberOfSteps = aValue;
+ },
+
+ 'updateNumberOfSteps': function (aValue) {
+ this._numberOfSteps += aValue;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'currentStep': function() {
+ return this._currentStep;
+ },
+
+ 'advanceCurrentStep': function () {
+ this._currentStep ++;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'completedPercentage': function () {
+ var result;
+//Clipperz.log(">>> completedPercentage" + this.currentStep() + "/" + this.numberOfSteps(), this.currentStep() / this.numberOfSteps());
+ if (this.numberOfSteps() == 0) {
+ result = 0;
+ } else {
+ result = (Math.min(100, 100 * (this.currentStep() / this.numberOfSteps())));
+ }
+//Clipperz.log("<<< completedPercentage", result);
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'resetStatus': function () {
+ this._numberOfSteps = 0;
+ this._currentStep = 0;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'updateProgress': function () {
+//Clipperz.log(">>> updateProgress: " + this.completedPercentage() + "%");
+ MochiKit.Signal.signal(this, 'updateProgress', this.completedPercentage());
+ },
+
+ //=============================================================================
+
+ 'initProgressHandle': function (anEvent) {
+//Clipperz.log(">>> initProgressHandle - steps: " + (anEvent != null ? anEvent['steps'] : 0));
+ this.resetStatus();
+ if (anEvent != null) {
+ this.setNumberOfSteps(anEvent['steps']);
+ }
+ MochiKit.Signal.signal(this, 'initProgress');
+ this.updateProgress();
+ },
+
+ //.............................................................................
+
+ 'updateProgressHandle': function (anEvent) {
+ this.updateNumberOfSteps(anEvent['extraSteps']);
+//Clipperz.log("=== updateProgressHandle - steps: " + this.numberOfSteps() + " (extra " + anEvent['extraSteps'] + ")");
+ this.updateProgress();
+ },
+
+ //.............................................................................
+
+ 'advanceProgressHandle': function (anEvent) {
+ this.advanceCurrentStep();
+//Clipperz.log("--- advanceProgressHandle: " + this.currentStep() + "/" + this.numberOfSteps());
+ this.updateProgress();
+ },
+
+ //.............................................................................
+
+ 'progressDoneHandle': function (anEvent) {
+//Clipperz.log("<<< progressDoneHandle: " + this.currentStep() + "/" + this.numberOfSteps());
+ this.resetStatus();
+ MochiKit.Signal.signal(this, 'progressDone');
+ },
+
+ //=============================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+Clipperz.PM.UI.Common.Controllers.ProgressBarController.defaultController = new Clipperz.PM.UI.Common.Controllers.ProgressBarController();
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/TabPanelController.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/TabPanelController.js
new file mode 100644
index 0000000..fbc5929
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/TabPanelController.js
@@ -0,0 +1,188 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Common.Controllers');
+
+Clipperz.PM.UI.Common.Controllers.TabPanelController = function(args) {
+ args = args || {};
+
+ this._component = args.component;
+ this._configuration = args.configuration;
+ this._isEnabled = args.enabled || true;
+
+ this._selectedTab = null;
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.Common.Controllers.TabPanelController.prototype, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Common.Controllers.TabPanelController";
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'component': function() {
+ return this._component;
+ },
+
+ 'configuration': function() {
+ return this._configuration;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'getElement': function(anElementID) {
+ return this.component().getElement(anElementID);
+ },
+
+ 'tabForTabElement': function(anElement) {
+ var result;
+
+ for (result in this.configuration()) {
+ if (this.getElement(this.configuration()[result]['tab']) == anElement) {
+ break;
+ }
+ }
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'setupTab': function(aConfiguration) {
+ var tabElement;
+
+ tabElement = this.getElement(aConfiguration['tab']);
+
+ MochiKit.DOM.removeElementClass(tabElement, 'selected');
+ MochiKit.Signal.connect(tabElement, 'onclick', this, 'handleTabClick')
+ },
+
+ 'setupPanel': function(aConfiguration) {
+ this.hidePanel(aConfiguration['panel']);
+ },
+
+ 'setup': function(args) {
+ args = args || {};
+
+ MochiKit.Base.map(MochiKit.Base.method(this, 'setupTab'), MochiKit.Base.values(this.configuration()));
+ MochiKit.Base.map(MochiKit.Base.method(this, 'setupPanel'), MochiKit.Base.values(this.configuration()));
+ this.selectTab(args.selected);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'hidePanel': function(aPanel) {
+ MochiKit.DOM.removeElementClass(this.getElement(aPanel), 'selected');
+ },
+
+ 'selectTab': function(aTab) {
+ if ((aTab != this.selectedTab()) && (this.isEnabled())) {
+ if (this.selectedTab() != null) {
+ MochiKit.DOM.removeElementClass(this.getElement(this.configuration()[this.selectedTab()]['tab']), 'selected');
+ MochiKit.DOM.removeElementClass(this.getElement(this.configuration()[this.selectedTab()]['panel']), 'selected');
+ }
+
+ if (aTab != null) {
+ MochiKit.DOM.addElementClass(this.getElement(this.configuration()[aTab]['tab']), 'selected');
+ MochiKit.DOM.addElementClass(this.getElement(this.configuration()[aTab]['panel']), 'selected');
+ }
+
+ this.setSelectedTab(aTab);
+ MochiKit.Signal.signal(this, 'tabSelected', aTab);
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'selectedTab': function() {
+ return this._selectedTab;
+ },
+
+ 'setSelectedTab': function(aTab) {
+ this._selectedTab = aTab;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'selectedTabElement': function() {
+ var result;
+
+ if (this.selectedTab() != null) {
+ result = this.getElement(this.configuration()[this.selectedTab()]['tab']);
+ } else {
+ result = null;
+ }
+
+ return null;
+ },
+
+ 'selectedTabPanelElement': function() {
+ var result;
+
+ if (this.selectedTab() != null) {
+ result = this.getElement(this.configuration()[this.selectedTab()]['panel']);
+ } else {
+ result = null;
+ }
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleTabClick': function(anEvent) {
+ this.selectTab(this.tabForTabElement(anEvent.src()));
+ anEvent.preventDefault();
+ },
+
+ //=============================================================================
+
+ 'isEnabled': function () {
+ return this._isEnabled;
+ },
+
+ 'enable': function () {
+ this._isEnabled = true;
+ MochiKit.Base.map(MochiKit.Base.bind(function (aTabComponentID) {
+ MochiKit.DOM.removeElementClass(this.getElement(this.configuration()[aTabComponentID]['tab']), 'disabled');
+ }, this), MochiKit.Base.keys(this.configuration()));
+ },
+
+ 'disable': function () {
+ this._isEnabled = false;
+ MochiKit.Base.map(MochiKit.Base.bind(function (aTabComponentID) {
+ MochiKit.DOM.addElementClass(this.getElement(this.configuration()[aTabComponentID]['tab']), 'disabled');
+ }, this), MochiKit.Base.keys(this.configuration()));
+ },
+
+ //=============================================================================
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/WizardController.js b/frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/WizardController.js
new file mode 100644
index 0000000..868cea6
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Common/Controllers/WizardController.js
@@ -0,0 +1,31 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+// Still empty, but here it should be reasonable to factor in code duplicated between
+// - DirectLoginWizardController
+// - NewUserWizardController \ No newline at end of file
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Compact/MainController.js b/frontend/gamma/js/Clipperz/PM/UI/Compact/MainController.js
new file mode 100644
index 0000000..22258f6
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Compact/MainController.js
@@ -0,0 +1,59 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Compact');
+
+Clipperz.PM.UI.Compact.MainController = function() {
+// this._loginPanel = null;
+// this._user = null;
+//
+// this._isRunningCompact = false;
+//
+// Clipperz.NotificationCenter.register(null, 'userConnected', this, 'userConnectedCallback');
+// Clipperz.NotificationCenter.register(null, 'switchLanguage', this, 'switchLanguageHandler');
+//
+// Clipperz.NotificationCenter.register(null, 'EXCEPTION', this, 'reportException');
+
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.Compact.MainController.prototype, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Compact.MainController";
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'run': function(shouldShowRegistrationForm) {
+MochiKit.Logging.logDebug("running " + this.toString());
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+}); \ No newline at end of file
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js
new file mode 100644
index 0000000..4378b19
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AccountPanel.js
@@ -0,0 +1,148 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.AccountPanel = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.AccountPanel.superclass.constructor.apply(this, arguments);
+
+// this._initiallySelectedTab = args.selected || 'ACCOUNT';
+ this._initiallySelectedTab = args.selected || 'PASSPHRASE';
+ this._tabPanelControllerConfiguration = {
+// 'ACCOUNT': {
+// tab: 'accountTab',
+// panel: 'accountPanel'
+// },
+ 'PASSPHRASE': {
+ tab: 'passphraseTab',
+ panel: 'passphrasePanel'
+ },
+ 'PREFERENCES': {
+ tab: 'preferencesTab',
+ panel: 'preferencesPanel'
+ },
+ 'LOGIN_HISTORY': {
+ tab: 'loginHistoryTab',
+ panel: 'loginHistoryPanel'
+ }
+ };
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.AccountPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.AccountPanel component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+//Clipperz.log("AccountPanel.renderSelf element", this.element());
+ this.append(this.element(), [
+ {tag:'div', cls:'header', children:[
+ {tag:'div', cls:'subPanelTabs', children:[
+ {tag:'ul', children:[
+// {tag:'li', id:this.getId('accountTab'), children:[{tag:'a', href:'#', html:'Account'}], cls:'first'},
+ {tag:'li', id:this.getId('passphraseTab'), children:[{tag:'a', href:'#', html:'Passphrase'}], cls:'first'},
+ {tag:'li', id:this.getId('preferencesTab'), children:[{tag:'a', href:'#', html:'Preferences'}]},
+ {tag:'li', id:this.getId('loginHistoryTab'), children:[{tag:'a', href:'#', html:'Login history'}]}
+ ]}
+ ]}
+ ]},
+ {tag:'div', cls:'body', children:[
+ {tag:'div', cls:'accountPanel', children:[
+ {tag:'div', cls:'subPanelContent', children:[
+ {tag:'ul', children:[
+// {tag:'li', id:this.getId('accountPanel'), children:[
+// {tag:'h3', html:"-- Account --"}
+// ]},
+ {tag:'li', id:this.getId('passphrasePanel'), children:[
+ {tag:'h3', cls:'changePassphrase', html:"Change passphrase"},
+ {tag:'form', id:this.getId('changePassphrase'), cls:'changePassphrase', children:[
+ {tag:'div', cls:'currentCredentials', children:[
+ {tag:'div', cls:'field username', children:[
+ {tag:'label', html:"username", 'for':this.getId('currentUsername')},
+ {tag:'input', id:this.getId('currentUsername')}
+ ]},
+ {tag:'div', cls:'field passphrase', children:[
+ {tag:'label', html:"passphrase", 'for':this.getId('currentPassphrase')},
+ {tag:'input', id:this.getId('currentPassphrase')}
+ ]}
+ ]},
+ {tag:'div', cls:'newPassphrase', children:[
+ {tag:'div', cls:'field', children:[
+ {tag:'label', html:"new passphrase", 'for':this.getId('newPassphrase')},
+ {tag:'input', id:this.getId('newPassphrase')}
+ ]},
+ {tag:'div', cls:'field', children:[
+ {tag:'label', html:"re-new passphrase", 'for':this.getId('reNewPassphrase')},
+ {tag:'input', id:this.getId('reNewPassphrase')}
+ ]}
+ ]},
+ {tag:'div', cls:'confirm', children:[
+ {tag:'input', type:'checkbox', id:this.getId('confirm')},
+ {tag:'label', html:"I understand that Clipperz will not be able to recover a lost passphrase", 'for':this.getId('confirm')}
+ ]}
+ ]},
+ {tag:'div', cls:'clear'},
+ {tag:'div', cls:'confirmButton', id:this.getId('confirmationButton'), children:[
+ {tag:'span', html:"change passphrase"}
+ ]},
+
+ {tag:'h3', cls:'manageOTP', html:"Manage One-Time Passphrases"},
+ {}
+ ]},
+ {tag:'li', id:this.getId('preferencesPanel'), children:[
+ {tag:'h3', html:"-- Preferences --"}
+ ]},
+ {tag:'li', id:this.getId('loginHistoryPanel'), children:[
+ {tag:'h3', html:"-- Login History --"}
+ ]}
+ ]}
+ ]}
+ ]}
+ ]},
+ {tag:'div', cls:'footer'}
+ ]);
+
+ this.tabPanelController().setup({selected:this.initiallySelectedTab()});
+ },
+
+ //-------------------------------------------------------------------------
+
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AppPage.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AppPage.js
new file mode 100644
index 0000000..67247df
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/AppPage.js
@@ -0,0 +1,78 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.AppPage = function(args) {
+ args = args || {};
+ Clipperz.PM.UI.Web.Components.AppPage.superclass.constructor.call(this, args);
+
+ this._element = args.element || null;
+
+ this._slots = {
+ 'cardGrid' : this.getId('cardGrid'),
+// 'directLoginGrid' : this.getId('directLoginGrid'),
+ 'accountPanel': this.getId('accountPanel'),
+ 'dataPanel': this.getId('dataPanel'),
+ 'toolsPanel': this.getId('toolsPanel'),
+ 'userInfoBox': this.getId('userInfoBox'),
+ 'tabSidePanel': this.getId('tabSidePanel')
+ };
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.AppPage, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.AppPage component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.append(this.element(), {tag:'div', id:this.getId('userInfoBox'), cls:'userInfoBox'});
+ this.append(this.element(), {tag:'div', id:this.getId('sidePanels'), cls:'sidePanels'});
+ this.append(this.getId('sidePanels'), {tag:'div', id:this.getId('tabSidePanel'), cls:'tabSidePanel', children:[]});
+
+ this.append(this.element(), {tag:'div', id:this.getId('mainPanels'), cls:'mainPanels'});
+ this.append(this.getId('mainPanels'), {tag:'div', id:this.getId('cardGrid'), cls:'gridComponent cardGrid'});
+// this.append(this.getId('mainPanels'), {tag:'div', id:this.getId('directLoginGrid'), cls:'gridComponent directLoginGrid'});
+ this.append(this.getId('mainPanels'), {tag:'div', id:this.getId('accountPanel'), cls:'otherPanel'});
+ this.append(this.getId('mainPanels'), {tag:'div', id:this.getId('dataPanel'), cls:'otherPanel'});
+ this.append(this.getId('mainPanels'), {tag:'div', id:this.getId('toolsPanel'), cls:'otherPanel'});
+ },
+
+ //-------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/BookmarkletComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/BookmarkletComponent.js
new file mode 100644
index 0000000..42a6052
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/BookmarkletComponent.js
@@ -0,0 +1,109 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.BookmarkletComponent = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.BookmarkletComponent.superclass.constructor.apply(this, arguments);
+ MochiKit.Signal.connect(Clipperz.PM.Strings.Languages, 'switchLanguage', this, 'updateBookmarkletURLs');
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.BookmarkletComponent, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.BookmarkletComponent component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function() {
+// var bookmarkletUrl;
+//
+// if (Clipperz_IEisBroken == true) {
+// bookmarkletUrl = bookmarklet_ie;
+// } else {
+/// bookmarkletUrl = bookmarklet;
+// bookmarkletUrl = Clipperz.PM.Strings['bookmarklet'];
+// }
+
+ this.append(this.element(), {tag:'div', cls:'bookmarklet', children: [
+ {tag:'div', id:this.getId('linkBlock'), cls:'bookmarklet_link', children:[
+// {tag:'a', id:this.getId('link'), href:bookmarkletUrl, children:[
+ {tag:'a', id:this.getId('link'), href:'#', children:[
+ {tag:'div', cls:'icon'},
+ {tag:'div', cls:'text', children:[
+ {tag:'span', html:"add to Clipperz"}
+ ]}
+ ]}
+ ]}
+ ]});
+
+ new Clipperz.PM.UI.Common.Components.Tooltip({
+ element: this.getElement('linkBlock'),
+ text: "Drag and drop the \"add to Clipperz\" link above to the bookmark bar.",
+ position: 'BELOW'
+ });
+
+ MochiKit.Signal.connect(this.getId('link'), 'onclick', this, 'handleOnclick');
+ this.updateBookmarkletURLs();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleOnclick': function (anEvent) {
+ anEvent.preventDefault();
+
+Clipperz.log("BOOKMARKLET CLICK");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateBookmarkletURLs': function () {
+ var bookmarkletUrl;
+
+ if (Clipperz_IEisBroken == true) {
+ bookmarkletUrl = bookmarklet_ie;
+ } else {
+// bookmarkletUrl = bookmarklet;
+ bookmarkletUrl = Clipperz.PM.Strings.getValue('bookmarklet');
+ }
+
+ this.getElement('link').href = bookmarkletUrl;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogComponent.js
new file mode 100644
index 0000000..e3238ca
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogComponent.js
@@ -0,0 +1,881 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.CardDialogComponent = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.CardDialogComponent.superclass.constructor.apply(this, arguments);
+
+ this._tabPanelController = null;
+
+ this._tabPanelControllerConfiguration = {
+ 'DETAILS': {
+ tab: 'detailTab',
+ panel: 'detailTabpanel'
+ },
+ 'DIRECT_LOGINS': {
+ tab: 'directLoginTab',
+ panel: 'directLoginTabpanel'
+ },
+ 'SHARING': {
+ tab: 'sharingTab',
+ panel: 'sharingTabpanel'
+ }
+ };
+
+ this._tooltips = null;
+
+ this._isSavingEnabled = false;
+ this._hintMode = 'OFF'; // 'ON'
+
+ this._fieldComponents = {};
+ this._directLoginComponents = {};
+
+ this._displayMode = 'fixed'; // 'scrollable';
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.CardDialogComponent, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.CardDialogComponent component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'tabPanelController': function () {
+ if (this._tabPanelController == null) {
+ this._tabPanelController = new Clipperz.PM.UI.Common.Controllers.TabPanelController({
+ component:this,
+ configuration:this._tabPanelControllerConfiguration
+ });
+
+ MochiKit.Signal.connect(this._tabPanelController, 'tabSelected', this, 'handleTabSelected')
+ }
+
+ return this._tabPanelController;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function() {
+ this.append(this.element(), {tag:'div', cls:'CardDialog mainDialog loading', id:this.getId('panel'), children: [
+ {tag:'form', id:this.getId('form'), children:[
+// {tag:'input', type:'text', id:this.getId('hidden'), cls:'hidden'},
+ {tag:'div', cls:'header', children:[
+ {tag:'div', cls:'title', children:[
+ {tag:'input', type:'text', id:this.getId('title')}
+ ]}
+ ]},
+ {tag:'div', id:this.getId('body'), cls:'body', children:[
+ {tag:'div', cls:'tabs', children:[
+ {tag:'ul', cls:'tabs', children:[
+ {tag:'li', id:this.getId('detailTab'), children:[{tag:'span', html:"details"}]},
+ {tag:'li', id:this.getId('directLoginTab'), children:[
+ {tag:'span', html:"direct logins"}//,
+// {tag:'div', id:this.getId('addDirectLoginButton'), cls:'addDirectLoginButton', children:[
+// {tag:'span', html:"+"}
+// ]}
+ ]},
+ {tag:'li', id:this.getId('sharingTab'), children:[{tag:'span', html:"sharing"}]}
+ ]}
+ ]},
+ {tag:'div', cls:'tabPanels', children:[
+ {tag:'ul', cls:'tabPanels', children:[
+ {tag:'li', id:this.getId('detailTabpanel'), cls:'tabPanel', children:[
+ {tag:'div', id:this.getId('recordFields'), children:[
+ {tag:'table', cls:'fields', cellpadding:'0', id:this.getId('fieldTable'), cellspacing:'0', children:[
+ {tag:'thead', children:[
+ {tag:'tr', children:[
+ {tag:'th', cls:'fieldStateTH', html:""},
+ {tag:'th', cls:'fieldLabelTH', html:"label"},
+ {tag:'th', cls:'fieldLockTH', html:""},
+ {tag:'th', cls:'fieldValueTH', html:"value"},
+ {tag:'th', cls:'fieldActionTH', html:""},
+ {tag:'th', cls:'fieldDeleteTH', html:""}
+ ]}
+ ]},
+ {tag:'tfoot'},
+ {tag:'tbody', id:this.getId('tableBody'), children:[
+ {tag:'tr', id:this.getId('newFieldTR'), cls:'newFieldTR', children:[
+ {tag:'td', cls:'fieldState'},
+ {tag:'td', cls:'fieldLabel', children:[
+ {tag:'input', cls:'label', id:this.getId('newFieldLabel')}
+ ]},
+ {tag:'td', cls:'fieldLock', children:[
+ {tag:'div', cls:'unlocked', id:this.getId('newFieldIsLocked')}
+ ]},
+ {tag:'td', cls:'fieldValue', children:[
+ {tag:'div', cls:'unlocked', id:this.getId('newFieldValueWrapper'), children:[
+ {tag:'input', type:'text', cls:'value', id:this.getId('newFieldValue')}
+ ]}
+ ]},
+ {tag:'td', cls:'fieldAction', children:[
+ {tag:'div', html:'&nbsp;'}
+ ]},
+ {tag:'td', cls:'fieldAddDelete', children:[
+ {tag:'div', cls:'new', children:[
+ {tag:'span', children:[
+ {tag:'a', href:'#', id:this.getId('newFieldAddButton'), html:"add"}
+ ]}
+ ]}
+ ]}
+ ]}
+ ]}
+ ]}
+ ]},
+ {tag:'div', cls:'notes', children:[
+ {tag:'div', children:[
+ {tag:'textarea', id:this.getId('recordNote'), value:""}
+ ]}
+ ]}
+ ]},
+ {tag:'li', id:this.getId('directLoginTabpanel'), cls:'tabPanel', children:[
+ {tag:'div', id:this.getId('directLoginsComponentContainer'), cls:'directLoginsComponentContainer', children:[
+ {tag:'div', id:this.getId('directLogins'), cls:'directLogins', children:[
+ {tag:'div', id:this.getId('addNewDirectLoginSplash'), cls:'addNewDirectLoginSplash', children:[
+ {tag:'h3', html:"Here you can add a Direct Login for this card: instant access to your favorit website!"},
+ {tag:'a', href:'#', id:this.getId('addNewDirectLoginSplashButton'), children:[{tag:'span', html:"Add Direct Login"}]}
+ ]},
+ {tag:'div', id:this.getId('directLoginsList')},
+ {tag:'div', cls:'addDirectLoginListItem', id:this.getId('addDirectLoginListItem'), children:[{tag:'a', href:'#', id:this.getId('addNewDirectLoginListItemButton'), children:[{tag:'span', html:"Add Direct Login"}]}]}
+ ]},
+ {tag:'div', id:this.getId('directLoginEditDetail'), cls:'directLoginEditDetail'}
+ ]}
+ ]},
+ {tag:'li', id:this.getId('sharingTabpanel'), cls:'tabPanel', children:[
+ {tag:'h2', html:"Coming soon!"}
+ ]}
+ ]}
+ ]},
+ {tag:'div', cls:'mask', children:[
+ {tag:'div', id:this.getId('progress'), children:[
+ {tag:'h3', id:this.getId('progressDescription'), cls:'progressDescription', html:"Loading"},
+ {tag:'div', id:this.getId('progressBar')}
+ ]},
+ {tag:'div', id:this.getId('error'), cls:'error', children:[
+ {tag:'div', cls:'img'},
+ {tag:'p', id:this.getId('errorMessage')}
+ ]}
+ ]}
+ ]},
+ {tag:'div', cls:'footer', children:[
+ {tag:'div', cls:'buttonArea', children:[
+ {tag:'div', cls:'cancel', id:this.getId('cancelButton'), html:"cancel"},
+ {tag:'div', cls:'save disabled', id:this.getId('saveButton'), html:"save"}
+ ]}
+ ]}
+ ]}
+ ]});
+
+
+ this.insertAllTooltips();
+
+ this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')}));
+
+ this.tabPanelController().setup({selected:'DETAILS'});
+// this.tabPanelController().setup({selected:'DIRECT_LOGINS'});
+
+ MochiKit.Style.hideElement(this.getId('error'));
+ MochiKit.Style.hideElement(this.getElement('directLoginEditDetail'));
+ MochiKit.Style.hideElement(this.getElement('addDirectLoginListItem'));
+ this.plumbDetailsPanel();
+
+ MochiKit.Signal.connect(this.getId('cancelButton'), 'onclick', this, 'handleCancelEvent');
+ MochiKit.Signal.connect(this.getId('saveButton'), 'onclick', this, 'handleSaveEvent');
+
+ MochiKit.Signal.connect(this.getId('addNewDirectLoginSplashButton'), 'onclick', this, 'handleAddDirectLogin');
+ MochiKit.Signal.connect(this.getId('addNewDirectLoginListItemButton'), 'onclick', this, 'handleAddDirectLogin');
+
+ MochiKit.Signal.connect(MochiKit.DOM.currentDocument().body, 'onkeydown', this, 'handleKeyEvent');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'displayMode': function () {
+ return this._displayMode;
+ },
+
+ 'setDisplayMode': function (aValue) {
+ this._displayMode = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'plumbDetailsPanel': function () {
+ MochiKit.Signal.connect(this.getId('title'), 'onfocus', MochiKit.Base.method(this, 'handleOnFocusEvent', this.getElement('title').parentNode));
+ MochiKit.Signal.connect(this.getId('title'), 'onblur', MochiKit.Base.method(this, 'handleLooseFocusEvent', this.getElement('title').parentNode));
+ MochiKit.Signal.connect(this.getId('title'), 'onchange', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue'));
+ MochiKit.Signal.connect(this.getId('title'), 'onkeyup', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue'));
+
+ MochiKit.Signal.connect(this.getId('recordNote'), 'onfocus', MochiKit.Base.method(this, 'handleOnFocusEvent', MochiKit.Selector.findChildElements(this.element(), ['div.notes'])[0]));
+ MochiKit.Signal.connect(this.getId('recordNote'), 'onblur', MochiKit.Base.method(this, 'handleLooseFocusEvent', MochiKit.Selector.findChildElements(this.element(), ['div.notes'])[0]));
+ MochiKit.Signal.connect(this.getId('recordNote'), 'onchange', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue'));
+ MochiKit.Signal.connect(this.getId('recordNote'), 'onkeyup', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue'));
+
+ MochiKit.Signal.connect(this.getId('newFieldValue'), 'onkeydown', this, 'handleKeyDownOnNewFieldValue');
+
+ MochiKit.Signal.connect(this.getId('newFieldLabel'), 'onkeyup', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue'));
+ MochiKit.Signal.connect(this.getId('newFieldIsLocked'), 'onclick', this, 'toggleNewFieldIsHidden');
+ MochiKit.Signal.connect(this.getId('newFieldValue'), 'onkeyup', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue'));
+
+ MochiKit.Signal.connect(this.getId('newFieldAddButton'), 'onclick', this, 'handleAddClick');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'insertAllTooltips': function () {
+ var tooltips;
+ var tooltipEnabled;
+
+ tooltips = {};
+ tooltipEnabled = (this.hintMode() == 'ON');
+
+ tooltips['title'] = new Clipperz.PM.UI.Common.Components.Tooltip({
+ 'element': this.getElement('title'),
+ 'text': "Insert here the title of the card",
+ 'position': 'RIGHT'
+ });
+ this.addComponent(tooltips['title']);
+ MochiKit.Signal.connect(this.getId('title'), 'onfocus', MochiKit.Base.method(this, 'showTooltipOnFocus', 'title'));
+ MochiKit.Signal.connect(this.getId('title'), 'onblur', MochiKit.Base.method(this, 'hideTooltipOnBlur', 'title'));
+
+ tooltips['newFieldTR'] = new Clipperz.PM.UI.Common.Components.Tooltip({
+ 'element': this.getElement('newFieldTR'),
+ 'text': "Insert your card new values here",
+ 'position': 'RIGHT'
+ });
+ this.addComponent(tooltips['newFieldTR']);
+ MochiKit.Signal.connect(this.getId('newFieldLabel'), 'onfocus', MochiKit.Base.method(this, 'showTooltipOnFocus', 'newFieldTR'));
+ MochiKit.Signal.connect(this.getId('newFieldValue'), 'onblur', MochiKit.Base.method(this, 'hideTooltipOnBlur', 'newFieldTR'));
+
+ tooltips['recordNote'] = new Clipperz.PM.UI.Common.Components.Tooltip({
+ 'element': this.getElement('recordNote'),
+ 'text': "You can insert some notes here",
+ 'position': 'RIGHT'
+ });
+ this.addComponent(tooltips['recordNote']);
+ MochiKit.Signal.connect(this.getId('recordNote'), 'onfocus', MochiKit.Base.method(this, 'showTooltipOnFocus', 'recordNote'));
+ MochiKit.Signal.connect(this.getId('recordNote'), 'onblur', MochiKit.Base.method(this, 'hideTooltipOnBlur', 'recordNote'));
+
+ this._tooltips = tooltips;
+ },
+
+ //.........................................................................
+
+ 'updateAllTooltipsEnabledMode': function (aStatus) {
+ var tooltipLabel;
+ var tooltipEnabled;
+
+ tooltipEnabled = (aStatus == 'ON') ? true : false;
+
+ for (tooltipLabel in this.tooltips()) {
+ this.tooltips()[tooltipLabel].setIsEnabled(tooltipEnabled);
+ }
+ },
+
+ //.........................................................................
+
+ 'tooltips': function () {
+ return this._tooltips;
+ },
+
+ //.........................................................................
+
+ 'showTooltipOnFocus': function (aTooltip, anEvent) {
+ MochiKit.Async.callLater(0.5, MochiKit.Base.method(this.tooltips()[aTooltip], 'show'));
+ },
+
+ //.........................................................................
+
+ 'hideTooltipOnBlur': function (aTooltip, anEvent) {
+ this.tooltips()[aTooltip].hide();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'displayElement': function() {
+ return this.getElement('panel');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'fieldComponents': function () {
+ return this._fieldComponents;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'directLoginComponents': function () {
+ return this._directLoginComponents;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hintMode': function () {
+ return this._hintMode;
+ },
+
+ 'setHintMode': function (aValue) {
+ if (this._hintMode != aValue) {
+ this._hintMode = aValue;
+
+ this.updateAllTooltipsEnabledMode(this._hintMode);
+// if (this._hintMode == 'ON') {
+// this.enableHints();
+// }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'focusOnNewFieldLabel': function () {
+ this.getElement('newFieldLabel').focus();
+ },
+
+ //=========================================================================
+
+ 'isSavingEnabled': function () {
+ return this._isSavingEnabled;
+ },
+
+ 'setShouldEnableSaving': function (aValue) {
+ this._isSavingEnabled = aValue || this.newFieldHasPendingChanges();
+
+ if (this._isSavingEnabled == true) {
+ MochiKit.DOM.addElementClass(this.getElement('panel'), 'hasPendingChanges');
+ MochiKit.DOM.removeElementClass(this.getId('saveButton'), 'disabled');
+ } else {
+ MochiKit.DOM.removeElementClass(this.getElement('panel'), 'hasPendingChanges');
+ MochiKit.DOM.addElementClass(this.getId('saveButton'), 'disabled');
+ }
+ },
+
+ //=========================================================================
+
+ 'title': function () {
+ return this.getElement('title').value;
+ },
+
+ 'setTitle': function (aValue) {
+ this.renderTitle(aValue);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderTitle': function (aValue) {
+ this.getElement('title').value = Clipperz.Base.sanitizeString(aValue);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setFocusOnTitleField': function () {
+ this.getElement('title').focus();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'disableCardTitleEditing': function () {
+ this.getElement('title').disabled = true;
+ MochiKit.DOM.addElementClass(this.getElement('title').parentNode, 'disabled');
+ },
+
+
+ 'enableCardTitleEditing': function () {
+ this.getElement('title').disabled = false;
+ MochiKit.DOM.removeElementClass(this.getElement('title').parentNode, 'disabled');
+ },
+
+ //=========================================================================
+
+ 'notes': function () {
+ return this.getElement('recordNote').value;
+ },
+
+ 'setNotes': function (aValue) {
+ this.renderNotes(aValue);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderNotes': function (aValue) {
+ var noteElement;
+
+ noteElement = this.getElement('recordNote');
+
+ if ((aValue != null) && (typeof(aValue) != 'undefined')) {
+ noteElement.value = aValue;
+ } else {
+ noteElement.value = "";
+ }
+
+ this.fixNotesHeight();
+ },
+
+ //=========================================================================
+
+ 'addFieldRowComponent': function (aFieldComponent) {
+ var fieldTR;
+
+ fieldTR = this.insertBefore(this.getElement('newFieldTR'), {tag:'tr', id:'recordFieldReferece_'+aFieldComponent.reference()});
+ aFieldComponent.renderInNode(fieldTR);
+ this.fieldComponents()[aFieldComponent.reference()] = aFieldComponent;
+ },
+
+ //=========================================================================
+
+ 'addDirectLoginComponent': function (aDirectLoginComponent) {
+ var directLoginDIV;
+
+ if (MochiKit.Base.keys(this.directLoginComponents()).length == 0) {
+ this.hideNewDirectLoginSplash();
+ }
+
+ directLoginDIV = this.append(this.getElement('directLoginsList'), {tag:'div', cls:'directLoginItem'});
+ aDirectLoginComponent.renderInNode(directLoginDIV);
+ this.directLoginComponents()[aDirectLoginComponent.reference()] = aDirectLoginComponent;
+ },
+
+ 'removeDirectLoginComponent': function (aDirectLoginComponent) {
+ delete this.directLoginComponents()[aDirectLoginComponent.reference()];
+ aDirectLoginComponent.remove();
+
+ if (MochiKit.Base.keys(this.directLoginComponents()).length == 0) {
+ this.showNewDirectLoginSplash();
+ }
+ },
+
+ //=========================================================================
+
+ 'showNewDirectLoginSplash': function () {
+ MochiKit.Style.showElement(this.getElement('addNewDirectLoginSplash'));
+ MochiKit.Style.hideElement(this.getElement('addDirectLoginListItem'));
+ },
+
+ 'hideNewDirectLoginSplash': function () {
+ MochiKit.Style.hideElement(this.getElement('addNewDirectLoginSplash'));
+ MochiKit.Style.showElement(this.getElement('addDirectLoginListItem'));
+ },
+
+ //=========================================================================
+
+ 'renderDirectLoginEditingComponent': function (aDirectLoginEditingComponent) {
+ aDirectLoginEditingComponent.renderInNode(this.getElement('directLoginEditDetail'));
+ },
+
+ 'placeDirectLoginEditingComponent': function () {
+ var width;
+
+ width = MochiKit.Style.getElementDimensions(this.getElement('directLoginsComponentContainer'))['w'];
+
+ return Clipperz.Async.callbacks("CardDialogComponent.renderDirectLoginEditingComponent", [
+ MochiKit.Base.bind(function () {
+ MochiKit.Style.setElementPosition (this.getElement('directLoginEditDetail'), {x:width, y:-MochiKit.Style.getElementDimensions(this.getElement('directLogins'))['h']});
+ MochiKit.Style.setElementDimensions(this.getElement('directLoginEditDetail'), {w:width});
+ }, this),
+
+ MochiKit.Base.noop
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'newFieldLabel': function () {
+ return this.getElement('newFieldLabel').value;
+ },
+
+ 'setNewFieldLabel': function (aValue) {
+ this.getElement('newFieldLabel').value = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'newFieldValue': function () {
+ return this.getElement('newFieldValue').value;
+ },
+
+ 'setNewFieldValue': function (aValue) {
+ this.getElement('newFieldValue').value = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'newFieldIsHidden': function () {
+ return MochiKit.DOM.hasElementClass(this.getElement('newFieldIsLocked'), 'locked');
+ },
+
+ 'setNewFieldIsHidden': function (aValue) {
+ MochiKit.DOM.setElementClass(this.getElement('newFieldIsLocked'), (aValue ? 'locked': 'unlocked'));
+ MochiKit.DOM.setElementClass(this.getElement('newFieldValueWrapper'), (aValue ? 'locked': 'unlocked'));
+ },
+
+ 'toggleNewFieldIsHidden': function (anEvent) {
+ anEvent.preventDefault();
+
+ this.setNewFieldIsHidden(! this.newFieldIsHidden());
+ MochiKit.Signal.signal(this, 'changedValue');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'newFieldHasPendingChanges': function () {
+ return ((this.newFieldLabel() != '') || (this.newFieldValue() != '') || (this.newFieldIsHidden() == true));
+ },
+
+ 'resetNewFieldInputs': function () {
+ this.setNewFieldLabel('');
+ this.setNewFieldValue('');
+ this.setNewFieldIsHidden(false);
+ },
+
+ //=========================================================================
+
+ 'handleKeyDownOnNewFieldValue': function (anEvent) {
+ MochiKit.Signal.signal(this, 'keyPressed', anEvent);
+/*
+ if ((anEvent.key().string == 'KEY_TAB') && this.newFieldHasPendingChanges()) {
+ anEvent.preventDefault();
+
+ MochiKit.Signal.signal(this, 'addField');
+ this.getElement('newFieldLabel').focus();
+ }
+*/
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleAddClick': function (anEvent) {
+ anEvent.preventDefault();
+ MochiKit.Signal.signal(this, 'addField');
+ this.getElement('newFieldLabel').focus();
+ },
+
+ //=========================================================================
+
+ 'handleDeleteClick': function (aFieldKey, anEvent) {
+ anEvent.preventDefault();
+ MochiKit.Signal.signal(this, 'deleteField', aFieldKey);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toggleLock': function (aFieldKey, anEvent) {
+ var shouldRedrawAsLocked;
+ var currentTRElement;
+
+ anEvent.preventDefault();
+
+ currentTRElement = Clipperz.DOM.get(aFieldKey);
+ shouldRedrawAsLocked = (MochiKit.DOM.hasElementClass(currentTRElement, 'locked') ? false : true);
+
+ this.renderFieldTR(currentTRElement, {
+ label:MochiKit.Selector.findChildElements(currentTRElement, ['td.fieldLabel input'])[0].value,
+ value:MochiKit.Selector.findChildElements(currentTRElement, ['td.fieldValue input'])[0].value
+ }, shouldRedrawAsLocked, MochiKit.DOM.hasElementClass(currentTRElement, 'new'));
+ },
+
+ //=========================================================================
+
+ 'fixNotesHeight': function () {
+ var element;
+
+ element = this.getElement('recordNote');
+
+ if (element.scrollHeight == 0) {
+ MochiKit.Async.callLater(0.1, MochiKit.Base.method(this, 'fixNotesHeight'));
+ } else {
+ var textareaHeight;
+
+ textareaHeight = Math.min(Math.max(50, element.scrollHeight), 500);
+
+ MochiKit.Style.setElementDimensions(element, {h:textareaHeight}, 'px');
+ MochiKit.Async.callLater(0.1, MochiKit.Base.method(this, 'fixRendering'));
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'fixRendering': function () {
+// var height;
+ var y;
+ var scrollHeight;
+ var viewportHeight;
+ var viewportY;
+ var footerElement;
+ var footerElementPosition;
+ var footerElementDimensions;
+ var footerComputedHeight;
+
+// height = MochiKit.Style.getElementDimensions(this.displayElement())['h'];
+ y = MochiKit.Style.getElementPosition(this.displayElement())['y'];
+
+ footerElement = MochiKit.Selector.findChildElements(this.displayElement(), ['div.footer'])[0];
+ footerElementPosition = MochiKit.Style.getElementPosition(footerElement);
+ footerElementDimensions = MochiKit.Style.getElementDimensions(footerElement);
+ footerComputedHeight = footerElementPosition['y'] + footerElementDimensions['h'] - y;
+
+// scrollHeight = this.displayElement().scrollHeight;
+ scrollHeight = footerComputedHeight;
+
+ viewportHeight = MochiKit.Style.getViewportDimensions()['h'];
+ viewportY = MochiKit.Style.getViewportPosition()['y'];
+
+ if ((y + scrollHeight) > (viewportY + viewportHeight)) {
+ this.setDisplayMode('scrollable');
+ MochiKit.DOM.addElementClass(this.element(), 'scrollable');
+ MochiKit.DOM.removeElementClass(this.element(), 'fixed');
+ MochiKit.Style.setElementPosition(this.displayElement(), {y:Math.max(0, Math.min(y, (viewportY + viewportHeight) - scrollHeight))}, 'px');
+ MochiKit.Visual.ScrollTo(this.displayElement(), {duration:0.5});
+ } else {
+ this.setDisplayMode('fixed');
+ MochiKit.DOM.removeElementClass(this.element(), 'scrollable');
+ MochiKit.DOM.addElementClass(this.element(), 'fixed');
+ }
+ },
+
+ //=========================================================================
+
+ 'unselectCurrentSelectedItems': function () {
+ MochiKit.Iter.forEach(MochiKit.Selector.findChildElements(this.displayElement(), ['.selectedField']), function (anElement) {
+ MochiKit.DOM.removeElementClass(anElement, 'selectedField');
+ });
+ },
+
+ //=========================================================================
+
+ 'hideProgressMask': function () {
+ MochiKit.DOM.removeElementClass(this.getId('panel'), 'loading');
+ },
+
+ 'showProgressMask': function () {
+ this.getElement('progressDescription').innerHTML = "Saving";
+ MochiKit.DOM.addElementClass(this.getId('panel'), 'loading');
+ },
+
+ 'showError': function (anError) {
+//console.log(">>> showError", anError);
+ MochiKit.Style.hideElement(this.getId('progress'));
+ this.getElement('errorMessage').innerHTML = Clipperz.PM.Strings.errorDescriptionForException(anError['message']);
+ MochiKit.Style.showElement(this.getId('error'));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'cancel': function () {
+/*
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("CardDialogComponent.cancel", {trace:false});
+ deferredResult.addCallback(MochiKit.Base.method(this, 'isSavingEnabled'));
+ deferredResult.addIf([
+ MochiKit.Base.method(this, 'askConfirmationForLoosingPendingChanges')
+ ], []);
+ deferredResult.addCallback(MochiKit.Base.partial(MochiKit.Signal.signal, this, 'cancel'));
+ deferredResult.callback();
+
+ return deferredResult;
+*/
+ MochiKit.Signal.signal(this, 'cancel');
+ },
+
+ 'handleCancelEvent': function (anEvent) {
+ anEvent.preventDefault();
+ this.cancel();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleSaveEvent': function (anEvent) {
+ anEvent.preventDefault();
+
+ if (! MochiKit.DOM.hasElementClass(anEvent.src(), 'disabled')) {
+ MochiKit.Signal.signal(this, 'save');
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleAddDirectLogin': function (anEvent) {
+ anEvent.preventDefault();
+
+ MochiKit.Signal.signal(this, 'addDirectLogin');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleOnFocusEvent': function (anElement, anEvent) {
+ this.unselectCurrentSelectedItems();
+ MochiKit.DOM.addElementClass(anElement, 'selectedField');
+ },
+
+ 'handleLooseFocusEvent': function (anElement, anEvent) {
+ this.unselectCurrentSelectedItems();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleTabSelected': function (aSelectedTab) {
+ this.unselectCurrentSelectedItems();
+
+ switch (aSelectedTab) {
+ case 'DETAILS':
+// MochiKit.Style.hideElement(this.getElement('addDirectLoginButton'));
+ break;
+ case 'DIRECT_LOGINS':
+// MochiKit.Style.showElement(this.getElement('addDirectLoginButton'));
+ break;
+ case 'SHARING':
+// MochiKit.Style.hideElement(this.getElement('addDirectLoginButton'));
+ break;
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleKeyEvent': function (anEvent) {
+//console.log("####", anEvent.key().string);
+ if (anEvent.key().string == 'KEY_ESCAPE') {
+ MochiKit.Signal.signal(this, 'changedValue');
+ this.cancel();
+ } else if (anEvent.key().string == 'KEY_ENTER') {
+ if (anEvent.target().nodeName == 'TEXTAREA') {
+
+ } else {
+ anEvent.preventDefault();
+ }
+ }
+ },
+
+ //=========================================================================
+
+ 'askConfirmationForLoosingPendingChanges': function () {
+ var deferredResult;
+ var confirmationDialog;
+
+ confirmationDialog = new Clipperz.PM.UI.Common.Components.SimpleMessagePanel({
+ title: "Alert",
+ text: "Should lost pending changes?",
+ type: 'ALERT',
+ buttons: [
+ {text:"Cancel", result:'CANCEL', isDefault:true},
+ {text:"Ok", result:'OK'}
+ ]
+ });
+
+ deferredResult = new Clipperz.Async.Deferred("CardDialogComponent.askConfirmationForLoosingPendingChanges", {trace:false});
+// deferredResult = confirmationDialog.deferredShow({openFromElement:anEvent.src(), onOkCloseToElement:MochiKit.DOM.currentDocument().body, onCancelCloseToElement:anEvent.src()});
+ deferredResult.addMethod(confirmationDialog, 'deferredShow', {
+ 'openFromElement': this.getElement('cancelButton'),
+ 'onOkCloseToElement': null, // this.getElement('cancelButton'),
+ 'onCancelCloseToElement': this.getElement('cancelButton')
+ });
+// deferredResult.addCallback(function () { console.log("DELETE: " + anObject.toString(), anObject); });
+// deferredResult.addErrbackPass(function () { console.log("skip deletion: " + anObject.toString(), anObject); });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'showDirectLoginEditingComponent': function () {
+ var width;
+ var transition;
+ var duration;
+
+ width = MochiKit.Style.getElementDimensions(this.getElement('directLoginsComponentContainer'))['w'];
+ transition = MochiKit.Visual.Transitions.sinoidal;
+ duration = 1;
+
+ return Clipperz.Async.callbacks("CardDialogComponent.showDirectLoginEditingComponent", [
+ MochiKit.Base.method(this, 'disableCardTitleEditing'),
+ MochiKit.Base.method(this.tabPanelController(), 'disable'),
+
+ MochiKit.Base.bind(function () {
+ MochiKit.Style.setElementPosition (this.getElement('directLoginEditDetail'), {x:width, y:-MochiKit.Style.getElementDimensions(this.getElement('directLogins'))['h']});
+ MochiKit.Style.setElementDimensions(this.getElement('directLoginEditDetail'), {w:width});
+ MochiKit.Style.showElement(this.getElement('directLoginEditDetail'));
+ MochiKit.Style.setOpacity(this.getElement('directLoginEditDetail'), 0);
+ MochiKit.Style.setElementDimensions(this.getElement('directLoginsComponentContainer'), {
+ h:Math.max(
+ MochiKit.Style.getElementDimensions(this.getElement('directLogins'))['h'],
+ MochiKit.Style.getElementDimensions(this.getElement('directLoginEditDetail'))['h']
+ )
+ });
+// MochiKit.Style.setElementDimensions(this.getElement('directLoginsComponentContainer'), {h:MochiKit.Style.getElementDimensions(this.getElement('directLogins'))['h']});
+ }, this),
+ MochiKit.Base.partial(Clipperz.Visual.deferredAnimations, MochiKit.Visual.Parallel, [
+ new MochiKit.Visual.Move(this.getElement('directLogins'), {x:-width, y:0, mode:'relative', transition:transition, sync:true}),
+ new MochiKit.Visual.Opacity(this.getElement('directLogins'), {from:1.0, to:0.0, transition:transition, sync:true}),
+ new MochiKit.Visual.Move(this.getElement('directLoginEditDetail'), {x:-width, y:0, mode:'relative', transition:transition, sync:true}),
+ new MochiKit.Visual.Opacity(this.getElement('directLoginEditDetail'), {from:0.0, to:1.0, transition:transition, sync:true})
+ ], {duration:duration}),
+
+ MochiKit.Base.noop
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hideDirectLoginEditingComponent': function () {
+ var width;
+ var transition;
+ var duration;
+
+ width = MochiKit.Style.getElementDimensions(this.getElement('directLoginsComponentContainer'))['w'];
+ transition = MochiKit.Visual.Transitions.sinoidal;
+ duration = 1;
+
+ return Clipperz.Async.callbacks("CardDialogComponent.hideDirectLoginEditingComponent", [
+ MochiKit.Base.partial(Clipperz.Visual.deferredAnimations, MochiKit.Visual.Parallel, [
+ new MochiKit.Visual.Move(this.getElement('directLogins'), {x:width, y:0, mode:'relative', transition:transition, sync:true}),
+ new MochiKit.Visual.Opacity(this.getElement('directLogins'), {from:0.0, to:1.0, transition:transition, sync:true}),
+ new MochiKit.Visual.Move(this.getElement('directLoginEditDetail'), {x:width, y:0, mode:'relative', transition:transition, sync:true}),
+ new MochiKit.Visual.Opacity(this.getElement('directLoginEditDetail'), {from:1.0, to:0.0, transition:transition, sync:true})
+ ], {duration:duration}),
+// MochiKit.Base.partial(MochiKit.Visual.appear, this.getElement('addDirectLoginButton'), {duration:0.3}),
+ Clipperz.Async.clearResult,
+ MochiKit.Base.partial(MochiKit.Style.hideElement, this.getElement('directLoginEditDetail')),
+// MochiKit.Base.partial(MochiKit.Style.showElement, this.getElement('directLogins')),
+ MochiKit.Base.partial(MochiKit.Style.setElementDimensions, this.getElement('directLoginsComponentContainer'), {h:MochiKit.Style.getElementDimensions(this.getElement('directLogins'))['h']}),
+
+ MochiKit.Base.method(this, 'enableCardTitleEditing'),
+ MochiKit.Base.method(this.tabPanelController(), 'enable')
+ ], {trace:false});
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogRecordDirectLoginComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogRecordDirectLoginComponent.js
new file mode 100644
index 0000000..126c5b1
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogRecordDirectLoginComponent.js
@@ -0,0 +1,182 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.CardDialogRecordDirectLoginComponent = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.CardDialogRecordDirectLoginComponent.superclass.constructor.apply(this, arguments);
+
+ this._reference = args.reference || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._faviconComponent = null;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.CardDialogRecordDirectLoginComponent, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.CardDialogRecordDirectLoginComponent component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'reference': function () {
+ return this._reference;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function() {
+//console.log(">>> CardDialogRecordDirectLoginComponent.renderSelf");
+ this.append(this.element(), [
+ {tag:'div', cls:'cardDialogRecordDirectLoginComponent_favicon', children:[
+ {tag:'img', cls:'favicon', id:this.getId('favicon')}
+ ]},
+ {tag:'div', cls:'cardDialogRecordDirectLoginComponent_label', children:[
+ {tag:'input', id:this.getId('label'), type:'text'}
+ ]},
+ {tag:'div', cls:'open', children:[
+ {tag:'span', children:[
+ {tag:'a', href:'open', id:this.getId('open'), html:'&nbsp;'}
+ ]}
+ ]},
+ {tag:'div', cls:'edit', children:[
+ {tag:'span', children:[
+ {tag:'a', href:'edit', id:this.getId('edit'), html:"edit"}
+ ]}
+ ]},
+ {tag:'div', cls:'delete', children:[
+ {tag:'span', children:[
+ {tag:'a', href:'delete', id:this.getId('delete'), html:"delete"}
+ ]}
+ ]}
+/*
+ {tag:'td', cls:'fieldState'},
+ {tag:'td', cls:'fieldLabel', children:[
+ {tag:'input', cls:'label', id:this.getId('label')}
+ ]},
+ {tag:'td', cls:'fieldLock', children:[
+ {tag:'div', cls:'unlocked', id:this.getId('isHidden')}
+ ]},
+ {tag:'td', cls:'fieldValue', children:[
+ {tag:'div', cls:'unlocked', id:this.getId('valueWrapper'), children:[
+ {tag:'input', type:'text', cls:'value', id:this.getId('value')}
+ ]}
+ ]},
+ {tag:'td', cls:'fieldAddDelete', children:[
+ {tag:'div', cls:'delete', children:[
+ {tag:'span', children:[
+ {tag:'a', href:'#', id:this.getId('delete'), html:"delete"}
+ ]}
+ ]}
+ ]}
+*/
+ ]);
+
+ MochiKit.Signal.connect(this.getId('label'), 'onkeyup', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue'));
+ MochiKit.Signal.connect(this.getId('open'), 'onclick', this, 'openDirectLogin');
+ MochiKit.Signal.connect(this.getId('edit'), 'onclick', this, 'editDirectLogin');
+ MochiKit.Signal.connect(this.getId('delete'), 'onclick', this, 'deleteDirectLogin');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'shouldShowElementWhileRendering': function () {
+ return false;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'faviconComponent': function () {
+ if (this._faviconComponent == null) {
+//console.log("created the FAVICON component");
+ this._faviconComponent = new Clipperz.PM.UI.Common.Components.FaviconComponent({element:this.getId('favicon')});
+ }
+
+ return this._faviconComponent;
+ },
+
+ //=========================================================================
+
+ 'label': function () {
+ return this.getElement('label').value;
+ },
+
+ 'setLabel': function (aValue) {
+ this.getElement('label').value = Clipperz.Base.sanitizeString(aValue);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'favicon': function () {
+// return this.getElement('favicon').src;
+ return this.faviconComponent().src();
+ },
+
+ 'setFavicon': function (aValue) {
+// this.getElement('favicon').src = Clipperz.Base.sanitizeString(aValue);
+ this.faviconComponent().setSrc(Clipperz.Base.sanitizeString(aValue));
+ },
+
+ //=========================================================================
+
+ 'openDirectLogin': function (anEvent) {
+ anEvent.preventDefault();
+
+ MochiKit.Signal.signal(this, 'openDirectLogin', this.reference());
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'editDirectLogin': function (anEvent) {
+ anEvent.preventDefault();
+
+ MochiKit.Signal.signal(this, 'editDirectLogin', this.reference());
+//console.log("EDIT DIRECT LOGIN");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deleteDirectLogin': function (anEvent) {
+ anEvent.preventDefault();
+
+ MochiKit.Signal.signal(this, 'deleteDirectLogin', this.reference());
+//console.log("DELETE DIRECT LOGIN");
+ },
+
+
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js
new file mode 100644
index 0000000..c1a7c13
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js
@@ -0,0 +1,190 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.CardDialogRecordFieldComponent = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.CardDialogRecordFieldComponent.superclass.constructor.apply(this, arguments);
+
+ this._reference = args.reference || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._actionType = null;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.CardDialogRecordFieldComponent, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.CardDialogRecordFieldComponent component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function() {
+ this.append(this.element(), [
+ {tag:'td', cls:'fieldState'},
+ {tag:'td', cls:'fieldLabel', children:[
+ {tag:'input', cls:'label', id:this.getId('label')}
+ ]},
+ {tag:'td', cls:'fieldLock', children:[
+ {tag:'div', cls:'unlocked', id:this.getId('isHidden')}
+ ]},
+ {tag:'td', cls:'fieldValue', children:[
+ {tag:'div', cls:'unlocked', id:this.getId('valueWrapper'), children:[
+ {tag:'input', type:'text', cls:'value', id:this.getId('value')}
+ ]}
+ ]},
+ {tag:'td', cls:'fieldAction', children:[
+ {tag:'a', href:'#', id:this.getId('actionLink'), html:'&nbsp;'}
+ ]},
+ {tag:'td', cls:'fieldAddDelete', children:[
+ {tag:'div', cls:'delete', children:[
+ {tag:'span', children:[
+ {tag:'a', href:'#', id:this.getId('delete'), html:"delete"}
+ ]}
+ ]}
+ ]}
+ ]);
+
+ MochiKit.Signal.connect(this.getId('label'), 'onkeyup', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue'));
+ MochiKit.Signal.connect(this.getId('isHidden'), 'onclick', this, 'toggleIsHidden');
+ MochiKit.Signal.connect(this.getId('value'), 'onkeyup', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'changedValue'));
+ MochiKit.Signal.connect(this.getId('actionLink'), 'onclick', this, 'handleActionLink');
+ MochiKit.Signal.connect(this.getId('delete'), 'onclick', this, 'deleteField');
+// MochiKit.Signal.connect(this.getId('delete'), 'onclick', MochiKit.Base.partial(MochiKit.Signal.signal, this, 'deleteField', this.reference()));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'shouldShowElementWhileRendering': function () {
+ return false;
+ },
+
+ //=========================================================================
+
+ 'reference': function () {
+ return this._reference;
+ },
+
+ //=========================================================================
+
+ 'label': function () {
+ return this.getElement('label').value;
+ },
+
+ 'setLabel': function (aValue) {
+// this.getElement('label').value = Clipperz.Base.sanitizeString(aValue);
+ this.getElement('label').value = aValue;
+ },
+
+ //=========================================================================
+
+ 'value': function () {
+ return this.getElement('value').value;
+ },
+
+ 'setValue': function (aValue) {
+// this.getElement('value').value = Clipperz.Base.sanitizeString(aValue);
+ this.getElement('value').value = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'actionType': function () {
+ return this._actionType;
+ },
+
+ 'setActionType': function (anActionType) {
+ this._actionType = anActionType;
+
+ switch (this._actionType) {
+ case 'NONE':
+ MochiKit.Style.hideElement(this.getId('actionLink'));
+ MochiKit.DOM.setElementClass(this.getId('actionLink'), '');
+ break;
+ case 'URL':
+ MochiKit.Style.showElement(this.getId('actionLink'));
+ MochiKit.DOM.setElementClass(this.getId('actionLink'), 'url');
+ break;
+ case 'EMAIL':
+ MochiKit.Style.showElement(this.getId('actionLink'));
+ MochiKit.DOM.setElementClass(this.getId('actionLink'), 'email');
+ break;
+ case 'PASSWORD':
+ MochiKit.Style.showElement(this.getId('actionLink'));
+ MochiKit.DOM.setElementClass(this.getId('actionLink'), 'password');
+ break;
+ }
+ },
+
+ //=========================================================================
+
+ 'isHidden': function () {
+// return this.getElement('value').value;
+ return MochiKit.DOM.hasElementClass(this.getElement('isHidden'), 'locked');
+ },
+
+ 'setIsHidden': function (aValue) {
+// this.getElement('value').value = Clipperz.Base.sanitizeString(aValue);
+ MochiKit.DOM.setElementClass(this.getElement('isHidden'), (aValue ? 'locked': 'unlocked'));
+ MochiKit.DOM.setElementClass(this.getElement('valueWrapper'), (aValue ? 'locked': 'unlocked'));
+ },
+
+ 'toggleIsHidden': function (anEvent) {
+ anEvent.preventDefault();
+
+ this.setIsHidden(! this.isHidden());
+ MochiKit.Signal.signal(this, 'changedValue');
+ },
+
+ //=========================================================================
+
+ 'handleActionLink': function (anEvent) {
+ anEvent.preventDefault();
+
+//console.log("ACTION LINK - " + this.actionType());
+ MochiKit.Signal.signal(this, 'performAction', this.reference(), anEvent.target());
+ },
+
+ //=========================================================================
+
+ 'deleteField': function (anEvent) {
+ anEvent.preventDefault();
+
+ MochiKit.Signal.signal(this, 'deleteField', this.reference());
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ColumnManager.js
new file mode 100644
index 0000000..bfc7e61
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ColumnManager.js
@@ -0,0 +1,203 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+//#############################################################################
+
+Clipperz.PM.UI.Web.Components.ColumnManager = function(args) {
+ args = args || {};
+ Clipperz.PM.UI.Web.Components.ColumnManager.superclass.constructor.call(this, args);
+
+ this._name = args.name || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._selector = args.selector || Clipperz.Base.exception.raise('MandatoryParameter');;
+ this._label = args.label || null;
+ this._isSortable = args.sortable || false;
+ this._comparator = args.comparator || null;
+ this._sorted = args.sorted || 'UNSORTED'; // 'ASCENDING' | 'DESCENDING' | 'UNSORTED'
+ this._cssClass = args.cssClass || '';
+
+ this._signalIdentifiers = [];
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.ColumnManager, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.ColumnManager - " + this._name;
+ },
+
+ 'name': function () {
+ return this._name;
+ },
+
+ 'label': function () {
+ return this._label;
+ },
+
+ 'selector': function () {
+ return this._selector;
+ },
+
+ 'comparator': function() {
+ return this._comparator;
+ },
+
+ 'cssClass': function() {
+ return this._cssClass;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isSortable': function () {
+ return this._isSortable;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'sorted': function () {
+ return this._sorted;
+ },
+
+ 'isSorted': function () {
+ return (this.sorted() != 'UNSORTED');
+ },
+
+ 'setSorted': function(aValue) {
+ this._sorted = aValue;
+ this.updateSortIcon();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'signalIdentifiers': function () {
+ return this._signalIdentifiers;
+ },
+
+ 'resetSignalIdentifiers': function () {
+ this._signalIdentifiers = [];
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'disconnectRowsSignals': function () {
+ MochiKit.Base.map(MochiKit.Signal.disconnect, this.signalIdentifiers());
+ this.resetSignalIdentifiers();
+ },
+
+ 'connectEvent': function () {
+ var ident;
+
+ ident = MochiKit.Signal.connect.apply(null, arguments);
+ this.signalIdentifiers().push(ident);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderHeader': function(aTRElement) {
+ var thElement;
+
+ thElement = Clipperz.DOM.Helper.append(aTRElement, {tag:'th', cls:(this.cssClass() + 'TH'), id:this.getId('sortLink'), children:[
+ {tag:'span', html:this.label() ? this.label() : '&nbsp;'}
+ ]});
+
+ if (this.isSortable()) {
+ Clipperz.DOM.Helper.append(thElement, {tag:'span', cls:'sortable', children:[
+ {tag:'a', href:'#'/*, id:this.getId('sortLink')*/, html:'&nbsp;'}
+ ]});
+
+ MochiKit.DOM.addElementClass(thElement, 'sortable');
+ MochiKit.Signal.connect(thElement, 'onclick', this, 'handleClickOnSortingCriteria');
+ };
+
+ this.updateSortIcon();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toggleSorting': function () {
+ var result;
+ switch (this.sorted()) {
+ case 'UNSORTED':
+ result = 'ASCENDING';
+ break;
+ case 'ASCENDING':
+ result = 'DESCENDING';
+ break;
+ case 'DESCENDING':
+ result = 'ASCENDING';
+ break;
+ default:
+ result = 'UNSORTED';
+ break;
+ }
+
+ this.setSorted(result);
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'sortElementClass': function () {
+ return this.sorted().toLowerCase();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateSortIcon': function () {
+ if (this.isSortable()) {
+ MochiKit.DOM.removeElementClass(this.getId('sortLink'), 'ascending');
+ MochiKit.DOM.removeElementClass(this.getId('sortLink'), 'descending');
+ MochiKit.DOM.removeElementClass(this.getId('sortLink'), 'unsorted');
+
+ MochiKit.DOM.addElementClass(this.getId('sortLink'), this.sortElementClass());
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderCell': function(aRowElement, anObject) {
+ Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[{tag:'span', html:anObject[this.name()]}]});
+ },
+
+ //-----------------------------------------------------
+
+ 'handleClickOnSortingCriteria': function (anEvent) {
+ anEvent.preventDefault();
+ MochiKit.Signal.signal(this, 'sort', this);
+ },
+
+ //-----------------------------------------------------
+ '__syntax_fix__' : 'syntax fix'
+
+});
+
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CreateNewCardSplashComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CreateNewCardSplashComponent.js
new file mode 100644
index 0000000..61d6ead
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/CreateNewCardSplashComponent.js
@@ -0,0 +1,71 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.CreateNewCardSplashComponent = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.CreateNewCardSplashComponent.superclass.constructor.apply(this, arguments);
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.CreateNewCardSplashComponent, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.CreateNewCardSplashComponent component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function() {
+ this.append(this.element(), [
+ {tag:'div', cls:'createNewCardSplash', id:this.getId('button'), children:[
+ {tag:'span', html:"Create New Card"}
+ ]}
+ ]);
+
+ MochiKit.Signal.connect(this.getElement('button'), 'onclick', this, 'handleClick');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleClick': function (anEvent) {
+ anEvent.preventDefault();
+ MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'addCard', this.element());
+ },
+
+ //-------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js
new file mode 100644
index 0000000..91d99e3
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DataPanel.js
@@ -0,0 +1,111 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.DataPanel = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.DataPanel.superclass.constructor.apply(this, arguments);
+
+ this._initiallySelectedTab = args.selected || 'OFFLINE_COPY';
+ this._tabPanelControllerConfiguration = {
+ 'OFFLINE_COPY': {
+ tab: 'offlineCopyTab',
+ panel: 'offlineCopyPanel'
+ },
+ 'SHARING': {
+ tab: 'sharingTab',
+ panel: 'sharingPanel'
+ },
+ 'IMPORT': {
+ tab: 'importTab',
+ panel: 'importPanel'
+ },
+ 'EXPORT': {
+ tab: 'exportTab',
+ panel: 'exportPanel'
+ }
+ };
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DataPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.DataPanel component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.append(this.element(), [
+ {tag:'div', cls:'header', children:[
+ {tag:'div', cls:'subPanelTabs', children:[
+ {tag:'ul', children:[
+ {tag:'li', id:this.getId('offlineCopyTab'), children:[{tag:'a', href:'#', html:'Offline copy'}], cls:'first'},
+ {tag:'li', id:this.getId('sharingTab'), children:[{tag:'a', href:'#', html:'Sharing'}]},
+ {tag:'li', id:this.getId('importTab'), children:[{tag:'a', href:'#', html:'Import'}]},
+ {tag:'li', id:this.getId('exportTab'), children:[{tag:'a', href:'#', html:'Export'}]}
+ ]}
+ ]}
+ ]},
+ {tag:'div', cls:'body', children:[
+ {tag:'div', cls:'accountPanel', children:[
+ {tag:'div', cls:'subPanelContent', children:[
+ {tag:'ul', children:[
+ {tag:'li', id:this.getId('offlineCopyPanel'), children:[
+ {tag:'h3', html:"Offline copy"}
+ ]},
+ {tag:'li', id:this.getId('sharingPanel'), children:[
+ {tag:'h3', html:"Sharing"}
+ ]},
+ {tag:'li', id:this.getId('importPanel'), children:[
+ {tag:'h3', html:"Import"}
+ ]},
+ {tag:'li', id:this.getId('exportPanel'), children:[
+ {tag:'h3', html:"Export"}
+ ]}
+ ]}
+ ]}
+ ]}
+ ]},
+ {tag:'div', cls:'footer'}
+ ]);
+
+ this.tabPanelController().setup({selected:this.initiallySelectedTab()});
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DateColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DateColumnManager.js
new file mode 100644
index 0000000..3f8aa88
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DateColumnManager.js
@@ -0,0 +1,72 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+//#############################################################################
+
+Clipperz.PM.UI.Web.Components.DateColumnManager = function(args) {
+ args = args || {};
+ Clipperz.PM.UI.Web.Components.DateColumnManager.superclass.constructor.call(this, args);
+
+ this._format = args.format || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DateColumnManager, Clipperz.PM.UI.Web.Components.ColumnManager, {
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.DateColumnManager component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'format': function () {
+ return this._format;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderCell': function(aRowElement, anObject) {
+ Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[
+ {
+ tag:'span',
+ title:Clipperz.PM.Date.formatDateWithTemplate(anObject[this.name()], "D, d M Y H:i:s"),
+ html:Clipperz.PM.Date.formatDateWithTemplate(anObject[this.name()], this.format())
+ }
+ ]});
+ },
+
+ //-----------------------------------------------------
+
+ '__syntax_fix__' : 'syntax fix'
+});
+
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DeleteObjectColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DeleteObjectColumnManager.js
new file mode 100644
index 0000000..ee60f2f
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DeleteObjectColumnManager.js
@@ -0,0 +1,70 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+//#############################################################################
+
+Clipperz.PM.UI.Web.Components.DeleteObjectColumnManager = function(args) {
+ args = args || {};
+ Clipperz.PM.UI.Web.Components.DeleteObjectColumnManager.superclass.constructor.call(this, args);
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DeleteObjectColumnManager, Clipperz.PM.UI.Web.Components.LinkColumnManager, {
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.DeleteObjectColumnManager component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderCell': function(aRowElement, anObject) {
+ var tdElement;
+ var linkElement;
+
+ tdElement = Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[
+ {tag:'div', cls:'delete', children:[
+ {tag:'span', children:[
+ {tag:'a', href:'delete', html:"delete"}
+ ]}
+ ]}
+ ]});
+
+ linkElement = MochiKit.DOM.getFirstElementByTagAndClassName('a', null, tdElement);
+// MochiKit.Signal.connect(linkElement, 'onclick', MochiKit.Base.method(this, 'handleLinkClick', anObject['_rowObject']));
+ this.connectEvent(linkElement, 'onclick', MochiKit.Base.method(this, 'handleLinkClick', anObject['_rowObject']));
+ },
+
+ //-----------------------------------------------------
+ '__syntax_fix__' : 'syntax fix'
+});
+
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginColumnManager.js
new file mode 100644
index 0000000..4bf9020
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginColumnManager.js
@@ -0,0 +1,90 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+//#############################################################################
+
+Clipperz.PM.UI.Web.Components.DirectLoginColumnManager = function(args) {
+ args = args || {};
+ Clipperz.PM.UI.Web.Components.DirectLoginColumnManager.superclass.constructor.call(this, args);
+
+ this._actionMethod = args.actionMethod || null;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DirectLoginColumnManager, Clipperz.PM.UI.Web.Components.ColumnManager, {
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.DateColumnManager component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'actionMethod': function () {
+ return this._actionMethod;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderCell': function(aRowElement, anObject) {
+ var tdElement;
+ var linkElement;
+
+ tdElement = Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[
+ {tag:'div', cls:'directLogin_directLogin', children:[
+ {tag:'div', cls:'directLogin_directLogin_body', children:[
+ {tag:'a', href:'#', html:anObject[this.name()]}
+ ]}
+ ]}
+ ]});
+
+ linkElement = MochiKit.DOM.getFirstElementByTagAndClassName('a', null, tdElement);
+// MochiKit.Signal.connect(linkElement, 'onclick', MochiKit.Base.method(this, 'handleLinkClick', anObject['_rowObject']));
+ this.connectEvent(linkElement, 'onclick', MochiKit.Base.method(this, 'handleLinkClick', anObject['_rowObject']));
+ },
+
+ //-----------------------------------------------------
+
+ 'handleLinkClick': function (anObject, anEvent) {
+ anEvent.preventDefault();
+
+ if (this.actionMethod() != null) {
+ this.actionMethod()(anObject, anEvent);
+ }
+ },
+
+ //-----------------------------------------------------
+ '__syntax_fix__' : 'syntax fix'
+});
+
+*/ \ No newline at end of file
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingBindingComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingBindingComponent.js
new file mode 100644
index 0000000..9a9c0b2
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingBindingComponent.js
@@ -0,0 +1,168 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.DirectLoginEditingBindingComponent = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.DirectLoginEditingBindingComponent.superclass.constructor.apply(this, arguments);
+
+ this._formFieldName = args.formFieldName || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._fields = args.fields || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._initiallySelectedFieldKey = args.selectedFieldKey || null;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DirectLoginEditingBindingComponent, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.DirectLoginEditingBindingComponent component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'formFieldName': function () {
+ return this._formFieldName;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'fields': function () {
+ return this._fields;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'selectedValue': function () {
+ var result;
+
+ result = this.getElement('select').value;
+
+ if (result == '---') {
+ result = null;
+ }
+
+ return result;
+ },
+
+ 'initiallySelectedFieldKey': function () {
+ return this._initiallySelectedFieldKey;
+ },
+
+ //=========================================================================
+
+ 'renderSelf': function() {
+ var initiallySelectedOptions;
+
+ this.append(this.element(), {tag:'div', id:this.getId('div'), cls:'binding', children:[
+ {tag:'span', cls:'formFieldName', html:this.formFieldName()},
+ {tag:'span', cls:'fieldLock', id:this.getId('isHidden'), children:[
+ {tag:'a', href:'#', id:this.getId('showHide'), html:'&nbsp;'}
+ ]},
+ {tag:'input', id:this.getId('input'), cls:'formFieldExampleValue', disabled:true, value:''},
+ {tag:'select', name:this.formFieldName(), id:this.getId('select'), cls:'formFieldMatchinCardField', children:
+ MochiKit.Base.flattenArguments(
+ {tag:'option', value:'---', html:"---"},
+ MochiKit.Base.map(
+ MochiKit.Base.bind(function (aField) { return {tag:'option', value:aField['reference'], html:aField['label']}; }, this),
+ this.fields()
+ )
+ )
+ }
+ ]});
+
+ MochiKit.Signal.connect(this.getElement('select'), 'onchange', this, 'handleSelectChange');
+ MochiKit.Signal.connect(this.getElement('showHide'), 'onclick', this, 'handleShowHide');
+
+ if (! MochiKit.Base.isUndefinedOrNull(this.initiallySelectedFieldKey())) {
+ initiallySelectedOptions = MochiKit.Selector.findChildElements(this.element(), ['option[value=' + this.initiallySelectedFieldKey() + ']']);
+ if (initiallySelectedOptions.length == 1) {
+ MochiKit.DOM.updateNodeAttributes(initiallySelectedOptions[0], {selected:true});
+ this.handleSelectChange();
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setFieldValue': function (aValue) {
+ this.getElement('input').value = aValue;
+ },
+
+ 'isHidden': function () {
+ return MochiKit.DOM.hasElementClass(this.getElement('div'), 'locked');
+ },
+
+ 'setIsHidden': function (aValue) {
+ if (aValue == true) {
+ MochiKit.DOM.addElementClass(this.getElement('div'), 'locked');
+ MochiKit.DOM.addElementClass(this.getElement('div'), 'showLocked');
+ } else {
+ MochiKit.DOM.removeElementClass(this.getElement('div'), 'locked');
+ MochiKit.DOM.removeElementClass(this.getElement('div'), 'showLocked');
+ }
+ },
+
+ 'isShowLocked': function () {
+ return MochiKit.DOM.hasElementClass(this.getElement('div'), 'showLocked');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleSelectChange': function (anEvent) {
+// this.getElement('input').value = this.valueOfField(anEvent.src().value);
+ MochiKit.Signal.signal(this, 'bindChange', this);
+ },
+
+ 'handleShowHide': function (anEvent) {
+ anEvent.preventDefault();
+
+ if (this.isShowLocked()) {
+ MochiKit.DOM.removeElementClass(this.getElement('div'), 'showLocked');
+ } else {
+ MochiKit.DOM.addElementClass(this.getElement('div'), 'showLocked');
+ }
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
+
+
+
+
+
+
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingComponent.js
new file mode 100644
index 0000000..d254c29
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingComponent.js
@@ -0,0 +1,481 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.DirectLoginEditingComponent = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.DirectLoginEditingComponent.superclass.constructor.apply(this, arguments);
+
+ this._tabPanelController = null;
+
+ this._initiallySelectedTab = args.selected || 'TYPE';
+ this._tabPanelControllerConfiguration = {
+ 'LABEL': {
+ tab: 'labelTab',
+ panel: 'labelTabpanel'
+ },
+ 'TYPE': {
+ tab: 'typeTab',
+ panel: 'typeTabpanel'
+ },
+ 'CONFIGURATION': {
+ tab: 'configurationTab',
+ panel: 'configurationTabpanel'
+ },
+ 'BINDINGS': {
+ tab: 'bindingsTab',
+ panel: 'bindingsTabpanel'
+ },
+ 'FAVICON': {
+ tab: 'faviconTab',
+ panel: 'faviconTabpanel'
+ },
+ 'DONE': {
+ tab: 'doneTab',
+ panel: 'doneTabpanel'
+ }
+ };
+
+ this._directLoginReference = null;
+
+ this._directLoginFavicon = null;
+
+ this._updateFaviconCounter = 0;
+ this._faviconComponent = null;
+
+ this._bindingComponents = [];
+ this._formValueComponents = [];
+
+ return this;
+}
+
+//=============================================================================
+
+//Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DirectLoginEditingComponent, Clipperz.PM.UI.Common.Components.BaseComponent, {
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DirectLoginEditingComponent, Clipperz.PM.UI.Common.Components.TabPanelComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.DirectLoginEditingComponent component";
+ },
+
+ //=========================================================================
+
+ 'directLoginReference': function () {
+ return this._directLoginReference;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setDirectLoginReference': function (aDirectLoginReference) {
+ this._directLoginReference = aDirectLoginReference;
+
+ return this._directLoginReference;
+ },
+
+ //=========================================================================
+
+ 'label': function () {
+ return this.getElement('label').value
+ },
+
+ 'setLabel': function (aValue) {
+//console.log("##> LABEL: " + aValue);
+ this.getElement('label').value = (aValue ? aValue : '');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'favicon': function () {
+ return this.getElement('faviconURL').value;
+ },
+
+ 'setFavicon': function (aValue) {
+ var regexp;
+ var displayValue;
+
+ regexp = new RegExp('^data\:\/\/.*', 'i');
+ if (regexp.test(aValue)) {
+ displayValue = ''
+ } else {
+ displayValue = (aValue ? aValue : '');
+ }
+
+ this.getElement('faviconURL').value = displayValue;
+ this.faviconComponent().setSrc(aValue);
+ },
+
+// 'setFaviconData': function (aValue) {
+// this.getElement('faviconIcon').src = aValue;
+// },
+
+ 'directLoginFavicon': function () {
+ return this._directLoginFavicon;
+ },
+
+ 'setDirectLoginFavicon': function (aValue) {
+ this._directLoginFavicon = aValue;
+ this.setFavicon(aValue);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'bookmarkletConfiguration': function () {
+ return this.getElement('bookmarkletConfiguration').value
+ },
+
+ 'setBookmarkletConfiguration': function (aValue) {
+ this.getElement('bookmarkletConfiguration').value = aValue;
+ },
+
+ 'highlightConfigurationSyntaxError': function () {
+ MochiKit.DOM.addElementClass(this.getElement('bookmarkletConfiguration'), 'error');
+ },
+
+ 'removeHighlightConfigurationSyntaxError': function () {
+ MochiKit.DOM.removeElementClass(this.getElement('bookmarkletConfiguration'), 'error');
+ },
+
+ //=========================================================================
+
+ 'disableAllPanels': function () {
+ this.getElement('label').disabled = true;
+ MochiKit.DOM.addElementClass(this.getElement('label').parentNode, 'disabled');
+
+ this.tabPanelController().selectTab(null);
+ },
+
+ //-------------------------------------------------------------------------
+
+// 'disableLabelField': function () {
+// this.getElement('label').disabled = true;
+// MochiKit.DOM.addElementClass(this.getElement('label').parentNode, 'disabled');
+// },
+
+ 'enableLabelField': function () {
+ this.getElement('label').disabled = false;
+ MochiKit.DOM.removeElementClass(this.getElement('label').parentNode, 'disabled');
+ this.tabPanelController().selectTab('LABEL');
+ },
+
+ //-------------------------------------------------------------------------
+
+// 'disableTypeField': function () {
+// this.tabPanelController().selectTab(null);
+// },
+
+ 'enableTypeField': function () {
+ this.tabPanelController().selectTab('TYPE');
+ },
+
+ //-------------------------------------------------------------------------
+
+// 'disableConfigurationField': function () {
+// this.tabPanelController().selectTab(null);
+// },
+
+ 'enableConfigurationField': function () {
+ this.tabPanelController().selectTab('CONFIGURATION');
+ },
+
+ //-------------------------------------------------------------------------
+
+// 'disableBindingFields': function () {
+// this.tabPanelController().selectTab(null);
+// },
+
+ 'enableBindingFields': function () {
+ this.tabPanelController().selectTab('BINDINGS');
+ },
+
+ //-------------------------------------------------------------------------
+
+// 'disableFaviconField': function () {
+// this.tabPanelController().selectTab(null);
+// },
+
+ 'enableFaviconField': function () {
+ this.tabPanelController().selectTab('FAVICON');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'enableDonePanel': function () {
+ this.tabPanelController().selectTab('DONE');
+ },
+
+ //=========================================================================
+
+ 'shouldShowElementWhileRendering': function() {
+ return false;
+ },
+
+ //=========================================================================
+
+ 'faviconComponent': function () {
+ if (this._faviconComponent == null) {
+ this._faviconComponent = new Clipperz.PM.UI.Common.Components.FaviconComponent({element:this.getId('favicon')});
+ }
+
+ return this._faviconComponent;
+ },
+
+ //=========================================================================
+
+ 'tabPanelController': function () {
+ if (this._tabPanelController == null) {
+ this._tabPanelController = new Clipperz.PM.UI.Common.Controllers.TabPanelController({
+ component:this,
+ configuration:this._tabPanelControllerConfiguration
+ });
+
+ MochiKit.Signal.connect(this._tabPanelController, 'tabSelected', this, 'handleTabSelected')
+ }
+
+ return this._tabPanelController;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function() {
+ var bookmarkletComponent;
+
+ this.append(this.element(), {tag:'div', cls:'directLoginEditing', id:this.getId('panel'), children: [
+// {tag:'div', cls:'back', children:[
+// {tag:'a', href:'#', id:this.getId('back'), html:"&nbsp;"}
+// ]},
+ {tag:'form', id:this.getId('form'), cls:'directLoginEditingForm', children:[
+ {tag:'div', cls:'title', children:[
+ {tag:'img', id:this.getId('favicon'), cls:'favicon'},
+ {tag:'input', type:'text', id:this.getId('label')} //,
+// {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.LABEL.description')}]},
+ ]},
+ {tag:'div', cls:'tabContainer', children:[
+ {tag:'ul', cls:'tabs', children:[
+ {tag:'li', id:this.getId('labelTab'), children:[{tag:'span', html:"label"}]},
+ {tag:'li', id:this.getId('typeTab'), children:[{tag:'span', html:"type"}]},
+ {tag:'li', id:this.getId('configurationTab'), children:[{tag:'span', html:"configuration"}]},
+ {tag:'li', id:this.getId('bindingsTab'), children:[{tag:'span', html:"bindings"}]},
+ {tag:'li', id:this.getId('faviconTab'), children:[{tag:'span', html:"favicon"}]},
+ {tag:'li', id:this.getId('doneTab'), children:[{tag:'span', html:"done"}]}
+ ]},
+ {tag:'ul', cls:'tabPanels', children:[
+ {tag:'li', id:this.getId('labelTabpanel'), cls:'tabPanel label', children:[
+ {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.LABEL.description')}]}
+ ]},
+ {tag:'li', id:this.getId('typeTabpanel'), cls:'tabPanel type', children:[
+ {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.TYPE.description')}]},
+ {tag:'h2', html:"type"}
+ ]},
+ {tag:'li', id:this.getId('configurationTabpanel'), cls:'tabPanel configuration', children:[
+ {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.CONFIGURATION.description')}]},
+ {tag:'div', cls:'bookmarkletConfigurationWrapper', children:[
+ {tag:'textarea', id:this.getId('bookmarkletConfiguration'), value:""},
+// {tag:'div', cls:'bookmarkletComponentWrapper', children:[{tag:'div', id:this.getId('bookmarkletComponent'), cls:'bookmarkletComponent'}]}
+ {tag:'div', id:this.getId('bookmarkletComponent'), cls:'bookmarkletComponent'}
+ ]}
+ ]},
+ {tag:'li', id:this.getId('bindingsTabpanel'), cls:'tabPanel bindings', children:[
+ {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.BINDINGS.description')}]},
+ {tag:'div', cls:'bindings', id:this.getId('bindings'), children:[]},
+ {tag:'div', cls:'formValues', id:this.getId('formValues'), children:[]}
+ ]},
+ {tag:'li', id:this.getId('faviconTabpanel'), cls:'tabPanel favicon', children:[
+ {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.FAVICON.description')}]},
+ {tag:'div', cls:'favicon', children:[
+ {tag:'input', type:'text', id:this.getId('faviconURL')}
+ ]}
+ ]},
+ {tag:'li', id:this.getId('doneTabpanel'), cls:'tabPanel done', children:[
+ {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', id:this.getId('doneDescription')/*, html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.DONE.description')*/}]}
+ ]}
+ ]}
+ ]}
+ ]},
+ {tag:'div', cls:'clear'}
+ ]});
+
+ bookmarkletComponent = new Clipperz.PM.UI.Web.Components.BookmarkletComponent({element:this.getElement('bookmarkletComponent')});
+ bookmarkletComponent.render();
+
+ this.tabPanelController().setup(/*{selected:this.initiallySelectedTab()}*/);
+
+ MochiKit.Signal.connect(this.getId('label'), 'onchange', this, 'changedValue');
+ MochiKit.Signal.connect(this.getId('label'), 'onkeyup', this, 'changedValue');
+
+ MochiKit.Signal.connect(this.getId('bookmarkletConfiguration'), 'onchange', this, 'changedValue');
+ MochiKit.Signal.connect(this.getId('bookmarkletConfiguration'), 'onkeyup', this, 'changedValue');
+
+ MochiKit.Signal.connect(this.getId('faviconURL'), 'onchange', this, 'changedValue');
+ MochiKit.Signal.connect(this.getId('faviconURL'), 'onkeyup', this, 'changedValue');
+
+ MochiKit.Signal.connect(this.getId('panel'), 'onkeydown',this, 'handleKeyEvent');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleTabSelected': function (aSelectedTab) {
+ switch (aSelectedTab) {
+ case 'DETAILS':
+ break;
+ case 'DIRECT_LOGINS':
+ MochiKit.Style.hideElement(this.getElement('backToDirectLoginList'));
+ break;
+ case 'SHARING':
+ break;
+ }
+ },
+
+ //=========================================================================
+
+ 'incrementUpdateFaviconCounter': function () {
+ this._updateFaviconCounter ++;
+ },
+
+ 'decrementUpdateFaviconCounter': function () {
+ this._updateFaviconCounter --;
+ },
+
+ 'updateFaviconCounter': function () {
+ return this._updateFaviconCounter;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateFavicon': function () {
+ this.decrementUpdateFaviconCounter();
+
+ if (this.updateFaviconCounter() == 0) {
+ this.setFavicon(this.favicon());
+ }
+ },
+
+ //=========================================================================
+
+ 'bindingComponents': function () {
+ return this._bindingComponents;
+ },
+
+ 'clearAllBindingsComponents': function () {
+ MochiKit.Iter.forEach(this.bindingComponents(), MochiKit.Base.methodcaller('remove'));
+ this._bindingComponents = [];
+ this.getElement('bindings').innerHTML = '';
+ },
+
+ 'addBindingComponent': function (aBindingComponent) {
+ this.bindingComponents().push(aBindingComponent);
+ aBindingComponent.renderInNode(this.append(this.getElement('bindings'), {tag:'div'}));
+ },
+
+ //=========================================================================
+
+ 'formValueComponents': function () {
+ return this._formValueComponents;
+ },
+
+ 'clearAllFormValueComponents': function () {
+ MochiKit.Iter.forEach(this.formValueComponents(), MochiKit.Base.methodcaller('remove'));
+ this._formValueComponents = [];
+ this.getElement('formValues').innerHTML = '';
+ },
+
+ 'addFormValueComponent': function (aFormValueComponent) {
+ this.formValueComponents().push(aFormValueComponent);
+ aFormValueComponent.renderInNode(this.append(this.getElement('formValues'), {tag:'div'}));
+ },
+
+ //=========================================================================
+
+ 'changedValue': function (anEvent) {
+ MochiKit.Signal.signal(this, 'changedValue', anEvent);
+
+ this.incrementUpdateFaviconCounter();
+ MochiKit.Async.callLater(1, MochiKit.Base.method(this, 'updateFavicon'));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleBackClick': function (anEvent) {
+ anEvent.preventDefault();
+
+ MochiKit.Signal.signal(this, 'back');
+ },
+
+ //=========================================================================
+
+ 'bottomMargin': function () {
+ return MochiKit.Style.getElementPosition(this.element().parentNode)['y'] +
+ MochiKit.Style.getElementDimensions(this.element())['h'];
+ },
+
+ //=========================================================================
+
+ 'focusOnLabelElement': function () {
+ this.getElement('label').focus();
+ },
+
+ 'focusOnBookmarkletConfigurationElement': function () {
+ this.getElement('bookmarkletConfiguration').focus();
+ },
+
+ 'focusOnFaviconElement': function () {
+ this.getElement('faviconURL').focus();
+ },
+
+ //=========================================================================
+
+ 'setDoneDescriptionWithKeys': function (someKeys) {
+// {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', id:this.getId('doneDescription')/*, html:Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.DONE.description')*/}]}
+ this.getElement('doneDescription').innerHTML = Clipperz.PM.Strings.getValue('Wizards.DirectLoginWizard.DONE.description', someKeys);
+ },
+
+ //=========================================================================
+
+ 'handleKeyEvent': function (anEvent) {
+ MochiKit.Signal.signal(this, 'keyPressed', anEvent);
+/*
+ if (anEvent.key().string == 'KEY_ENTER') {
+ if (anEvent.target().nodeName != 'TEXTAREA') {
+ MochiKit.Signal.signal(this, 'moveForward');
+ anEvent.preventDefault();
+ }
+ } else if (anEvent.key().string == 'KEY_TAB') {
+ if ((anEvent.target().nodeName == 'INPUT') || (anEvent.target().nodeName == 'TEXTAREA')) {
+ MochiKit.Signal.signal(this, 'moveForward');
+ anEvent.preventDefault();
+ }
+ }
+*/
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingFormValueComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingFormValueComponent.js
new file mode 100644
index 0000000..b91eb98
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginEditingFormValueComponent.js
@@ -0,0 +1,179 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.DirectLoginEditingFormValueComponent = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.DirectLoginEditingFormValueComponent.superclass.constructor.apply(this, arguments);
+
+ this._formFieldName = args.formFieldName || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._fieldOptions = args.fieldOptions || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._initialValue = args.initialValue || null;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DirectLoginEditingFormValueComponent, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.DirectLoginEditingFormValueComponent component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'formFieldName': function () {
+ return this._formFieldName;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'fieldOptions': function () {
+ return this._fieldOptions;
+ },
+
+ 'fieldType': function () {
+ return this.fieldOptions()['type'];
+ },
+
+ 'optionValues': function () {
+ return MochiKit.Base.map(function (anOptionValue) {
+ return {
+ 'label': anOptionValue['label'] || anOptionValue['value'],
+ 'value': anOptionValue['value']
+ }
+ }, this.fieldOptions()['options']);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'selectedValue': function () {
+ var result;
+
+ result = this.getElement('select').value;
+
+ if (result == '---') {
+ result = null;
+ }
+
+ return result;
+ },
+
+ 'initialValue': function () {
+ return this._initialValue;
+ },
+
+ //=========================================================================
+
+ 'renderSelf': function() {
+//console.log(">>> DirectLoginEditingFormValueComponent.renderSelf");
+//console.log("FIELD OPTIONS", this.fieldOptions());
+//console.log("OPTION VALUES", this.optionValues());
+ this.append(this.element(), {tag:'div', id:this.getId('div'), cls:'formValue', children:[
+ {tag:'span', cls:'formFieldName', html:this.formFieldName()},
+ {tag:'div', id:this.getId('values')}
+ ]});
+
+ if ((this.fieldType() == 'radio') || (this.fieldType() == 'select')) {
+ this.append(this.getElement('values'),
+ {tag:'select', name:this.formFieldName(), id:this.getId('select'), cls:'formFieldMatchinCardField', children:
+ MochiKit.Base.flattenArguments(
+// {tag:'option', value:'---', html:"---"},
+ MochiKit.Base.map(
+ MochiKit.Base.bind(function (aValue) { return {tag:'option', value:aValue['value'], html:aValue['label']}; }, this),
+ this.optionValues()
+ )
+ )
+ }
+ );
+
+ MochiKit.Signal.connect(this.getElement('select'), 'onchange', this, 'handleSelectChange');
+
+ if (! MochiKit.Base.isUndefinedOrNull(this.initialValue())) {
+ var initiallySelectedOptions;
+ initiallySelectedOptions = MochiKit.Selector.findChildElements(this.element(), ['option[value=' + this.initialValue() + ']']);
+ if (initiallySelectedOptions.length == 1) {
+ MochiKit.DOM.updateNodeAttributes(initiallySelectedOptions[0], {selected:true});
+ this.handleSelectChange();
+ } else {
+ Clipperz.DOM.Helper.insertBefore(this.getElement('select').childNodes[0], {tag:'option', value:'---', html:"", selected:true});
+ }
+ } else {
+ Clipperz.DOM.Helper.insertBefore(this.getElement('select').childNodes[0], {tag:'option', value:'---', html:"", selected:true});
+ }
+ } else if (this.fieldType() == 'checkbox') {
+ this.append(this.getElement('values'),
+ {tag:'input', type:'checkbox', name:this.formFieldName(), id:this.getId('checkbox'), cls:'formFieldMatchinCardField'}
+ );
+
+ MochiKit.Signal.connect(this.getElement('checkbox'), 'onchange', this, 'handleSelectChange');
+
+ if (this.initialValue()) {
+ MochiKit.DOM.updateNodeAttributes(this.getElement('checkbox'), {checked:true});
+ }
+ } else {
+ WTF = TODO;
+ }
+//console.log("<<< DirectLoginEditingFormValueComponent.renderSelf");
+ },
+
+ //=========================================================================
+
+ 'handleSelectChange': function (anEvent) {
+//console.log("handleSelectChange", anEvent, anEvent.src(), anEvent.src().value);
+ var options;
+
+ options = {};
+
+ options['fieldName'] = this.formFieldName();
+
+ if (this.fieldType() == 'checkbox') {
+ options['selectedValue'] = (this.getElement('checkbox').checked ? 1 : null);
+ } else {
+ options['selectedValue'] = this.selectedValue();
+ }
+
+ MochiKit.Signal.signal(this, 'formValueChange', options);
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
+
+
+
+
+
+
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginsColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginsColumnManager.js
new file mode 100644
index 0000000..1f49575
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/DirectLoginsColumnManager.js
@@ -0,0 +1,271 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+//#############################################################################
+
+Clipperz.PM.UI.Web.Components.DirectLoginsColumnManager = function(args) {
+ args = args || {};
+ Clipperz.PM.UI.Web.Components.DirectLoginsColumnManager.superclass.constructor.call(this, args);
+
+ this._enterLeaveCounter = 0;
+ this._selectedRowObject = null;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.DirectLoginsColumnManager, Clipperz.PM.UI.Web.Components.ColumnManager, {
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.DirectLoginsColumnManager component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderHeader': function(aTRElement) {
+ Clipperz.PM.UI.Web.Components.DirectLoginsColumnManager.superclass.renderHeader.call(this, aTRElement);
+
+ Clipperz.DOM.Helper.append(MochiKit.DOM.currentDocument().body, {tag:'div', cls:'DirectLoginListPopup', id:this.getId('DirectLoginListPopup'), children:[
+ {tag:'div', cls:'DirectLoginListPopup_body', children:[
+ {tag:'ul', id:this.getId('DirectLoginListPopup_list'), children:[
+// {tag:'li', children:[
+// {tag:'img', cls:'favicon', src:'http://www.microsoft.com/favicon.ico'},
+// {tag:'a', href:'#', html:"Google Mail"}
+// ]},
+// ...
+ ]}
+ ]},
+ {tag:'div', cls:'DirectLoginListPopup_footer'}
+ ]});
+
+ MochiKit.Style.hideElement(this.getId('DirectLoginListPopup'));
+
+ // BEWARE: use MochiKit.Signal.connect instead of this.connectEvent, as the HEADER is NOT redrawn after each refresh
+ MochiKit.Signal.connect(this.getId('DirectLoginListPopup'), 'onmouseenter', this, 'handleDirectLoginListPopupEnter');
+ MochiKit.Signal.connect(this.getId('DirectLoginListPopup'), 'onmouseleave', this, 'handleDirectLoginListPopupLeave');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderCell': function(aRowElement, anObject) {
+ var i,c;
+ var directLoginsInfo;
+
+ directLoginsInfo = anObject[this.name()];
+
+ TDElement = Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:'card_directLogins'});
+
+ c = Math.min(2, directLoginsInfo.length);
+ for (i=0; i<c; i++) {
+ var elementID;
+
+ elementID = 'directLogin_' + directLoginsInfo[i]['_reference'];
+
+ Clipperz.DOM.Helper.append(TDElement, {tag:'div', cls:'card_directLogin', children:[
+ {tag:'div', cls:'card_directLogin_body', children:[
+ {tag:'a', href:'#', id:elementID, html:directLoginsInfo[i]['label']}
+ ]}
+ ]});
+// MochiKit.Signal.connect(elementID, 'onclick', MochiKit.Base.method(this, 'handleDirectLoginClick', directLoginsInfo[i]['_rowObject']));
+ this.connectEvent(elementID, 'onclick', MochiKit.Base.method(this, 'handleDirectLoginClick', directLoginsInfo[i]['_rowObject']));
+ }
+
+ if (directLoginsInfo.length > 2) {
+ var ellipsesElement;
+
+ ellipsesElement = Clipperz.DOM.Helper.append(TDElement, {tag:'div', cls:'card_directLogin_ellipses', children:[
+ {tag:'div', cls:'card_directLogin_ellipses_body', children:[
+ {tag:'span', html:'&hellip;'}
+ ]}
+ ]});
+
+/// MochiKit.Signal.connect(ellipsesElement, 'onmouseenter', MochiKit.Base.method(this, 'handleEllipsesEnter', anObject));
+/// MochiKit.Signal.connect(ellipsesElement, 'onmouseleave', MochiKit.Base.method(this, 'handleEllipsesLeave'));
+// MochiKit.Signal.connect(TDElement, 'onmouseleave', MochiKit.Base.method(this, 'handleTDLeave'));
+ this.connectEvent(TDElement, 'onmouseleave', MochiKit.Base.method(this, 'handleTDLeave'));
+ }
+// MochiKit.Signal.connect(TDElement, 'onmouseenter', MochiKit.Base.method(this, 'handleTDEnter', anObject));
+ this.connectEvent(TDElement, 'onmouseenter', MochiKit.Base.method(this, 'handleTDEnter', anObject));
+
+ },
+
+ //=========================================================================
+/*
+ 'handleEllipsesEnter': function (aRecordInfo, anEvent) {
+ this._enterLeaveCounter ++;
+ if (this._enterLeaveCounter > 2) {
+ this._enterLeaveCounter = 2;
+ }
+
+ if (this._enterLeaveCounter == 1) {
+ this.showDirectLoginListPopup(aRecordInfo, anEvent.src());
+ }
+ },
+
+ 'handleEllipsesLeave': function (anEvent) {
+ this._enterLeaveCounter --;
+
+ MochiKit.Async.callLater(0.3, MochiKit.Base.bind(function () {
+ if (this._enterLeaveCounter == 0) {
+ this.hideDirectLoginListPopup();
+ }
+ }, this))
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'handleTDEnter': function (aRecordInfo, anEvent) {
+ if (MochiKit.Selector.findChildElements(anEvent.src(), ['div.card_directLogin_ellipses']).length > 0) {
+ this._enterLeaveCounter ++;
+ if (this._enterLeaveCounter > 2) {
+ this._enterLeaveCounter = 2;
+ }
+
+ if (this._enterLeaveCounter == 1) {
+ this.showDirectLoginListPopup(aRecordInfo, anEvent.src());
+ }
+ } else {
+ if (this._selectedRowObject != null) {
+ this.hideDirectLoginListPopup();
+ }
+ }
+ },
+
+ 'handleTDLeave': function (anEvent) {
+ this._enterLeaveCounter --;
+ if (this._enterLeaveCounter < 0) {
+ this._enterLeaveCounter = 0;
+ }
+
+ MochiKit.Async.callLater(0.3, MochiKit.Base.bind(function () {
+ if (this._enterLeaveCounter == 0) {
+ this.hideDirectLoginListPopup();
+ }
+ }, this))
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleDirectLoginListPopupEnter': function (anEvent) {
+ this._enterLeaveCounter ++;
+ if (this._enterLeaveCounter > 2) {
+ this._enterLeaveCounter = 2;
+ }
+ },
+
+ 'handleDirectLoginListPopupLeave': function (anEvent) {
+ this._enterLeaveCounter --;
+ if (this._enterLeaveCounter < 0) {
+ this._enterLeaveCounter = 0;
+ }
+
+ MochiKit.Async.callLater(0.3, MochiKit.Base.bind(function () {
+ if (this._enterLeaveCounter == 0) {
+ this.hideDirectLoginListPopup();
+ }
+ }, this))
+ },
+
+ //=========================================================================
+
+ 'showDirectLoginListPopup': function (aRecordInfo, anElement) {
+ var position;
+ var directLoginsInfo;
+ var directLoginsListElement;
+ var ellipsesElement;
+
+
+ ellipsesElement = MochiKit.Selector.findChildElements(anElement, ['div.card_directLogin_ellipses'])[0];
+ position = MochiKit.Style.getElementPosition(ellipsesElement);
+// position = MochiKit.Style.getElementPosition(anElement);
+ position.x += 14;
+ position.y -= 26;
+
+ MochiKit.Style.setElementPosition(this.getId('DirectLoginListPopup'), position /*[, units='px'] */);
+
+ directLoginsListElement = this.getElement('DirectLoginListPopup_list');
+ directLoginsListElement.innerHTML = '';
+
+ directLoginsInfo = aRecordInfo[this.name()];
+ c = directLoginsInfo.length;
+ for (i=0; i<c; i++) {
+ var elementID;
+ var label;
+ var trunkedLabel;
+
+ label = directLoginsInfo[i]['label'];
+ trunkedLabel = (label.length > 20 ? label.slice(0,20) + '&hellip;' : label);
+
+ elementID = this.getId('directLoginList_' + directLoginsInfo[i]['_reference']);
+
+ Clipperz.DOM.Helper.append(directLoginsListElement, {tag:'li', children:[
+ {tag:'div', children:[
+ {tag:'img', cls:'favicon', src:directLoginsInfo[i]['favicon']},
+ (label == trunkedLabel ? {tag:'a', href:'#', id:elementID, html:trunkedLabel} : {tag:'a', href:'#', id:elementID, title:label, html:trunkedLabel})
+ ]}
+ ]});
+
+// MochiKit.Signal.connect(elementID, 'onclick', MochiKit.Base.method(this, 'handleDirectLoginClick', directLoginsInfo[i]['_rowObject']));
+ this.connectEvent(elementID, 'onclick', MochiKit.Base.method(this, 'handleDirectLoginClick', directLoginsInfo[i]['_rowObject']));
+ }
+
+// MochiKit.Style.showElement(this.getId('DirectLoginListPopup'));
+ MochiKit.Visual.appear(this.getId('DirectLoginListPopup'), {duration:0.5});
+ MochiKit.Signal.signal(this, 'selectRow', aRecordInfo);
+
+ this._selectedRowObject = aRecordInfo;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hideDirectLoginListPopup': function () {
+ if (this._selectedRowObject != null) {
+ MochiKit.Signal.signal(this, 'unselectRow', this._selectedRowObject);
+ MochiKit.Visual.fade(this.getId('DirectLoginListPopup'), {duration:0.5});
+ this._selectedRowObject = null;
+ this._enterLeaveCounter = 0;
+ }
+ },
+
+ //=========================================================================
+
+ 'handleDirectLoginClick': function (aDirectLogin, anEvent) {
+ anEvent.preventDefault();
+// aDirectLogin.runDirectLogin();
+ Clipperz.PM.UI.Common.Controllers.DirectLoginRunner.openDirectLogin(aDirectLogin);
+ },
+
+ //-------------------------------------------------------------------------
+
+ '__syntax_fix__' : 'syntax fix'
+
+});
+
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/FaviconColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/FaviconColumnManager.js
new file mode 100644
index 0000000..19d1635
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/FaviconColumnManager.js
@@ -0,0 +1,89 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+//#############################################################################
+
+Clipperz.PM.UI.Web.Components.FaviconColumnManager = function(args) {
+ args = args || {};
+ Clipperz.PM.UI.Web.Components.FaviconColumnManager.superclass.constructor.call(this, args);
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.FaviconColumnManager, Clipperz.PM.UI.Web.Components.ColumnManager, {
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.FaviconColumnManager component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderCell': function(aRowElement, anObject) {
+ var faviconImageElement;
+ var faviconUrl;
+
+ faviconImageElement = this.getId('favicon');
+ faviconUrl = anObject[this.name()];
+
+ if (faviconUrl == null) {
+ faviconUrl = Clipperz.PM.Strings.getValue('defaultFaviconUrl');
+ }
+
+ Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[
+ {tag:'img', id:faviconImageElement, src:faviconUrl}
+ ]});
+
+ MochiKit.Signal.connect(faviconImageElement, 'onload', this, 'handleLoadedFaviconImage');
+ MochiKit.Signal.connect(faviconImageElement, 'onerror', this, 'handleMissingFaviconImage');
+ MochiKit.Signal.connect(faviconImageElement, 'onabort', this, 'handleMissingFaviconImage');
+ },
+
+ //-----------------------------------------------------
+
+ 'handleLoadedFaviconImage': function(anEvent) {
+ MochiKit.Signal.disconnectAllTo(anEvent.src());
+ if (anEvent.src().complete == false) {
+ anEvent.src().src = Clipperz.PM.Strings.getValue('defaultFaviconUrl');
+ }
+ },
+
+ //-----------------------------------------------------
+
+ 'handleMissingFaviconImage': function(anEvent) {
+ MochiKit.Signal.disconnectAllTo(anEvent.src());
+ anEvent.src().src = Clipperz.PM.Strings.getValue('defaultFaviconUrl');
+ },
+
+ //-----------------------------------------------------
+ '__syntax_fix__' : 'syntax fix'
+});
+
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/GridComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/GridComponent.js
new file mode 100644
index 0000000..8b3e6c9
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/GridComponent.js
@@ -0,0 +1,262 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.GridComponent = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.GridComponent.superclass.constructor.apply(this, arguments);
+
+ this._columnsManagers = args.columnsManagers;
+
+ this._rowsObjects = [];
+ this._noRowsGridComponent = null;
+
+ this._slots = {
+ 'headerSlot': this.getId('headerSlot')
+ };
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.GridComponent, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.GridComponent component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'rows': function () {
+ throw Clipperz.Base.exception.AbstractMethod;
+// return this._rows;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'columnsManagers': function () {
+ return this._columnsManagers;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.append(this.element(), [
+ {tag:'div', cls:'header', children:[
+ {tag:'form', id:this.getId('searchForm'), cls:'search', children:[
+ {tag:'div', cls:'search', children:[
+ {tag:'input', type:'text', id:this.getId('search'), cls:'search', placeholder:"search", name:'textToSearch'/*, value:"clipperz"*/}
+ ]},
+ {tag:'div', cls:'clearSearchButton', id:this.getId('clearSearch')},
+// {tag:'input', type:'button', cls:'searchButton', name:'searchButton', value:"search"},
+ {tag:'div', cls:'headerSlot', id:this.getId('headerSlot')}
+ ]}
+ ]},
+ {tag:'div', cls:'body', children:[
+ {tag:'div', cls:'rows', id:this.getId('rows'), children:[
+ {tag:'table', cellpadding:'0', cellspacing:'0', cls:'rows', children:[
+ {tag:'thead', children:[
+ {tag:'tr', id:this.getId('thead_tr'), children:[]}
+ ]},
+ {tag:'tbody', id:this.getId('gridRows'), children:[]}
+ ]}
+ ]},
+ {tag:'div', cls:'noRowsBlock', id:this.getId('noRowsBlock'), children:[]}
+ ]},
+ {tag:'div', cls:'footer'}
+ ]);
+
+ this.renderHeader();
+ MochiKit.Signal.connect(this.getId('clearSearch'), 'onclick', this, 'clearSearchHandler');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderHeader': function () {
+ var headerElement;
+
+ headerElement = this.getElement('thead_tr');
+ headerElement.innerHTML = "";
+
+ MochiKit.Iter.forEach(this.columnsManagers(), function (aColumnManager) {
+ aColumnManager.renderHeader(headerElement);
+ });
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'update': function (someObjects) {
+ this._rowsObjects = someObjects
+ this.refresh();
+ this.focus();
+ },
+
+ 'focus': function () {
+ this.getElement('search').focus();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'startSearch': function () {
+//console.log("--> startSearch");
+ MochiKit.DOM.addElementClass(this.getElement('search'), 'running');
+ },
+
+ 'endSearch': function () {
+ MochiKit.DOM.removeElementClass(this.getElement('search'), 'running');
+//console.log("<-- startSearch");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'disconnectColumnManagersRowsSignals': function () {
+ MochiKit.Iter.forEach(this.columnsManagers(), function (aColumnManager) {
+ aColumnManager.disconnectRowsSignals();
+ });
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'refresh': function () {
+ var gridRowsElement;
+ var rowClass;
+
+ this.disconnectColumnManagersRowsSignals();
+
+ {
+ MochiKit.DOM.removeElementClass(this.getElement('search'), 'disabled');
+// MochiKit.DOM.setNodeAttribute(this.getElement('search'), 'disabled', null);
+ MochiKit.DOM.removeElementClass(this.element(), 'empty');
+ MochiKit.DOM.removeElementClass(this.element(), 'noRows');
+ }
+
+
+ gridRowsElement = this.getElement('gridRows');
+ gridRowsElement.innerHTML = "";
+
+ MochiKit.DOM.removeElementClass(this.element(), 'empty');
+
+ rowClass = 'odd';
+ MochiKit.Iter.forEach(this._rowsObjects, MochiKit.Base.bind(function (aRowObject) {
+ var cardRowElement;
+
+ cardRowElement = this.append(gridRowsElement, {tag:'tr', id:this.getId(aRowObject['_reference']), cls:rowClass});
+ MochiKit.Iter.forEach(this.columnsManagers(), function (aColumnManager) {
+ aColumnManager.renderCell(cardRowElement, aRowObject);
+ });
+
+ rowClass = (rowClass == 'odd') ? 'even' : 'odd';
+ }, this));
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'filterElement': function () {
+ return this.getElement('search');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'shouldShowElementWhileRendering': function () {
+ return false;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'selectRow': function (aRowObject) {
+ MochiKit.DOM.addElementClass(this.getId(aRowObject['_reference']), 'selected');
+ },
+
+ 'unselectRow': function (aRowObject) {
+ MochiKit.DOM.removeElementClass(this.getId(aRowObject['_reference']), 'selected');
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'passOpenDirectLogin': function(aDirectLoginReferenceId) {
+ MochiKit.Signal.signal(this, 'openDirectLogin', aDirectLoginReferenceId);
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'clearSearchHandler': function (anEvent) {
+ var searchElement;
+
+ anEvent.preventDefault();
+
+ searchElement = this.getElement('search');
+ searchElement.value = "";
+ searchElement.focus();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'drawEmpty': function () {
+ this.disconnectColumnManagersRowsSignals();
+ MochiKit.DOM.addElementClass(this.getElement('search'), 'disabled');
+// MochiKit.DOM.setNodeAttribute(this.getElement('search'), 'disabled', 'disabled');
+
+ gridRowsElement = this.getElement('gridRows');
+ gridRowsElement.innerHTML = "";
+ MochiKit.DOM.addElementClass(this.element(), 'empty');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setNoRowsGridComponent': function (aComponent) {
+ this.removeNoRowsGridComponent();
+ this._noRowsGridComponent = aComponent;
+
+ this.disconnectColumnManagersRowsSignals();
+ MochiKit.DOM.addElementClass(this.getElement('search'), 'disabled');
+// MochiKit.DOM.setNodeAttribute(this.getElement('search'), 'disabled', 'disabled');
+
+ gridRowsElement = this.getElement('gridRows');
+ gridRowsElement.innerHTML = "";
+ MochiKit.DOM.addElementClass(this.element(), 'noRows');
+
+ if (aComponent != null) {
+ aComponent.renderInNode(this.getElement('noRowsBlock'));
+ }
+ },
+
+ 'removeNoRowsGridComponent': function () {
+ if (this._noRowsGridComponent != null) {
+ this._noRowsGridComponent.remove();
+ this._noRowsGridComponent = null;
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ImageColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ImageColumnManager.js
new file mode 100644
index 0000000..07b8dcc
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ImageColumnManager.js
@@ -0,0 +1,68 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+//#############################################################################
+
+Clipperz.PM.UI.Web.Components.ImageColumnManager = function(args) {
+ args = args || {};
+ Clipperz.PM.UI.Web.Components.ImageColumnManager.superclass.constructor.call(this, args);
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.ImageColumnManager, Clipperz.PM.UI.Web.Components.ColumnManager, {
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.ImageColumnManager component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderCell': function(aRowElement, anObject) {
+ Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[
+ {tag:'img', src:anObject[this.name()]}
+ ]});
+
+// return Clipperz.Async.callbacks("ImageColumnManager.renderCell", [
+// this.selector(),
+// MochiKit.Base.bind(function (aValue) {
+// Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[
+// {tag:'img', src:aValue}
+// ]});
+// }, this)
+// ], {trace:false}, anObject);
+ },
+
+ //-----------------------------------------------------
+ '__syntax_fix__' : 'syntax fix'
+});
+
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LinkColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LinkColumnManager.js
new file mode 100644
index 0000000..e833190
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LinkColumnManager.js
@@ -0,0 +1,92 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+//#############################################################################
+
+Clipperz.PM.UI.Web.Components.LinkColumnManager = function(args) {
+ args = args || {};
+ Clipperz.PM.UI.Web.Components.LinkColumnManager.superclass.constructor.call(this, args);
+
+ this._actionMethod = args.actionMethod || null;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.LinkColumnManager, Clipperz.PM.UI.Web.Components.ColumnManager, {
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.DateColumnManager component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'actionMethod': function () {
+ return this._actionMethod;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderCell': function(aRowElement, anObject) {
+ var tdElement;
+ var linkElement;
+
+ tdElement = Clipperz.DOM.Helper.append(aRowElement, {tag:'td', cls:this.cssClass(), children:[
+ {tag:'span', children:[
+ {tag:'a', href:'#', html:anObject[this.name()]}
+ ]}
+ ]});
+
+ linkElement = MochiKit.DOM.getFirstElementByTagAndClassName('a', null, tdElement);
+// MochiKit.Signal.connect(linkElement, 'onclick', MochiKit.Base.method(this, 'handleLinkClick', anObject['_rowObject']));
+ this.connectEvent(linkElement, 'onclick', MochiKit.Base.method(this, 'handleLinkClick', anObject['_rowObject']));
+ },
+
+ //-----------------------------------------------------
+
+ 'handleLinkClick': function (anObject, anEvent) {
+ anEvent.preventDefault();
+
+ if (this.actionMethod() != null) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("LinkColumnManager.handleLinkClick", {trace:false});
+// deferredResult.addCallbackPass(MochiKit.Signal.signal, this, 'selectRow', anObject);
+ deferredResult.addCallback(this.actionMethod(), anObject, anEvent);
+// deferredResult.addBothPass(MochiKit.Signal.signal, this, 'unselectRow', anObject);
+ deferredResult.callback();
+ }
+ },
+
+ //-----------------------------------------------------
+ '__syntax_fix__' : 'syntax fix'
+});
+
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginForm.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginForm.js
new file mode 100644
index 0000000..de20853
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginForm.js
@@ -0,0 +1,203 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.LoginForm = function(args) {
+ args = args || {};
+
+ this._autocomplete = args.autocomplete || 'off';
+
+ Clipperz.PM.UI.Web.Components.LoginForm.superclass.constructor.apply(this, arguments);
+
+ this._slots = {
+ 'passphraseEntropy': this.getId('passphraseEntropy')
+ };
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.LoginForm, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.LoginForm component";
+ },
+
+ 'autocomplete': function () {
+ return this._autocomplete;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function() {
+ this.append(this.element(), {tag:'div', id:'loginBox', children:[
+ {tag:'div', cls:'header'},
+ {tag:'div', cls:'body', id:this.getId('body'), children:[
+ {tag:'div', id:this.getId('loginForm'), children:[
+ {tag:'div', children:[
+ {tag:'h4', html:'Login'},
+// {tag:'form', cls:'loginForm', autocomplete:this.autocomplete(), children:[
+ {tag:'form', id:this.getId('form'), cls:'loginForm', children:[
+ {tag:'label', html:'username', 'for':this.getId('usernameField')},
+ {tag:'input', id:this.getId('usernameField'), type:'text', cls:'username'/*, value:'joe'*/},
+ {tag:'ul', id:this.getId('passwordOptions'), children:[
+ {tag:'li', id:this.getId('passphraseOption'), children:[
+ {tag:'label', html:'passphrase / OTP', 'for':this.getId('passphraseField')},
+ {tag:'input', id:this.getId('passphraseField'), type:'password', cls:'password'/*, value:'clipperz'*/}
+ ]} // ,
+/*
+ {tag:'li', id:this.getId('otpOption'), children:[
+ {tag:'label', html:'one-time password', 'for':this.getId('otpField_1')},
+ {tag:'input', id:this.getId('otpField_1'), type:'text', cls:'otp', value:'abcd-efgh'},
+ {tag:'input', id:this.getId('otpField_2'), type:'text', cls:'otp', value:'abcd-efgh'},
+ {tag:'input', id:this.getId('otpField_3'), type:'text', cls:'otp', value:'abcd-efgh'},
+ {tag:'input', id:this.getId('otpField_4'), type:'text', cls:'otp', value:'abcd-efgh'}
+ ]}
+*/
+ ]},
+// {tag:'input', id:this.getId('otpCheckbox'), type:'checkbox', cls:'checkbox'},
+// {tag:'label', html:'use a one-time passphrase', 'for':this.getId('otpCheckbox'), cls:'checkbox'},
+
+ {tag:'div', cls:'translations', children:[
+ {tag:'h4', html:'choose your language'},
+ {tag:'ul', children:[
+ {tag:'li', cls:'selected', html:'english'},
+ {tag:'li', html:'italiano'},
+ {tag:'li', html:'dutch'},
+ {tag:'li', html:'french'},
+ {tag:'li', html:'spanish'},
+ {tag:'li', html:'chinese'},
+ {tag:'li', html:'japanese'},
+ {tag:'li', html:'portugal'},
+ {tag:'li', html:'arabic'}
+ ]}
+ ]},
+
+ {tag:'input', id:this.getId('submitButton'), type:'submit', value:'login', cls:'submit'}
+ ]}
+ ]}
+ ]}
+ ]},
+ {tag:'div', cls:'footer'}
+ ]});
+
+ if (this.autocomplete() == 'off') {
+ MochiKit.DOM.updateNodeAttributes(this.getElement('form'), {autocomplete:'off'});
+ }
+
+// Clipperz.Style.setBackgroundGradient(this.getElement('body'), {from:"#ff9955", to:"#ff6622"})
+
+// this.setEntropyDisplay(new Clipperz.PM.UI.Common.Components.PasswordEntropyDisplay(this.getElement('passphraseField')));
+
+// MochiKit.Signal.connect(this.getId('otpCheckbox'), 'onclick', this, 'togglePasswordFields');
+// this.showPassphraseField();
+
+ this.getElement('usernameField').focus();
+
+ MochiKit.Signal.connect(this.getElement('loginForm'), 'onsubmit', this, 'loginEventHandler');
+ },
+
+ //-----------------------------------------------------------------------------
+/*
+ 'togglePasswordFields': function(anEvent) {
+ var shouldUseOTP;
+
+ shouldUseOTP = this.getElement('otpCheckbox').checked;
+
+ if (shouldUseOTP == false) {
+ this.showPassphraseField();
+ } else {
+ this.showOTPFields();
+ }
+ },
+*/
+ //-----------------------------------------------------------------------------
+/*
+ 'showPassphraseField': function() {
+ this.showElement('passphraseOption');
+ this.hideElement('otpOption');
+ },
+*/
+ //-----------------------------------------------------------------------------
+
+ 'focusOnPassphraseField': function () {
+ this.getElement('passphraseField').focus();
+ this.getElement('passphraseField').select();
+ },
+
+ //-----------------------------------------------------------------------------
+/*
+ 'showOTPFields': function() {
+ this.hideElement('passphraseOption');
+ this.showElement('otpOption');
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'loginEventHandler': function(anEvent) {
+ var username;
+ var passphrase;
+// var shouldUseOTP;
+// var otp;
+ var signalArguments;
+
+ anEvent.preventDefault();
+
+ username = this.getElement('usernameField').value;
+ passphrase = this.getElement('passphraseField').value;
+// otp = this.getElement('otpField_1').value +
+// this.getElement('otpField_2').value +
+// this.getElement('otpField_3').value +
+// this.getElement('otpField_4').value;
+// shouldUseOTP = this.getElement('otpCheckbox').checked;
+
+ signalArguments = {username:username};
+
+// if (shouldUseOTP) {
+// signalArguments.otp = otp;
+// } else {
+ signalArguments.passphrase = passphrase;
+// }
+
+ MochiKit.Signal.signal(this, 'doLogin', signalArguments);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'submitButtonElement': function() {
+ return this.getElement('submitButton');
+ },
+
+ //-------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginPage.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginPage.js
new file mode 100644
index 0000000..49c030d
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginPage.js
@@ -0,0 +1,206 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.LoginPage = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.LoginPage.superclass.constructor.apply(this, arguments);
+
+ this._slots = {
+ 'loginForm': this.getId('loginBoxSlot')
+ };
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.LoginPage, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.LoginPage component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.append(this.element(), [
+ {tag:'div', id:this.getId('loginBoxSlot')},
+ {tag:'div', id:'main', children:[
+ {tag:'div', id:'featurePoints', children:[
+ {tag:'table', children:[
+ {tag:'tr', children:[
+ {tag:'td', children:[
+ {tag:'div', cls:'block', children:[
+ {tag:'h3', html:'Clipperz is:'},
+ {tag:'ul', children:[
+ {tag:'li', html:'a secure and simple password manager'},
+ {tag:'li', html:'an effective single sign-on solution'},
+ {tag:'li', html:'a digital vault for your personal data'}
+ ]}
+ ]},
+ {tag:'div', cls:'block', children:[
+ {tag:'h3', html:'Clipperz benefits:'},
+ {tag:'ul', children:[
+ {tag:'li', html:'free and completely anonymous'},
+ {tag:'li', html:'access it any time from any computer'},
+ {tag:'li', html:'no software to download and nothing to install'},
+ {tag:'li', html:'avoid keeping secrets on your PC or on paper'}
+ ]}
+ ]}
+ ]}, {tag:'td', children:[
+ {tag:'div', cls:'block', children:[
+ {tag:'h3', html:'Clipperz security:'},
+ {tag:'ul', children:[
+ {tag:'li', html:'your secretes are locally encrypted by your browser before being uploaded to Clipperz'},
+ {tag:'li', html:'the encryption key is a passphrase known only to you'},
+ {tag:'li', html:'Clipperz hosts your sensitive data in an encrypted form and could never access the data in its plain form'},
+ {tag:'li', html:'Clipperz is built upon standard encryption schemes, nothing fancies of homemade'},
+ {tag:'li', html:'you can review the source code anytime you like, but you need to know nothing about cryptography to be an happy user!'}
+ ]}
+ ]}
+ ]}
+ ]}
+ ]}
+ ]},
+ {tag:'div', cls:'activeFeatures', children:[
+ {tag:'div', id:this.getId('registerButton'), cls:'createAccountLink', children:[
+ {tag:'canvas', id:this.getId('registerButtonIcon')},
+ {tag:'a', href:'#', id:this.getId('createAccountLink'), cls:'createAccountLink', children:[
+ {tag:'span', cls:'payoff', html:"Free sign up!"},
+ {tag:'span', cls:'link', html:"Create account >>"}
+ ]}
+ ]},
+ {tag:'div', cls:'keepTogether', children:[
+ {tag:'div', id:this.getId('screenshotLink'), cls:'screenshotLink', children:[
+ {tag:'canvas', id:this.getId('lookIcon')},
+ {tag:'a', href:'#', cls:'screenshotLink', children:[
+ {tag:'span', cls:'payoff', html:"Look Clipperz!"},
+ {tag:'span', cls:'link', html:"screenshot tour >>"}
+ ]}
+ ]},
+ {tag:'div', id:this.getId('offlineLink'), cls:'offlineLink', children:[
+ {tag:'canvas', id:this.getId('downloadIcon')},
+ {tag:'a', href:'#', cls:'offlineLink', children:[
+ {tag:'span', cls:'payoff', html:"Download!"},
+ {tag:'span', cls:'link', html:"Offline version >>"}
+ ]}
+ ]}
+ ]}
+ ]}
+ ]}
+ ]);
+
+ this.setRegistrationButtonIconDefaultColors();
+ this.setLookIconDefaultColors();
+ this.setDownloadIconDefaultColors();
+
+// MochiKit.Signal.connect(this.getElement('createAccountLink'), 'onclick', this, 'handleCreateAccountLink')
+
+ MochiKit.Signal.connect(this.getElement('registerButton'), 'onmouseenter', this, 'handleMouseEnterOnRegisterButtonIcon');
+ MochiKit.Signal.connect(this.getElement('registerButton'), 'onmouseleave', this, 'handleMouseLeaveOnRegisterButtonIcon');
+
+ MochiKit.Signal.connect(this.getElement('screenshotLink'), 'onmouseenter', this, 'handleMouseEnterOnLookIcon');
+ MochiKit.Signal.connect(this.getElement('screenshotLink'), 'onmouseleave', this, 'handleMouseLeaveOnLookIcon');
+
+ MochiKit.Signal.connect(this.getElement('offlineLink'), 'onmouseenter', this, 'handleMouseEnterOnDownloadIcon');
+ MochiKit.Signal.connect(this.getElement('offlineLink'), 'onmouseleave', this, 'handleMouseLeaveOnDownloadIcon');
+
+ MochiKit.Signal.connect(this.getElement('createAccountLink'), 'onclick', this, 'handleCreateAccountLink')
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setRegistrationButtonIconDefaultColors': function () {
+ Clipperz.PM.UI.Canvas.registerButton.normal(this.getElement('registerButtonIcon'), "#eeeeee", "#eeeeee", "#ecab12", "#e14624", "#ffffff");
+ },
+
+ 'setRegistrationButtonIconHoverColors': function () {
+ Clipperz.PM.UI.Canvas.registerButton.normal(this.getElement('registerButtonIcon'), "#cccccc", "#999999", "#ffb710", "#ff4d27", "#ffffff");
+ },
+
+ 'handleMouseEnterOnRegisterButtonIcon': function (anEvent) {
+ this.setRegistrationButtonIconHoverColors();
+ },
+
+ 'handleMouseLeaveOnRegisterButtonIcon': function (anEvent) {
+ this.setRegistrationButtonIconDefaultColors();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setLookIconDefaultColors': function () {
+ Clipperz.PM.UI.Canvas.coverActions.look(this.getElement('lookIcon'), "#7e7e7e", "#ffffff", 1);
+ },
+
+ 'setLookIconHoverColors': function () {
+ Clipperz.PM.UI.Canvas.coverActions.look(this.getElement('lookIcon'), "#666666", "#ffffff", 2);
+ },
+
+ 'handleMouseEnterOnLookIcon': function (anEvent) {
+ this.setLookIconHoverColors();
+ },
+
+ 'handleMouseLeaveOnLookIcon': function (anEvent) {
+ this.setLookIconDefaultColors();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setDownloadIconDefaultColors': function () {
+ Clipperz.PM.UI.Canvas.coverActions.download(this.getElement('downloadIcon'), "#7e7e7e", "#ffffff", 1);
+ },
+
+ 'setDownloadIconHoverColors': function () {
+ Clipperz.PM.UI.Canvas.coverActions.download(this.getElement('downloadIcon'), "#666666", "#ffffff", 2);
+ },
+
+ 'handleMouseEnterOnDownloadIcon': function (anEvent) {
+ this.setDownloadIconHoverColors();
+ },
+
+ 'handleMouseLeaveOnDownloadIcon': function (anEvent) {
+ this.setDownloadIconDefaultColors();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleCreateAccountLink': function (anEvent) {
+ anEvent.preventDefault();
+
+ MochiKit.Signal.signal(this, 'createNewAccountClick', anEvent.src());
+ },
+
+ //-------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js
new file mode 100644
index 0000000..03c7b9e
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/LoginProgress.js
@@ -0,0 +1,155 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.LoginProgress = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.LoginProgress.superclass.constructor.apply(this, arguments);
+
+ this._deferred = null;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.LoginProgress, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.LoginProgress component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferred': function() {
+ return this._deferred;
+ },
+
+ 'setDeferred': function(aValue) {
+ this._deferred = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function() {
+// var loginProgressElement;
+//
+// loginProgressElement = MochiKit.DOM.getElement('loginProgress');
+//
+// if (loginProgressElement == null) {
+// loginProgressElement = this.append(this.element(), {tag:'div', id:'loginProgress', cls:'LoginProgress'}, true);
+// }
+
+//console.log(">> LoginProgress.renderSelf", this.element());
+ this.append(this.element(), {tag:'div', id:'loginProgress', cls:'LoginProgress', children: [
+// this.append(loginProgressElement, [
+ {tag:'div', cls:'header', children:[
+ {tag:'h3', id:this.getId('title'), html:"login progress"}
+ ]},
+ {tag:'div', cls:'body', children:[
+ {tag:'div', id:this.getId('progressBar')},
+ {tag:'div', id:this.getId('errorBox'), cls:'errorBox', children:[
+// {tag:'div', cls:'img ALERT', children:[{tag:'div'}]},
+ {tag:'div', cls:'img ALERT', children:[{tag:'canvas', id:this.getId('canvas')}]},
+ {tag:'p', html:"Login failed"}
+ ]}
+ ]},
+ {tag:'div', cls:'footer', children:[
+ {tag:'div', cls:'buttonArea', id:this.getId('buttonArea'), children:[
+ {tag:'div', cls:'button', id:this.getId('button'), children:[
+ {tag:'a', href:'#', id:this.getId('buttonLink'), html:"cancel"}
+ ]}
+ ]}
+ ]}
+ ]});
+// ]);
+
+ Clipperz.PM.UI.Canvas.marks['!'](this.getElement('canvas'), "#ffffff");
+
+ this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')}));
+ MochiKit.Style.hideElement(this.getElement('errorBox'));
+
+ MochiKit.Signal.connect(this.getId('buttonLink'), 'onclick', this, 'cancelEventHandler');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'displayElement': function() {
+ return MochiKit.DOM.getElement('loginProgress');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'cancelEventHandler': function(anEvent) {
+ anEvent.preventDefault();
+
+ MochiKit.Signal.signal(this, 'cancelEvent');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'disableCancel': function() {
+ MochiKit.Style.hideElement(this.getElement('buttonArea'));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'showErrorMessage': function() {
+ this.getElement('buttonLink').innerHTML = "close";
+
+ MochiKit.Style.hideElement(this.getElement('progressBar'));
+
+ this.getElement('title').innerHTML = "Error";
+ MochiKit.Style.showElement(this.getElement('errorBox'));
+ MochiKit.Style.showElement(this.getElement('buttonArea'));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredHideModalAndRemove': function(someParameters, aResult) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("LoginProgress.deferredHideModalAndRemove", {trace:false});
+ deferredResult.addMethod(this, 'deferredHideModal');
+ deferredResult.addMethod(this, 'remove');
+ deferredResult.addCallback(function () {
+ return aResult;
+ });
+ deferredResult.callback(someParameters);
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/NewUserCreationComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/NewUserCreationComponent.js
new file mode 100644
index 0000000..b40d1f3
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/NewUserCreationComponent.js
@@ -0,0 +1,430 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.NewUserCreationComponent = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.NewUserCreationComponent.superclass.constructor.apply(this, arguments);
+
+ this._tabPanelController = null;
+
+ this._initiallySelectedTab = args.selected || 'CREDENTIALS';
+ this._tabPanelControllerConfiguration = {
+ 'CREDENTIALS': {
+ tab: 'credentialsTab',
+ panel: 'credentialsTabpanel'
+ },
+ 'CHECK_CREDENTIALS': {
+ tab: 'checkCredentialsTab',
+ panel: 'checkCredentialsTabpanel'
+ },
+ 'TERMS_OF_SERVICE': {
+ tab: 'termsOfServiceTab',
+ panel: 'termsOfServiceTabpanel'
+ },
+ 'CREATE_USER': {
+ tab: 'createUserTab',
+ panel: 'createUserTabpanel'
+ } //,
+/*
+ 'LOGIN': {
+ tab: 'loginTab',
+ panel: 'loginTabpanel'
+ }
+*/
+ };
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.NewUserCreationComponent, Clipperz.PM.UI.Common.Components.TabPanelComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.NewUserCreationComponent component";
+ },
+
+ //=========================================================================
+
+ 'disableAllPanels': function () {
+ this.tabPanelController().selectTab(null);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'enableCredentialsPanel': function () {
+ this.tabPanelController().selectTab('CREDENTIALS');
+ },
+
+ 'enableCheckCredentialsPanel': function () {
+ this.tabPanelController().selectTab('CHECK_CREDENTIALS');
+ },
+
+ 'enableTermsOfServicePanel': function () {
+ this.tabPanelController().selectTab('TERMS_OF_SERVICE');
+ },
+
+ 'enableCreateUserPanel': function () {
+ this.tabPanelController().selectTab('CREATE_USER');
+ },
+
+// 'enableLoginPanel': function () {
+// this.tabPanelController().selectTab('LOGIN');
+// },
+
+ //=========================================================================
+
+ 'shouldShowElementWhileRendering': function() {
+ return false;
+ },
+
+ //=========================================================================
+
+ 'tabPanelController': function () {
+ if (this._tabPanelController == null) {
+ this._tabPanelController = new Clipperz.PM.UI.Common.Controllers.TabPanelController({
+ component:this,
+ configuration:this._tabPanelControllerConfiguration
+ });
+
+ MochiKit.Signal.connect(this._tabPanelController, 'tabSelected', this, 'handleTabSelected')
+ }
+
+ return this._tabPanelController;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function() {
+//console.log('** Clipperz.targetModalDimensionsAndPosition', Clipperz.Base.serializeJSON(Clipperz.PM.UI.Common.Components.BaseComponent.targetModalDimensionsAndPosition));
+
+ this.append(this.element(), {tag:'div', cls:'NewUserCreation mainDialog', id:this.getId('panel'), children: [
+ {tag:'form', id:this.getId('form'), cls:'newUserCreationForm', children:[
+ {tag:'div', cls:'header', children:[
+ {tag:'div', cls:'title', children:[
+ {tag:'h3', id:this.getId('title'), html:"Create new user"}
+ ]}
+ ]},
+ {tag:'div', id:this.getId('body'), cls:'body', children:[
+ {tag:'div', cls:'tabContainer', children:[
+ {tag:'ul', cls:'tabs', children:[
+ {tag:'li', id:this.getId('credentialsTab'), children:[{tag:'span', html:"credentials"}]},
+ {tag:'li', id:this.getId('checkCredentialsTab'), children:[{tag:'span', html:"credentials check"}]},
+ {tag:'li', id:this.getId('termsOfServiceTab'), children:[{tag:'span', html:"terms of service"}]},
+ {tag:'li', id:this.getId('createUserTab'), children:[{tag:'span', html:"create user"}]} //,
+// {tag:'li', id:this.getId('loginTab'), children:[{tag:'span', html:"login"}]},
+ ]},
+ {tag:'ul', cls:'tabPanels', children:[
+ {tag:'li', id:this.getId('credentialsTabpanel'), cls:'tabPanel credentials', children:[
+ {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.NewUserWizard.CREDENTIALS.description')}]},
+ {tag:'ul', cls:'credentials', children:[
+ {tag:'li', children:[{tag:'span', cls:'label', html:"username"}, {tag:'input', type:'text', id:this.getId('username')/*, value:'test'*/}]},
+ {tag:'li', children:[{tag:'span', cls:'label', html:"passphrase"}, {tag:'input', type:'password', id:this.getId('passphrase')/*, value:'test'*/}]}
+ ]}
+ ]},
+ {tag:'li', id:this.getId('checkCredentialsTabpanel'), cls:'tabPanel checkCredentials', children:[
+ {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.NewUserWizard.CHECK_CREDENTIALS.description')}]},
+ {tag:'ul', cls:'credentials', children:[
+ {tag:'li', children:[{tag:'span', cls:'label', html:"re-passphrase"}, {tag:'input', type:'password', id:this.getId('re-passphrase')/*, value:'test'*/}]}
+ ]}
+ ]},
+ {tag:'li', id:this.getId('termsOfServiceTabpanel'), cls:'tabPanel termsOfService', children:[
+ {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.NewUserWizard.TERMS_OF_SERVICE.description')}]},
+ {tag:'ul', cls:'termsOfService', children:[
+ {tag:'li', children:[{tag:'input', type:'checkbox', id:this.getId('awareOfUnrecoverablePassphrase')/*, checked:true*/}, {tag:'label', cls:'label', 'for':this.getId('awareOfUnrecoverablePassphrase'), html:"I understand that Clipperz will not be able to recover a lost passphrase."}]},
+ {tag:'li', children:[{tag:'input', type:'checkbox', id:this.getId('readTermsOfService')/*, checked:true*/}, {tag:'label', cls:'label', 'for':this.getId('readTermsOfService'), htmlString:"I have read and agreed to the <a href='http://www.clipperz.com/terms_of_service' target='_blank'>Terms of Service</a>."}]}
+ ]}
+ ]},
+ {tag:'li', id:this.getId('createUserTabpanel'), cls:'tabPanel createUser', children:[
+ {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.NewUserWizard.CREATE_USER.description')}]},
+ {tag:'ul', cls:'createUserStates', children:[
+ {tag:'li', cls:'creating', id:this.getId('creatingRegistering'), children:[{tag:'span', html:"registering user"}]},
+ {tag:'li', cls:'done', id:this.getId('creatingDone'), children:[{tag:'span', html:"done"}]},
+ {tag:'li', cls:'fail', id:this.getId('creatingFailed'), children:[{tag:'span', html:"fail"}]}
+ ]}
+ ]} //,
+// {tag:'li', id:this.getId('loginTabpanel'), cls:'tabPanel login', children:[
+// {tag:'div', cls:'wizardStepDescription', children:[{tag:'span', html:Clipperz.PM.Strings.getValue('Wizards.NewUserWizard.LOGIN.description')}]},
+// ]}
+ ]}
+ ]}
+ ]},
+ {tag:'div', id:this.getId('footer'), cls:'footer', children:[
+ {tag:'div', cls:'buttonArea', children:[
+// {tag:'div', cls:'cancel', id:this.getId('cancelButton'), html:"cancel"},
+// {tag:'div', cls:'save disabled', id:this.getId('saveButton'), html:"save"}
+ ]}
+ ]}
+ ]},
+ {tag:'div', cls:'clear'}
+ ]});
+
+ this.tabPanelController().setup();
+// MochiKit.Signal.connect(this.getId('panel'), 'onkeydown', this, 'handleKeyEvent');
+ MochiKit.Signal.connect(MochiKit.DOM.currentDocument().body, 'onkeydown', this, 'handleKeyEvent');
+ MochiKit.Signal.connect(this.getId('awareOfUnrecoverablePassphrase'), 'onchange', this, 'handleTermsOfServiceCheckboxChange');
+ MochiKit.Signal.connect(this.getId('readTermsOfService'), 'onchange', this, 'handleTermsOfServiceCheckboxChange');
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'resetContent': function () {
+ this.getElement('username').value = '';
+ this.getElement('passphrase').value = '';
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'displayElement': function() {
+ return this.getElement('panel');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleTabSelected': function (aSelectedTab) {
+/*
+ switch (aSelectedTab) {
+ case 'DETAILS':
+ break;
+ case 'DIRECT_LOGINS':
+ MochiKit.Style.hideElement(this.getElement('backToDirectLoginList'));
+ break;
+ case 'SHARING':
+ break;
+ }
+*/
+ },
+
+ //=========================================================================
+
+ 'username': function () {
+ return this.getElement('username').value;
+ },
+
+ 'usernameElement': function () {
+ return this.getElement('username');
+ },
+
+ 'passphrase': function () {
+ return this.getElement('passphrase').value;
+ },
+
+ 'rePassphrase': function () {
+ return this.getElement('re-passphrase').value;
+ },
+
+ 'awareOfUnrecoverablePassphrase': function () {
+ return this.getElement('awareOfUnrecoverablePassphrase').value;
+ },
+
+ 'readTermsOfService': function () {
+ return this.getElement('readTermsOfService').value;
+ },
+
+ //=========================================================================
+/*
+ 'incrementUpdateFaviconCounter': function () {
+ this._updateFaviconCounter ++;
+ },
+
+ 'decrementUpdateFaviconCounter': function () {
+ this._updateFaviconCounter --;
+ },
+
+ 'updateFaviconCounter': function () {
+ return this._updateFaviconCounter;
+ },
+*/
+ //-------------------------------------------------------------------------
+/*
+ 'updateFavicon': function () {
+ this.decrementUpdateFaviconCounter();
+
+ if (this.updateFaviconCounter() == 0) {
+ this.setFavicon(this.favicon());
+ }
+ },
+*/
+ //=========================================================================
+/*
+ 'bindingComponents': function () {
+ return this._bindingComponents;
+ },
+
+ 'clearAllBindingsComponents': function () {
+ MochiKit.Iter.forEach(this.bindingComponents(), MochiKit.Base.methodcaller('remove'));
+ this._bindingComponents = [];
+ this.getElement('bindings').innerHTML = '';
+ },
+
+ 'addBindingComponent': function (aBindingComponent) {
+ this.bindingComponents().push(aBindingComponent);
+ aBindingComponent.renderInNode(this.append(this.getElement('bindings'), {tag:'div'}));
+ },
+*/
+ //=========================================================================
+/*
+ 'formValueComponents': function () {
+ return this._formValueComponents;
+ },
+
+ 'clearAllFormValueComponents': function () {
+ MochiKit.Iter.forEach(this.formValueComponents(), MochiKit.Base.methodcaller('remove'));
+ this._formValueComponents = [];
+ this.getElement('formValues').innerHTML = '';
+ },
+
+ 'addFormValueComponent': function (aFormValueComponent) {
+ this.formValueComponents().push(aFormValueComponent);
+ aFormValueComponent.renderInNode(this.append(this.getElement('formValues'), {tag:'div'}));
+ },
+*/
+ //=========================================================================
+
+ 'changedValue': function (anEvent) {
+ MochiKit.Signal.signal(this, 'changedValue', anEvent);
+
+ this.incrementUpdateFaviconCounter();
+ MochiKit.Async.callLater(1, MochiKit.Base.method(this, 'updateFavicon'));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleBackClick': function (anEvent) {
+ anEvent.preventDefault();
+
+ MochiKit.Signal.signal(this, 'back');
+ },
+
+ //=========================================================================
+
+ 'bottomMargin': function () {
+ var result;
+
+// TODO: WTF!!!
+// result = MochiKit.Style.getElementPosition(this.element())['y'] +
+// MochiKit.Style.getElementDimensions(this.element())['h'];
+
+// result = MochiKit.Style.getElementPosition(this.getElement('footer'))['y'];
+//console.log("### bottomMargin");
+//console.log('displayElement', this.displayElement());
+//console.log('-- Clipperz.targetModalDimensionsAndPosition', Clipperz.Base.serializeJSON(Clipperz.PM.UI.Common.Components.BaseComponent.targetModalDimensionsAndPosition));
+//console.log('element', MochiKit.Style.getElementPosition('modalDialog') ['y'], MochiKit.Style.getElementDimensions('modalDialog')['h']);
+// result = 450;
+
+ result = Clipperz.PM.UI.Common.Components.BaseComponent.targetModalDimensionsAndPosition['position']['y'] +
+ Clipperz.PM.UI.Common.Components.BaseComponent.targetModalDimensionsAndPosition['dimensions']['h'] -
+ 60;
+
+ return result;
+ },
+
+ //=========================================================================
+
+ 'focusOnUsernameElement': function () {
+ MochiKit.Async.callLater(0.1, MochiKit.Base.method(this.getElement('username'), 'focus'));
+ },
+
+ 'focusOnRePassphraseElement': function () {
+ this.getElement('re-passphrase').focus();
+ },
+/*
+ 'focusOnBookmarkletConfigurationElement': function () {
+ this.getElement('bookmarkletConfiguration').focus();
+ },
+
+ 'focusOnFaviconElement': function () {
+ this.getElement('faviconURL').focus();
+ },
+*/
+
+ //=========================================================================
+
+ 'hideAllProgeressStates': function () {
+ MochiKit.Style.hideElement(this.getElement('creatingRegistering'));
+ MochiKit.Style.hideElement(this.getElement('creatingDone'));
+ MochiKit.Style.hideElement(this.getElement('creatingFailed'));
+ },
+
+ 'showProgressOnUserCreation': function () {
+//Clipperz.log(">>> NewUserCreationComponent.showProgressOnUserCreation");
+ this.hideAllProgeressStates();
+ MochiKit.Style.showElement(this.getElement('creatingRegistering'));
+ },
+
+ 'showUserCreationDone': function () {
+//Clipperz.log(">>> NewUserCreationComponent.showUserCreationDone");
+ this.hideAllProgeressStates();
+ MochiKit.Style.showElement(this.getElement('creatingDone'));
+//Clipperz.log("<<< NewUserCreationComponent.showUserCreationDone");
+ },
+
+ 'showUserCreationFailed': function () {
+//Clipperz.log(">>> NewUserCreationComponent.showUserCreationFailed");
+ this.hideAllProgeressStates();
+ MochiKit.Style.showElement(this.getElement('creatingFailed'));
+ },
+
+ //=========================================================================
+
+ 'handleKeyEvent': function (anEvent) {
+ MochiKit.Signal.signal(this, 'keyPressed', anEvent);
+/*
+ if (anEvent.key().string == 'KEY_ENTER') {
+ if (anEvent.target().nodeName != 'TEXTAREA') {
+ MochiKit.Signal.signal(this, 'moveForward');
+ anEvent.preventDefault();
+ }
+ } else if (anEvent.key().string == 'KEY_TAB') {
+ if ((anEvent.target().nodeName == 'INPUT') || (anEvent.target().nodeName == 'TEXTAREA')) {
+ MochiKit.Signal.signal(this, 'moveForward');
+ anEvent.preventDefault();
+ }
+ }
+*/
+ },
+
+ 'handleTermsOfServiceCheckboxChange': function (anEvent) {
+ MochiKit.Signal.signal(this, 'changedValue');
+ },
+
+ //=========================================================================
+
+ 'clear': function () {
+ this.tabPanelController().selectTab(null);
+ Clipperz.PM.UI.Web.Components.NewUserCreationComponent.superclass.clear.apply(this, arguments);
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/Page.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/Page.js
new file mode 100644
index 0000000..bed6675
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/Page.js
@@ -0,0 +1,71 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.Page = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.Page.superclass.constructor.apply(this, arguments);
+
+ this._slots = {
+ 'header': 'pageHeader',
+ 'body': 'pageBody',
+ 'footer': 'pageFooter'
+ };
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.Page, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.Page component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.append(this.element(), [
+ {tag:'div', id:'pageHeaderAndBody', cls:'pageHeaderAndBody', children:[
+ {tag:'div', id:'pageHeader', cls:'pageHeader'},
+ {tag:'div', id:'pageBody', cls:'pageBody'}
+ ]},
+ {tag:'div', id:'pageFooter', cls:'pageFooter'}
+ ]);
+
+ },
+
+ //-------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PageFooter.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PageFooter.js
new file mode 100644
index 0000000..11135d8
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PageFooter.js
@@ -0,0 +1,71 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.PageFooter = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.PageFooter.superclass.constructor.apply(this, arguments);
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.PageFooter, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.PageFooter component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.append(this.element(), [
+ {tag:'div', cls:'footerWrapper', children:[
+ {tag:'div', cls:'footerContent', children:[
+// {tag:'div', cls:'footerStarIcon'},
+ {tag:'canvas', id:this.getId('footerStarIcon'), cls:'footerStarIcon'},
+ {tag:'span', cls:'copyright', html:'Copyright &copy; 2009 Clipperz Srl'},
+ {tag:'a', href:'http://www.clipperz.com/terms_of_service', target:'_blank', html:'terms of service'},
+ {tag:'a', href:'http://www.clipperz.com/privacy_policy', target:'_blank', html:'privacy policy'},
+ {tag:'span', cls:'applicationVersion', html:'application version: [1992]'}
+ ]}
+ ]}
+ ]);
+
+ Clipperz.PM.UI.Canvas.star.normal(this.getElement('footerStarIcon'), "#7e7e7e");
+ },
+
+ //-------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PageHeader.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PageHeader.js
new file mode 100644
index 0000000..3924434
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PageHeader.js
@@ -0,0 +1,184 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.PageHeader = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.PageHeader.superclass.constructor.apply(this, arguments);
+ this._newsIsOpen = args.newsIsOpen || false;
+ this._animationDuration = args.animationDuration || 0.5;
+
+ this._offset = 82;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.PageHeader, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.PageHeader component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'iframeURL': function () {
+// return './rss_view.html';
+ return 'http://www.clipperz.com/files/clipperz.com/appTips/index.html';
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.append(this.element(), [
+ {tag:'div', id:'miscLinks', children:[
+ {tag:'ul', children:[
+ {tag:'li', children:[{tag:'a', id:'donateHeaderLink', stringID:'pageHeader.donation', href:'http://www.clipperz.com/donations', target:'_blank', html:Clipperz.PM.Strings.getValue('pageHeader.donation')}]},
+ {tag:'li', children:[{tag:'a', id:'forumHeaderLink', stringID:'pageHeader.forum', href:'http://www.clipperz.com/forum', target:'_blank', html:Clipperz.PM.Strings.getValue('pageHeader.forum')}]},
+ {tag:'li', children:[{tag:'a', id:'creditsHeaderLink', stringID:'pageHeader.credits', href:'http://www.clipperz.com/credits', target:'_blank', html:Clipperz.PM.Strings.getValue('pageHeader.credits')}]},
+ {tag:'li', children:[{tag:'a', id:'feedbackHeaderLink', stringID:'pageHeader.feedback', href:'http://www.clipperz.com/contact', target:'_blank', html:Clipperz.PM.Strings.getValue('pageHeader.feedback')}]},
+ {tag:'li', children:[{tag:'a', id:'helpHeaderLink', stringID:'pageHeader.help', href:'http://www.clipperz.com/support/user_guide', target:'_blank', html:Clipperz.PM.Strings.getValue('pageHeader.help')}]}
+ ]}
+ ]},
+ {tag:'div', id:'logoFrame', children:[
+ {tag:'a', href:'http://www.clipperz.com', target:'_blank', children:[{tag:'div', id:'logo'}]},
+ {tag:'h5', cls:'clipperzPayoff', html:'keep it to yourself!'}
+ ]},
+ {tag:'div', id:'news', cls:'hidden', children:[
+// {tag:'div', cls:'close', children:[
+// {tag:'a', href:'#', id:this.getId('closeTips'), html:'x'}
+// ]},
+ {tag:'div', id:'newsframe', children:[
+ {tag:'iframe', id:this.getId('iframe'), src:this.iframeURL()}
+ ]},
+ {tag:'div', id:this.getId('newsGrip'), cls:'grip', children:[]}
+ ]},
+ {tag:'div', id:'featureTabs', children:[
+ {tag:'table', children:[{tag:'tr', children:[
+ {tag:'td', children:[{tag:'div', id:'feature_store', children:[{tag:'canvas', cls:'featureIcon', id:this.getId('storeIcon')}, {tag:'span', html:"Store and manage your password and online credentials"}]}]},
+ {tag:'td', children:[{tag:'div', id:'feature_protect', children:[{tag:'canvas', cls:'featureIcon', id:this.getId('protectIcon')}, {tag:'span', html:"Protect all your sensitive data"}]}]},
+ {tag:'td', children:[{tag:'div', id:'feature_directLogin', children:[{tag:'canvas', cls:'featureIcon', id:this.getId('directLoginIcon')}, {tag:'span', html:"Login to your web services without entering any username or password"}]}]},
+ {tag:'td', children:[{tag:'div', id:'feature_share', children:[{tag:'canvas', cls:'featureIcon', id:this.getId('shareIcon')}, {tag:'span', html:"Share secret with family members and associates"}]}]}
+ ]}]}
+ ]}
+ ]);
+
+ Clipperz.PM.UI.Canvas.features.store(this.getElement('storeIcon'), "#ffffff");
+ Clipperz.PM.UI.Canvas.features.protect(this.getElement('protectIcon'), "#ffffff");
+ Clipperz.PM.UI.Canvas.features.directLogin(this.getElement('directLoginIcon'), "#ffffff");
+ Clipperz.PM.UI.Canvas.features.share(this.getElement('shareIcon'), "#ffffff", "#ffffff", "#ff0000");
+
+ MochiKit.Signal.connect(this.getElement('newsGrip'), 'onclick', this, 'toggleTips');
+ MochiKit.Signal.connect(this.getElement('iframe'), 'onload', this, 'handleIframeDidLoad');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'switchToLoggedMode': function() {
+// MochiKit.Style.addElementClass(this.element(), 'logged');
+ MochiKit.Style.hideElement('featureTabs');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'animationDuration': function () {
+ return this._animationDuration;
+ },
+
+ 'offset': function () {
+ return this._offset;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isNewsOpen': function () {
+ return this._newsIsOpen;
+ },
+
+ 'toggleNewsIsOpen': function () {
+ this._newsIsOpen = !this._newsIsOpen;
+ },
+
+ 'toggleTips': function(anEvent) {
+ anEvent.preventDefault();
+
+ if (this.isNewsOpen() == true) {
+ MochiKit.Visual.Move(Clipperz.DOM.get('news'), {
+ x: 0,
+ y: -this.offset(),
+ mode: 'relative',
+ duration: this.animationDuration(),
+ beforeStart: function () {
+ MochiKit.DOM.setElementClass(Clipperz.DOM.get('news'), 'hiding');
+ },
+ afterFinish: function () {
+ Clipperz.DOM.get('newsframe').innerHTML = "";
+ MochiKit.DOM.setElementClass(Clipperz.DOM.get('news'), 'hidden');
+ }
+ })
+ this.toggleNewsIsOpen();
+ } else {
+ MochiKit.DOM.addElementClass('newsframe', 'loading');
+ MochiKit.Visual.Move(Clipperz.DOM.get('news'), {
+ x: 0,
+ y: this.offset(),
+ mode: 'relative',
+ duration: this.animationDuration(),
+ beforeStart: MochiKit.Base.bind(function () {
+ this.append(Clipperz.DOM.get('newsframe'), {tag:'iframe', id:this.getId('iframe'), src:this.iframeURL()});
+
+ MochiKit.Signal.connect(this.getElement('iframe'), 'onload', this, 'handleIframeDidLoad');
+ MochiKit.DOM.setElementClass(Clipperz.DOM.get('news'), 'opening');
+ }, this),
+ afterFinish: function () {
+ MochiKit.DOM.setElementClass(Clipperz.DOM.get('news'), 'open');
+ }
+ })
+ this.toggleNewsIsOpen();
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleIframeDidLoad': function (anEvent) {
+ if (this.isNewsOpen() == false) {
+ this.toggleTips(anEvent);
+ }
+
+ MochiKit.DOM.removeElementClass('newsframe', 'loading');
+ MochiKit.Signal.disconnectAllTo(this.getElement('iframe'));
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PasswordTooltip.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PasswordTooltip.js
new file mode 100644
index 0000000..79c8d4f
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/PasswordTooltip.js
@@ -0,0 +1,164 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Common.Components');
+
+Clipperz.PM.UI.Web.Components.PasswordTooltip = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.PasswordTooltip.superclass.constructor.apply(this, arguments);
+
+ this._referenceElement = args.referenceElement || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._text = args.text || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ this._boxDimensions = null;
+ this._isVisible = false;
+
+ this.renderSelf();
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.PasswordTooltip, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.PasswordTooltip component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'referenceElement': function () {
+ return this._referenceElement;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'text': function () {
+ return this._text;
+ },
+
+ 'setText': function (aValue) {
+ this._text = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isVisible': function () {
+ return this._isVisible;
+ },
+
+ 'setIsVisible': function (aValue) {
+ this._isVisible = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function() {
+ this.append(MochiKit.DOM.getElement('Clipperz_PM_UI_Common_Components_Tooltip_wrapperNode'), {tag:'div', id:this.getId('tooltip'), cls:'passwordTooltip', children:[
+ {tag:'div', id:this.getId('body'), cls:'passwordTooltip_body', children:[
+ {tag:'div', cls:'passwordTooltip_text', children:[
+ {tag:'span', html:this.text()}
+ ]},
+ {tag:'div', id:this.getId('footer'), cls:'passwordTooltip_footer'}
+ ]},
+ {tag:'div', id:this.getId('arrow'), cls:'passwordTooltip_arrow'}
+ ]});
+
+ this._boxDimensions = MochiKit.Style.getElementDimensions(this.getId('body'));
+// this._boxDimensions.h += MochiKit.Style.getElementDimensions(this.getId('footer')).h;
+
+ MochiKit.Style.hideElement(this.displayElement());
+ MochiKit.Signal.connect(this.element(), 'onmouseenter', this, 'show');
+ MochiKit.Signal.connect(this.element(), 'onmouseleave', this, 'hide');
+ },
+
+ //-----------------------------------------------------
+
+ 'displayElement': function() {
+ return this.getElement('tooltip');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'boxDimensions': function () {
+ return this._boxDimensions;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'show': function () {
+ var elementSizeAndPosition;
+ var arrowPosition;
+ var bodyPosition;
+
+ if (this.isVisible() == false) {
+ arrowPosition = {};
+ bodyPosition = {};
+
+ this.setIsVisible(true);
+ elementSizeAndPosition = Clipperz.Style.getSizeAndPosition(this.element());
+
+ MochiKit.Style.setElementDimensions(this.getId('arrow'), {w:36, h:13}, 'px');
+ bodyPosition.x = elementSizeAndPosition.position.x + (elementSizeAndPosition.dimensions.w/2 - this.boxDimensions().w/2);
+ bodyPosition.y = elementSizeAndPosition.position.y - this.boxDimensions().h - 13;
+
+ arrowPosition.x = elementSizeAndPosition.position.x + (elementSizeAndPosition.dimensions.w/2 - 36/2);
+ arrowPosition.y = elementSizeAndPosition.position.y - 13;
+
+ MochiKit.Style.setElementPosition(this.getId('body'), bodyPosition);
+ MochiKit.Style.setElementPosition(this.getId('arrow'), arrowPosition);
+ MochiKit.Visual.appear(this.displayElement(), {duration:0.4});
+ }
+ },
+
+ 'hide': function () {
+ if (this.isVisible() == true) {
+ MochiKit.Visual.fade(this.displayElement(), {duration:0.4});
+ this.setIsVisible(false);
+ }
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'shouldRemoveElementWhenClearningUp': function () {
+ return false;
+ },
+*/
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+Clipperz.PM.UI.Web.Components.PasswordTooltip.initTooltips = function () {
+ Clipperz.DOM.Helper.insertBefore(MochiKit.DOM.currentDocument().body.childNodes[0], {tag:'div', id:'Clipperz_PM_UI_Web_Components_PasswordTooltip_wrapperNode'});
+}
+
+MochiKit.DOM.addLoadEvent(Clipperz.PM.UI.Web.Components.PasswordTooltip.initTooltips);
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/RulerComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/RulerComponent.js
new file mode 100644
index 0000000..ab8a38c
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/RulerComponent.js
@@ -0,0 +1,324 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.RulerComponent = function(args) {
+ args = args || {};
+ Clipperz.PM.UI.Web.Components.RulerComponent.superclass.constructor.apply(this, arguments);
+
+ this._translationContext = args.translationContext || Clipperz.Base.exception.raise('MandatoryParameter');
+// this._steps = args.steps || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._steps = args.steps;
+
+ this._currentStep = -1;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.RulerComponent, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.RulerComponent component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'resetStatus': function (args) {
+ args = args || {};
+
+ if (this.currentStep() != 0) {
+ var shouldAnimateTransition;
+
+ shouldAnimateTransition = args.animateTransition || false;
+
+ if (shouldAnimateTransition) {
+ this.moveToFirstStep(MochiKit.Base.method(this, 'cursorMoved'));
+ } else {
+ this._currentStep = 0;
+ this.cursorMoved();
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'translationContext': function () {
+ return this._translationContext;
+ },
+
+ 'steps': function () {
+ return this._steps;
+ },
+
+ 'setSteps': function (aValue) {
+ this._steps = aValue;
+ this.renderStepsComponents();
+ this.resetStatus();
+ },
+
+ 'translatedStepDescription': function (aStep) {
+ return Clipperz.PM.Strings.getValue(this.translationContext() + '.' + aStep + '.' + 'name');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.setElement(this.append(MochiKit.DOM.currentDocument().body, [
+ {tag:'div', id:this.getId('rulerWrapper'), cls:'rulerWrapper fixed', children:[
+ {tag:'div', cls:'ruler', children:[
+ {tag:'a', href:'#', id:this.getId('exit'), cls:'exit', html:'&nbsp;'},
+ {tag:'a', href:'#', id:this.getId('smallPreviousButton'), cls:'smallButton previous', html:'&nbsp;'},
+ {tag:'a', href:'#', id:this.getId('smallNextButton'), cls:'smallButton next', html:'&nbsp;'},
+ {tag:'div', cls:'marker', id:this.getId('marker'), children:[
+ {tag:'div', cls:'previous', id:this.getId('previousButton')},
+ {tag:'div', cls:'markerBody'},
+ {tag:'div', cls:'next', id:this.getId('nextButton')}
+ ]},
+ {tag:'div', cls:'steps', id:this.getId('stepsFrame')},
+// {tag:'div', cls:'steps' + ' ' + 'steps_' + this.steps().length, children:[
+// {tag:'ul', id:this.getId('steps'), children:MochiKit.Base.map(MochiKit.Base.bind(function (aStep) { return {tag:'li', children:[{tag:'span', html:this.translatedStepDescription(aStep)}]}}, this), this.steps())}
+// ]},
+ {tag:'div', cls:'dots', id:this.getId('dotsFrame')}
+// {tag:'div', cls:'dots' + ' ' + 'steps_' + this.steps().length, children:[
+// {tag:'ul', id:this.getId('dots'), children:MochiKit.Base.map(function (aStep) { return {tag:'li', children:[{tag:'span', html:'*'}]}}, this.steps())}
+// ]}
+ ]}
+ ]}
+ ]));
+//console.log("ELEMENT", this.element());
+
+ MochiKit.Signal.connect(this.getElement('exit'), 'onclick', this, 'handleExit');
+
+ MochiKit.Signal.connect(this.getElement('previousButton'), 'onclick', this, 'handlePrevious');
+ MochiKit.Signal.connect(this.getElement('smallPreviousButton'), 'onclick', this, 'handlePrevious');
+
+ MochiKit.Signal.connect(this.getElement('nextButton'), 'onclick', this, 'handleNext');
+ MochiKit.Signal.connect(this.getElement('smallNextButton'), 'onclick', this, 'handleNext');
+
+ this.enablePrevious(false);
+ this.enableNext(false);
+
+// this.cursorMoved();
+ },
+
+ //.........................................................................
+
+ 'renderStepsComponents': function () {
+ var stepsFrame;
+ var dotsFrame;
+
+ stepsFrames = this.getElement('stepsFrame');
+ MochiKit.DOM.setElementClass(stepsFrames, 'steps');
+ MochiKit.DOM.addElementClass(stepsFrames, 'steps_' + this.steps().length);
+
+ stepsFrames.innerHTML = "";
+ this.append(stepsFrames, {tag:'ul', id:this.getId('steps'), children:MochiKit.Base.map(
+ MochiKit.Base.bind(function (aStep) { return {tag:'li', children:[{tag:'span', html:this.translatedStepDescription(aStep)}]}}, this),
+ this.steps())}
+ );
+
+ dotsFrames = this.getElement('dotsFrame');
+ MochiKit.DOM.setElementClass(dotsFrames, 'dots');
+ MochiKit.DOM.addElementClass(dotsFrames, 'steps_' + this.steps().length);
+
+ dotsFrames.innerHTML = "";
+ this.append(dotsFrames, {tag:'ul', id:this.getId('dots'), children:MochiKit.Base.map(
+ function (aStep) { return {tag:'li', children:[{tag:'span', html:'*'}]}; },
+ this.steps())}
+ );
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleExit': function (anEvent) {
+ anEvent.preventDefault();
+
+ MochiKit.Signal.signal(this, 'exit');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handlePrevious': function (anEvent) {
+ anEvent.preventDefault();
+
+// if (!MochiKit.DOM.hasElementClass(this.getElement('previousButton'), 'disabled')) {
+// this.moveBackward();
+// }
+
+ MochiKit.Signal.signal(this, 'moveBackward');
+ },
+
+ 'handleNext': function (anEvent) {
+ anEvent.preventDefault();
+
+// if (!MochiKit.DOM.hasElementClass(this.getElement('nextButton'), 'disabled')) {
+// this.moveForward();
+// }
+
+ MochiKit.Signal.signal(this, 'moveForward');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'currentStep': function () {
+ return this._currentStep;
+ },
+
+ 'markerInitialOffset': function () {
+ return -246;
+ },
+
+ 'markerStepOffset': function () {
+ return 410 / (this.steps().length - 1);
+// return 100;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'moveToFirstStep': function (aCallback) {
+ var stepsToMove;
+
+ stepsToMove = this._currentStep;
+ this._currentStep = 0;
+
+ this.enablePrevious(false);
+ this.enableNext(false);
+// MochiKit.Signal.signal(this, 'moveBackward');
+ MochiKit.Base.map(
+ function (anElement) { MochiKit.DOM.removeElementClass(anElement, 'selected'); },
+ MochiKit.Selector.findChildElements(this.element(), ['li.selected'])
+ );
+ new MochiKit.Visual.Move(this.getElement('marker'), {
+ x:-(this.markerStepOffset() * stepsToMove),
+ mode:'relative',
+ duration:(0.5 * (stepsToMove/2)),
+// afterFinish:MochiKit.Base.method(this, 'cursorMoved')
+ afterFinish:MochiKit.Base.compose(MochiKit.Base.method(this, 'cursorMoved'), aCallback)
+ });
+ },
+
+ 'moveBackward': function (aCallback) {
+ this._currentStep --;
+
+ this.enablePrevious(false);
+ this.enableNext(false);
+// MochiKit.Signal.signal(this, 'moveBackward');
+ MochiKit.Base.map(
+ function (anElement) { MochiKit.DOM.removeElementClass(anElement, 'selected'); },
+ MochiKit.Selector.findChildElements(this.element(), ['li.selected'])
+ );
+ new MochiKit.Visual.Move(this.getElement('marker'), {
+ x:-this.markerStepOffset(),
+ mode:'relative',
+ duration:0.5,
+// afterFinish:MochiKit.Base.method(this, 'cursorMoved')
+ afterFinish:MochiKit.Base.compose(MochiKit.Base.method(this, 'cursorMoved'), aCallback)
+ });
+ },
+
+ 'moveForward': function (aCallback) {
+ this._currentStep ++;
+
+ if (this._currentStep < this.steps().length) {
+ this.enablePrevious(false);
+ this.enableNext(false);
+// MochiKit.Signal.signal(this, 'moveForward');
+ MochiKit.Base.map(
+ function (anElement) { MochiKit.DOM.removeElementClass(anElement, 'selected'); },
+ MochiKit.Selector.findChildElements(this.element(), ['li.selected'])
+ );
+ new MochiKit.Visual.Move(this.getElement('marker'), {
+ x:this.markerStepOffset(),
+ mode:'relative',
+ duration:0.5,
+// afterFinish:MochiKit.Base.method(this, 'cursorMoved')
+ afterFinish:MochiKit.Base.compose(MochiKit.Base.method(this, 'cursorMoved'), aCallback)
+ });
+ } else {
+ MochiKit.Signal.signal(this, 'done');
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'enablePrevious': function (aValue) {
+ if (aValue == true) {
+ MochiKit.DOM.removeElementClass(this.getElement('previousButton'), 'disabled');
+ MochiKit.DOM.removeElementClass(this.getElement('smallPreviousButton'), 'disabled');
+ } else {
+ MochiKit.DOM.addElementClass(this.getElement('previousButton'), 'disabled');
+ MochiKit.DOM.addElementClass(this.getElement('smallPreviousButton'), 'disabled');
+ }
+ },
+
+// 'disablePrevious': function () {
+// MochiKit.DOM.addElementClass(this.getElement('previousButton'), 'disabled');
+// },
+
+ //.........................................................................
+
+ 'enableNext': function (aValue) {
+ if (aValue == true) {
+ MochiKit.DOM.removeElementClass(this.getElement('nextButton'), 'disabled');
+ MochiKit.DOM.removeElementClass(this.getElement('smallNextButton'), 'disabled');
+ } else {
+ MochiKit.DOM.addElementClass(this.getElement('nextButton'), 'disabled');
+ MochiKit.DOM.addElementClass(this.getElement('smallNextButton'), 'disabled');
+ }
+ },
+
+// 'disableNext': function () {
+// MochiKit.DOM.addElementClass(this.getElement('nextButton'), 'disabled');
+// },
+
+ //-------------------------------------------------------------------------
+
+ 'cursorMoved': function () {
+ MochiKit.Style.setElementPosition(this.getElement('marker'), {x:this.markerStepOffset() * this.currentStep() + this.markerInitialOffset()})
+ MochiKit.Signal.signal(this, 'cursorMoved');
+
+ MochiKit.DOM.addElementClass(this.getElement('steps').childNodes[this.currentStep()], 'selected');
+ MochiKit.DOM.addElementClass(this.getElement('dots').childNodes[this.currentStep()], 'selected');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setDisplayMode': function (aValue) {
+ MochiKit.DOM.removeElementClass(this.getElement('rulerWrapper'), 'fixed');
+ MochiKit.DOM.removeElementClass(this.getElement('rulerWrapper'), 'scrollable');
+ MochiKit.DOM.addElementClass(this.getElement('rulerWrapper'), aValue);
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/TabSidePanel.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/TabSidePanel.js
new file mode 100644
index 0000000..39a1ccb
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/TabSidePanel.js
@@ -0,0 +1,193 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.TabSidePanel = function(args) {
+ args = args || {};
+ Clipperz.PM.UI.Web.Components.TabSidePanel.superclass.constructor.call(this, args);
+
+ this._element = args.element || null;
+
+ this._slots = {
+ };
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.TabSidePanel, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.TabSidePanel component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deselectAllTabs': function() {
+ var tabListItems;
+
+ tabListItems = [
+ 'cardsLI',
+// 'directLoginLI',
+ 'accountLI',
+ 'dataLI',
+ 'toolsLI'
+ ];
+
+//Clipperz.log("=== TabSidePanel.tabSelected anEvent.src().id", anEvent.src().id);
+ for (var i in tabListItems) {
+//Clipperz.log("=== TabSidePanel.tabSelected aTabListItem", tabListItems[i]);
+ MochiKit.DOM.removeElementClass(this.getId(tabListItems[i]), 'selected');
+ }
+ },
+
+ 'selectTab': function(aTabName) {
+ this.deselectAllTabs();
+ MochiKit.DOM.addElementClass(this.getId(this.listItemIdForTabNamed(aTabName)), 'selected');
+ MochiKit.Signal.signal(this, 'tabSelected', aTabName);
+ },
+
+ 'tabNameForAnchorId': function(anId) {
+ var result;
+
+ switch(anId) {
+ case 'cards_tabSidePanel':
+ result = 'cards';
+ break;
+// case 'directLogins_tabSidePanel':
+// result = 'directLogins';
+// break;
+ case 'account_tabSidePanel':
+ result = 'account';
+ break;
+ case 'data_tabSidePanel':
+ result = 'data';
+ break;
+ case 'tools_tabSidePanel':
+ result = 'tools';
+ break;
+ }
+
+ return result;
+ },
+
+ 'listItemIdForTabNamed': function(aTabName) {
+ var result;
+
+ switch (aTabName) {
+ case 'cards':
+ result = 'cardsLI';
+ break;
+// case 'directLogins':
+// result = 'directLoginLI';
+// break;
+ case 'account':
+ result = 'accountLI';
+ break;
+ case 'data':
+ result = 'dataLI';
+ break;
+ case 'tools':
+ result = 'toolsLI';
+ break;
+ }
+
+ return result;
+ },
+
+ 'tabSelected': function (anEvent) {
+ this.selectTab(this.tabNameForAnchorId(anEvent.src().id));
+// anEvent.stop();
+ anEvent.preventDefault();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addCard': function (anEvent) {
+ anEvent.stop();
+ MochiKit.Signal.signal(this, 'addCard', anEvent.src());
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.append(this.element(), [
+ {tag:'div', cls:'header'},
+ {tag:'div', cls:'body', children:[
+ {tag:'ul', cls:'mainTabs', children:[
+ {tag:'li', id:this.getId('cardsLI'), cls:'cards', children:[
+ {tag:'a', id:'cards_tabSidePanel', href:'#', html:"cards"},
+ {tag:'div', cls:'selectionHighlighter', children:[
+ {tag:'img', src:'./images/old/main/tabs/selectionHighligher.png'},
+ {tag:'a', id:this.getId('addCardA'), cls:'add', href:'#', children:[
+ {tag:'span', html:"add"},
+ {tag:'h3', html:"+"}
+ ]}
+ ]}
+ ]}
+ ]},
+ {tag:'ul', cls:'otherTabs', children:[
+ {tag:'li', id:this.getId('accountLI'), children:[
+ {tag:'a', id:'account_tabSidePanel', href:'#', html:"account"},
+ {tag:'div', cls:'selectionHighlighter', children:[
+ {tag:'img', src:'./images/old/main/tabs/selectionHighligherGray.png'}
+ ]}
+ ]},
+ {tag:'li', id:this.getId('dataLI'), children:[
+ {tag:'a', id:'data_tabSidePanel', href:'#', html:"data"},
+ {tag:'div', cls:'selectionHighlighter', children:[
+ {tag:'img', src:'./images/old/main/tabs/selectionHighligherGray.png'}
+ ]}
+ ]},
+ {tag:'li', id:this.getId('toolsLI'), children:[
+ {tag:'a', id:'tools_tabSidePanel', href:'#', html:"tools"},
+ {tag:'div', cls:'selectionHighlighter', children:[
+ {tag:'img', src:'./images/old/main/tabs/selectionHighligherGray.png'}
+ ]}
+ ]}
+ ]}
+ ]},
+ {tag:'div', cls:'footer'}
+ ]);
+
+ MochiKit.Signal.connect('cards_tabSidePanel', 'onclick', this, 'tabSelected');
+// MochiKit.Signal.connect('directLogins_tabSidePanel', 'onclick', this, 'tabSelected');
+ MochiKit.Signal.connect('account_tabSidePanel', 'onclick', this, 'tabSelected');
+ MochiKit.Signal.connect('data_tabSidePanel', 'onclick', this, 'tabSelected');
+ MochiKit.Signal.connect('tools_tabSidePanel', 'onclick', this, 'tabSelected');
+ MochiKit.Signal.connect(this.getId('addCardA'), 'onclick', this, 'addCard');
+ },
+
+ //-------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/TextColumnManager.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/TextColumnManager.js
new file mode 100644
index 0000000..97e81b4
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/TextColumnManager.js
@@ -0,0 +1,53 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+//#############################################################################
+
+Clipperz.PM.UI.Web.Components.TextColumnManager = function(args) {
+ args = args || {};
+ Clipperz.PM.UI.Web.Components.TextColumnManager.superclass.constructor.call(this, args);
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.TextColumnManager, Clipperz.PM.UI.Web.Components.ColumnManager, {
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.TextColumnManager component";
+ },
+
+ //-----------------------------------------------------
+
+ '__syntax_fix__' : 'syntax fix'
+
+});
+
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js
new file mode 100644
index 0000000..179c495
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/ToolsPanel.js
@@ -0,0 +1,113 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.ToolsPanel = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.ToolsPanel.superclass.constructor.apply(this, arguments);
+
+ this._initiallySelectedTab = args.selected || 'PASSWORD_GENERATOR';
+ this._tabPanelControllerConfiguration = {
+ 'PASSWORD_GENERATOR': {
+ tab: 'passwordGeneratorTab',
+ panel: 'passwordGeneratorPanel'
+ },
+ 'BOOKMARKLET': {
+ tab: 'bookmarkletTab',
+ panel: 'bookmarkletPanel'
+ },
+ 'COMPACT_EDITION': {
+ tab: 'compactEditionTab',
+ panel: 'compactEditionPanel'
+ },
+ 'HTTP_AUTH': {
+ tab: 'httpAuthTab',
+ panel: 'httpAuthPanel'
+ }
+ };
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.ToolsPanel, Clipperz.PM.UI.Common.Components.TabPanelComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.ToolsPanel component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.append(this.element(), [
+ {tag:'div', cls:'header', children:[
+ {tag:'div', cls:'subPanelTabs', children:[
+ {tag:'ul', children:[
+ {tag:'li', id:this.getId('passwordGeneratorTab'), children:[{tag:'a', href:'#', html:'Password generator'}], cls:'first'},
+ {tag:'li', id:this.getId('bookmarkletTab'), children:[{tag:'a', href:'#', html:'Bookmarklet'}]},
+ {tag:'li', id:this.getId('compactEditionTab'), children:[{tag:'a', href:'#', html:'Compact edition'}]},
+ {tag:'li', id:this.getId('httpAuthTab'), children:[{tag:'a', href:'#', html:'HTTP Auth'}]}
+ ]}
+ ]}
+ ]},
+ {tag:'div', cls:'body', children:[
+ {tag:'div', cls:'accountPanel', children:[
+ {tag:'div', cls:'subPanelContent', children:[
+ {tag:'ul', children:[
+ {tag:'li', id:this.getId('passwordGeneratorPanel'), children:[
+ {tag:'h3', html:"Password generator"}
+ ]},
+ {tag:'li', id:this.getId('bookmarkletPanel'), children:[
+ {tag:'h3', html:"Bookmarklet"}
+ ]},
+ {tag:'li', id:this.getId('compactEditionPanel'), children:[
+ {tag:'h3', html:"Compact edition"}
+ ]},
+ {tag:'li', id:this.getId('httpAuthPanel'), children:[
+ {tag:'h3', html:"HTTP Auth"}
+ ]}
+ ]}
+ ]}
+ ]}
+ ]},
+ {tag:'div', cls:'footer'}
+ ]);
+
+ this.tabPanelController().setup({selected:this.initiallySelectedTab()});
+ },
+
+ //-------------------------------------------------------------------------
+
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/UnlockPasswordComponent.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/UnlockPasswordComponent.js
new file mode 100644
index 0000000..5b9d522
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/UnlockPasswordComponent.js
@@ -0,0 +1,184 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.UnlockPasswordComponent = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.UnlockPasswordComponent.superclass.constructor.apply(this, arguments);
+
+ this._openFromElement = args.openFromElement || null;
+ this._onOkCloseToElement = args.onOkCloseToElement || null;
+ this._onCancelCloseToElement = args.onCancelCloseToElement || null;
+
+ this._progressBarComponent = null;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.UnlockPasswordComponent, Clipperz.PM.UI.Common.Components.SimpleMessagePanel, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.UnlockPasswordComponent component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getPassphrase': function () {
+/* var deferredResult;
+
+ if (this.passphrase() == null) {
+ this.deferredShowModal({'openFromElement': this.openFromElement()});
+ deferredResult = this.deferred();
+ } else {
+ deferredResult = MochiKit.Async.succeed(this.passphrase());
+ }
+
+ return deferredResult;
+*/
+
+ this.deferredShowModal({'openFromElement': this.openFromElement()});
+
+ return this.deferred();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredShowModal': function (someParameters) {
+ return Clipperz.Async.callbacks("UnlockPasswordComponent.deferredShowModal", [
+ MochiKit.Base.bind(Clipperz.PM.UI.Web.Components.UnlockPasswordComponent.superclass.deferredShowModal, this, someParameters),
+ MochiKit.Base.method(this, 'getElement', 'passphrase'),
+ MochiKit.Base.methodcaller('focus')
+ ], {trace:false})
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'openFromElement': function () {
+ return this._openFromElement;
+ },
+
+ 'onOkCloseToElement': function () {
+ return this._onOkCloseToElement;
+ },
+
+ 'onCancelCloseToElement': function () {
+ return this._onCancelCloseToElement;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function() {
+ Clipperz.PM.UI.Web.Components.UnlockPasswordComponent.superclass.renderSelf.apply(this, arguments);
+
+ this.append(this.getElement('container'), {tag:'div', cls:'passphrase', children: [
+// {tag:'form', id:this.getId('passphraseForm'), children:[
+ {tag:'input', id:this.getId('passphrase'), type:'password', name:'passphrase', value:''}
+// ]}
+ ]});
+
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'userSuccessfullyLoggedIn', this, 'userSuccessfullyLoggedInHandler');
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'userLoginFailed', this, 'userLoginFailedHandler');
+
+
+// MochiKit.Async.callLater(0.1, MochiKit.Base.method(this.getElement('passphrase'), 'focus'));
+// this.getElement('passphrase').select();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'showProgressBar': function () {
+ var progressBarElement;
+
+ this.getElement('container').innerHTML = '';
+
+ progressBarElement = this.append(this.getElement('container'), {tag:'div', cls:'progressBarWrapper'});
+ this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':progressBarElement}));
+
+ this.setButtons([{text:"Cancel", result:'CANCEL'}]);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'showFailure': function () {
+ this.setType('ALERT');
+ this.setTitle("Login failed");
+ this.setText("Wrong passphrase; the unlock has failed.");
+ this.getElement('container').innerHTML = '';
+ this.setButtons([{text:"Close", result:'CANCEL', isDefault:true}]);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'closeOk': function () {
+ var passphrase;
+
+ passphrase = this.getElement('passphrase').value;
+ this.showProgressBar();
+// this.deferred().callback(passphrase);
+ MochiKit.Async.callLater(0.5, MochiKit.Base.method(this.deferred(), 'callback', passphrase));
+ this._deferred = null;
+ },
+
+ 'closeCancel': function () {
+ this.deferredHideModal({closeToElement:this.onCancelCloseToElement()});
+ this.deferred().cancel();
+ this._deferred = null;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'userSuccessfullyLoggedInHandler': function (anEvent) {
+ this.deferredHideModal({closeToElement:this.onOkCloseToElement()});
+ },
+
+ 'userLoginFailedHandler': function (anEvent) {
+//console.log("############### FAILED LOGIN ################");
+ this.showFailure();
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'deferredShow': function (someArgs, aResult) {
+ this.deferredShowModal(someArgs);
+
+// this.deferred().addMethod(this, 'deferredHideModal', {closeToElement:someArgs.onOkCloseToElement });
+// this.deferred().addErrback (MochiKit.Base.method(this, 'deferredHideModal', {closeToElement:someArgs.onCancelCloseToElement }));
+// this.deferred().addCallback(MochiKit.Async.succeed, aResult);
+
+ return this.deferred();
+ },
+*/
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Components/UserInfoBox.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/UserInfoBox.js
new file mode 100644
index 0000000..f26118e
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Components/UserInfoBox.js
@@ -0,0 +1,346 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Components');
+
+Clipperz.PM.UI.Web.Components.UserInfoBox = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Components.UserInfoBox.superclass.constructor.apply(this, arguments);
+
+ this._slots = { };
+ this._isLocked = false;
+ this._lockTooltip = null;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Components.UserInfoBox, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.Web.Components.UserInfoBox component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleLogout': function(anEvent) {
+//Clipperz.log(">>> UserInfoBox.handleLogout");
+ anEvent.preventDefault();
+ MochiKit.Signal.signal(this, 'logout');
+//Clipperz.log("<<< UserInfoBox.handleLogout");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'lockTooltip': function () {
+ return this._lockTooltip;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isLocked': function () {
+ return this._isLocked;
+ },
+
+ 'setIsLocked': function (aValue) {
+ this._isLocked = aValue;
+ },
+
+ 'toggleLock': function(anEvent) {
+ var deferredResult;
+ var shouldLock;
+
+//console.log(">>> UserInfoBox.toggleLock [locked: " + this.isLocked() + "]");
+ anEvent.preventDefault();
+ this.lockTooltip().hide();
+
+ shouldLock = (this.isLocked() == false);
+
+ if (shouldLock) {
+ var maskElement;
+
+ this.setIsLocked(true);
+ maskElement = this.getId('modalDialogMask');
+ deferredResult = Clipperz.Async.callbacks("UserInfoBox.toggleLock [lock]", [
+ MochiKit.Base.partial(MochiKit.DOM.addElementClass, this.element(), 'locked'),
+ MochiKit.Base.partial(Clipperz.Visual.deferredAnimation, MochiKit.Visual.appear, maskElement, {from:0.0, to:0.75, duration:0.5}),
+ MochiKit.Base.method(Clipperz.PM.RunTime.mainController, 'setPassphraseDelegate', MochiKit.Base.method(this, 'askForPassphrase')),
+ MochiKit.Base.partial(MochiKit.Signal.signal, this, 'lock')
+ ], {trace:false});
+ } else {
+ deferredResult = Clipperz.Async.callbacks("UserInfoBox.toggleLock [unlock]", [
+ MochiKit.Base.partial(MochiKit.Signal.signal, this, 'unlock')
+ ], {trace:false});
+ }
+//console.log("<<< UserInfoBox.toggleLock");
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'unlock': function () {
+ var deferredResult;
+ var maskElement;
+
+ this.setIsLocked(false);
+ maskElement = this.getId('modalDialogMask');
+
+ deferredResult = Clipperz.Async.callbacks("UserInfoBox.unlock", [
+ MochiKit.Base.partial(Clipperz.Visual.deferredAnimation, MochiKit.Visual.fade, maskElement, {from:0.75, to:0.0, duration:0.5}),
+// Clipperz.Visual.deferredAnimation(MochiKit.Visual.fade, maskElement, {from:0.75, to:0.0, duration:0.5}),
+ MochiKit.Base.partial(MochiKit.DOM.removeElementClass, this.element(), 'locked')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'askForPassphrase': function () {
+ var unlockPasswordComponent;
+/*
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("UserInfoBox.askForPassphrase", {trace:false});
+ deferredResult.addCallback(MochiKit.Async.succeed, 'test');
+
+ deferredResult.callback();
+
+ return deferredResult;
+*/
+//console.log(">>> UserInfoBox.askForPassphrase");
+ unlockPasswordComponent = new Clipperz.PM.UI.Web.Components.UnlockPasswordComponent({
+ 'title': "Unlock account",
+ 'text': "Insert the passprase to unlock the account",
+ 'type': 'INFO',
+ 'buttons': [
+ {text:"Cancel", result:'CANCEL'},
+ {text:"Unlock", result:'OK', isDefault:true}
+ ],
+ 'openFromElement': this.getElement('lock'),
+ 'onOkCloseToElement': null,
+ 'onCancelCloseToElement': this.getId('lock')
+ });
+//console.log("<<< UserInfoBox.askForPassphrase");
+
+ return unlockPasswordComponent.getPassphrase();
+ },
+
+ //=========================================================================
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.append(this.element(), [
+// {tag:'canvas', id:this.getId('canvas'), cls:'canvas', width:'188', height:'154'},
+ {tag:'div', cls:'header', children:[
+ {tag:'h1', html:"Welcome"},
+ {tag:'a', cls:'lockButton', href:'#', id:this.getId('lock'), html:'&nbsp;'}
+ ]},
+ {tag:'div', cls:'body', children:[
+ {tag:'h3', id:this.getId('username'), html:""},
+ {tag:'ul', children:[
+ {tag:'li', id:this.getId('cards'), children:[
+ {tag:'span', id:this.getId('cardsNumber'), cls:'number', html:"-"},
+ {tag:'span', id:this.getId('cardsLabel'), html:"cards"}
+ ]},
+ {tag:'li', id:this.getId('directLogins'), children:[
+ {tag:'span', id:this.getId('directLoginsNumber'), cls:'number', html:"-"},
+ {tag:'span', id:this.getId('directLoginsLabel'), html:"direct logins"}
+ ]}
+ ]},
+ {tag:'a', href:'#', id:this.getId('logout'), html:"logout >"}
+ ]},
+ {tag:'div', cls:'footer'}
+ ]);
+
+ MochiKit.Signal.connect(this.getElement('logout'), 'onclick', this, 'handleLogout');
+ MochiKit.Signal.connect(this.getElement('lock'), 'onclick', this, 'toggleLock');
+
+ this._lockTooltip = new Clipperz.PM.UI.Common.Components.Tooltip({
+ element: this.getElement('lock'),
+ text: "Click here to lock/unlock your account.",
+ position: 'RIGHT'
+ });
+
+ Clipperz.DOM.Helper.append(MochiKit.DOM.currentDocument().body,
+ {tag:'div', id:this.getId('modalDialogWrapper'), cls:'modalDialogWrapper', children:[
+ {tag:'div', id:this.getId('modalDialogMask'), cls:'modalDialogMask userInfoBoxMask'}
+ ]}
+ );
+ MochiKit.Style.hideElement(this.getId('modalDialogMask'));
+
+// this.drawUserInfoBackground(this.getElement('canvas'));
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'drawUserInfoBackground': function (canvas) {
+ var kMyDrawingFunctionWidth = 188.0;
+ var kMyDrawingFunctionHeight = 154.0;
+
+ var context = canvas.getContext("2d");
+ var color;
+ var resolution;
+ var alignStroke;
+ var path;
+ var pointX;
+ var pointY;
+ var controlPoint1X;
+ var controlPoint1Y;
+ var controlPoint2X;
+ var controlPoint2Y;
+ var gradient;
+ if (window.devicePixelRatio)
+ resolution = window.devicePixelRatio;
+ else
+ resolution = 1.0;
+ resolution *= 0.5 * (canvas.width / kMyDrawingFunctionWidth + canvas.height / kMyDrawingFunctionHeight);
+
+ context.save();
+ context.scale(canvas.width / kMyDrawingFunctionWidth, canvas.height / kMyDrawingFunctionHeight);
+ context.clearRect(0.0, 0.0, kMyDrawingFunctionWidth, kMyDrawingFunctionHeight);
+
+ // Setup for Shadow Effect
+ color = "rgba(0.0%, 0.0%, 0.0%, 0.667)";
+ context.save();
+ context.shadowColor = color;
+ context.shadowBlur = 3.0;
+ context.shadowOffsetX = 5.729 * Math.cos(7.592) * resolution;
+ context.shadowOffsetY = 5.729 * Math.sin(7.592) * resolution;
+
+ // Layer 1
+
+ alignStroke = 0.0;
+ context.beginPath();
+ pointX = 169.5;
+ pointY = 141.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.moveTo(pointX, pointY);
+ pointX = 177.5;
+ pointY = 133.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 173.889;
+ controlPoint1Y = 141.5;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 177.5;
+ controlPoint2Y = 137.889;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 177.5;
+ pointY = 19.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 169.5;
+ pointY = 11.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 177.5;
+ controlPoint1Y = 15.111;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 173.889;
+ controlPoint2Y = 11.5;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 18.5;
+ pointY = 11.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 10.5;
+ pointY = 19.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 14.111;
+ controlPoint1Y = 11.5;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 10.5;
+ controlPoint2Y = 15.111;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 10.5;
+ pointY = 133.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ pointX = 18.5;
+ pointY = 141.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ controlPoint1X = 10.5;
+ controlPoint1Y = 137.889;
+ controlPoint1X = (Math.round(resolution * controlPoint1X + alignStroke) - alignStroke) / resolution;
+ controlPoint1Y = (Math.round(resolution * controlPoint1Y + alignStroke) - alignStroke) / resolution;
+ controlPoint2X = 14.111;
+ controlPoint2Y = 141.5;
+ controlPoint2X = (Math.round(resolution * controlPoint2X + alignStroke) - alignStroke) / resolution;
+ controlPoint2Y = (Math.round(resolution * controlPoint2Y + alignStroke) - alignStroke) / resolution;
+ context.bezierCurveTo(controlPoint1X, controlPoint1Y, controlPoint2X, controlPoint2Y, pointX, pointY);
+ pointX = 169.5;
+ pointY = 141.5;
+ pointX = (Math.round(resolution * pointX + alignStroke) - alignStroke) / resolution;
+ pointY = (Math.round(resolution * pointY + alignStroke) - alignStroke) / resolution;
+ context.lineTo(pointX, pointY);
+ context.closePath();
+ gradient = context.createLinearGradient(94.0, 11.5, 94.0, 141.5);
+ color = "#EE9B69";
+ gradient.addColorStop(0.0, color);
+ color = "#E38D62";
+ gradient.addColorStop(1.0, color);
+ context.fillStyle = gradient;
+ context.fill();
+
+ // Shadow Effect
+ context.restore();
+
+ context.restore();
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'updateUserDetails': function (someUserInfo) {
+ var elementName;
+
+ for (elementName in someUserInfo) {
+ this.getElement(elementName).innerHTML = someUserInfo[elementName];
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js
new file mode 100644
index 0000000..05563bf
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/AppController.js
@@ -0,0 +1,329 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.AppController = function(args) {
+
+ this._user = null;
+ this._tabSlotNames = {
+ //tabName: slotName
+ 'cards': 'cardGrid',
+// 'directLogins': 'directLoginGrid',
+ 'account': 'accountPanel',
+ 'data': 'dataPanel',
+ 'tools': 'toolsPanel'
+ };
+
+ //controllers
+ this._cardsController = null;
+// this._directLoginsController = null;
+ this._filterController = null; // new Clipperz.PM.UI.Web.Controllers.FilterController();
+
+ //components
+ this._appPage = null;
+ this._userInfoBox = null;
+ this._tabSidePanel = null;
+
+// MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'editCard', this, 'handleEditCard');
+// MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'deleteCard', this, 'handleDeleteCard');
+
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'userDataSuccessfullySaved', this, 'userDataSuccessfullySavedHandler');
+
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.Web.Controllers.AppController.prototype, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.AppController";
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'setUser': function(anUser) {
+ this._user = anUser;
+ },
+
+ 'user': function() {
+ return this._user;
+ },
+
+ //-----------------------------------------------------------------------------
+/*
+ 'tabSlotNames': function() {
+ return this._tabSlotNames;
+ },
+*/
+ 'slotNameForTab': function(aTabName) {
+ return this._tabSlotNames[aTabName];
+ },
+
+ 'hideAllAppPageTabSlots': function() {
+ var aTabName;
+
+ for (aTabName in this._tabSlotNames) {
+ this.appPage().hideSlot(this.slotNameForTab(aTabName));
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'appPage': function() {
+ if (this._appPage == null) {
+ this._appPage = new Clipperz.PM.UI.Web.Components.AppPage();
+ }
+
+ return this._appPage;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'tabSidePanel': function() {
+ if (this._tabSidePanel == null) {
+ this._tabSidePanel = new Clipperz.PM.UI.Web.Components.TabSidePanel();
+ }
+
+ return this._tabSidePanel;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'userInfoBox': function() {
+ if (this._userInfoBox == null) {
+ this._userInfoBox = new Clipperz.PM.UI.Web.Components.UserInfoBox();
+
+ MochiKit.Signal.connect(this._userInfoBox, 'logout', this, 'handleLogout');
+ MochiKit.Signal.connect(this._userInfoBox, 'lock', this, 'handleLock');
+ MochiKit.Signal.connect(this._userInfoBox, 'unlock', this, 'handleUnlock');
+ }
+
+ return this._userInfoBox;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'accountPanel': function () {
+ if (this._accountPanel == null) {
+ this._accountPanel = new Clipperz.PM.UI.Web.Components.AccountPanel(/*{selected:'Preferences'}*/);
+ }
+
+ return this._accountPanel;
+ },
+
+ //.........................................................................
+
+ 'dataPanel': function () {
+ if (this._dataPanel == null) {
+ this._dataPanel = new Clipperz.PM.UI.Web.Components.DataPanel();
+ }
+
+ return this._dataPanel;
+ },
+
+ //.........................................................................
+
+ 'toolsPanel': function () {
+ if (this._toolsPanel == null) {
+ this._toolsPanel = new Clipperz.PM.UI.Web.Components.ToolsPanel();
+ }
+
+ return this._toolsPanel;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'filterController': function () {
+ if (this._filterController == null) {
+ this._filterController = new Clipperz.PM.UI.Web.Controllers.FilterController();
+ }
+
+ return this._filterController;
+ },
+
+ 'cardsController': function() {
+ if (this._cardsController == null) {
+ this._cardsController = new Clipperz.PM.UI.Web.Controllers.CardsController({'filterController':this._filterController});
+ }
+
+ return this._cardsController;
+ },
+
+ //-----------------------------------------------------------------------------
+/*
+ 'directLoginsController': function() {
+//Clipperz.log(">>> AppController.directLoginsController");
+ if (this._directLoginsController == null) {
+ this._directLoginsController = new Clipperz.PM.UI.Web.Controllers.DirectLoginsController({'filterController':this._filterController});
+ }
+//Clipperz.log("<<< AppController.directLoginsController");
+
+ return this._directLoginsController;
+ },
+*/
+ //-----------------------------------------------------------------------------
+
+ 'populateUserInfo': function() {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("AppController.populateUserInfo", {trace:false});
+ deferredResult.collectResults({
+ 'username': MochiKit.Base.methodcaller('displayName'),
+ 'cardsNumber': [
+ MochiKit.Base.methodcaller('getRecords'),
+ function (someResults) { return someResults.length; }
+ ],
+ 'directLoginsNumber': [
+ MochiKit.Base.methodcaller('getDirectLogins'),
+ function (someResults) { return someResults.length; }
+ ]
+ })
+ deferredResult.addMethod(this.userInfoBox(), 'updateUserDetails');
+ deferredResult.callback(this.user());
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'run': function(args) {
+ var deferredResult;
+ var slot;
+ var page;
+ var user;
+
+ slot = args.slot;
+ user = args.user;
+
+ this.setUser(user);
+
+ slot.setContent(this.appPage());
+
+ this.appPage().slotNamed('userInfoBox').setContent(this.userInfoBox());
+ this.appPage().slotNamed('tabSidePanel').setContent(this.tabSidePanel());
+
+ this.appPage().slotNamed('accountPanel').setContent(this.accountPanel());
+ this.appPage().slotNamed('dataPanel').setContent(this.dataPanel());
+ this.appPage().slotNamed('toolsPanel').setContent(this.toolsPanel());
+
+ this.hideAllAppPageTabSlots();
+ this.appPage().showSlot(this.slotNameForTab('cards'));
+
+ MochiKit.Signal.connect(this.tabSidePanel(), 'tabSelected', this, 'handleTabSelected');
+ MochiKit.Signal.connect(this.tabSidePanel(), 'addCard', this, 'handleAddCard');
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'addCard', this, 'handleAddCard');
+
+ deferredResult = new Clipperz.Async.Deferred("AppController.run", {trace:false});
+
+ deferredResult.addMethod(this.cardsController(), 'run', {slot:this.appPage().slotNamed('cardGrid'), user:user});
+// deferredResult.addMethod(this.directLoginsController(), 'run', {slot:this.appPage().slotNamed('directLoginGrid'), user:user});
+ deferredResult.addMethod(this, 'populateUserInfo');
+
+ deferredResult.addCallback(MochiKit.Visual.ScrollTo, 'miscLinks', {duration:0});
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'CARDS_CONTROLLER_DID_RUN');
+ deferredResult.addMethod(this.tabSidePanel(), 'selectTab', 'cards');
+ deferredResult.callback();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleTabSelected': function (selectedTabName) {
+ var aTabName;
+ var aSlotName;
+
+//Clipperz.log(">>> AppController.handleTabSelected", selectedTabName);
+ this.hideAllAppPageTabSlots();
+ this.appPage().showSlot(this.slotNameForTab(selectedTabName));
+
+ switch (selectedTabName) {
+ case 'cards':
+ this.cardsController().focus();
+ break;
+// case 'directLogins':
+// this.directLoginsController().focus();
+// break;
+ case 'data':
+ break;
+ case 'account':
+ break;
+ case 'tools':
+ break;
+ }
+//Clipperz.log("<-- AppController.handleTabSelected", aTabName);
+ },
+
+ //=============================================================================
+
+ 'handleAddCard': function (aSourceElement) {
+//Clipperz.log("=== AppController.addCard", aSourceElement);
+ this.cardsController().addCard(aSourceElement);
+ },
+
+ //=============================================================================
+
+ 'userDataSuccessfullySavedHandler': function (anEvent) {
+ this.populateUserInfo();
+ },
+
+ //=============================================================================
+
+ 'handleLogout': function(anEvent) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("AppController.handleLogout", {trace:false});
+ deferredResult.addMethod(this.user(), 'logout');
+ deferredResult.addCallback(MochiKit.Signal.signal, this, 'logout');
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleLock': function (anEvent) {
+ return Clipperz.Async.callbacks("AppController.handleLock", [
+ MochiKit.Base.method(this.cardsController(), 'deleteAllCleanTextData'),
+ MochiKit.Base.method(this.user(), 'lock')
+ ], {trace:false});
+ },
+
+ //.............................................................................
+
+ 'handleUnlock': function (anEvent) {
+ return Clipperz.Async.callbacks("AppController.handleUnock", [
+ MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress'),
+ MochiKit.Base.method(this.user(), 'login'),
+ MochiKit.Base.method(this.cardsController(), 'focus'),
+ MochiKit.Base.partial(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'progressDone'),
+ MochiKit.Base.method(this.userInfoBox(), 'unlock')
+ ], {trace:false});
+ },
+
+ //=============================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardDialogController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardDialogController.js
new file mode 100644
index 0000000..2340aeb
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardDialogController.js
@@ -0,0 +1,652 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.CardDialogController = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Controllers.CardDialogController.superclass.constructor.call(this, args);
+
+ this._record = args.record || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._delegate = args.delegate || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ this._referenceElement = null;
+ this._cardDialogComponent = null;
+
+ this._fieldsReferences = {};
+ this._directLoginReferences = {};
+
+ this._directLoginWizardController = null;
+ this._directLoginEditingComponent = null;
+ this._isDirectLoginEditingComponentVisible = false;
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Controllers.CardDialogController, Object, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.CardDialogController";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'record': function () {
+ return this._record;
+ },
+
+ 'delegate': function () {
+ return this._delegate;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'fieldsReferences': function () {
+ return this._fieldsReferences;
+ },
+
+ 'directLoginReferences': function () {
+ return this._directLoginReferences;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'referenceElement': function () {
+ return this._referenceElement;
+ },
+
+ 'setReferenceElement': function (anElement) {
+ this._referenceElement = anElement;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'cardDialogComponent': function () {
+ if (this._cardDialogComponent == null) {
+ this._cardDialogComponent = new Clipperz.PM.UI.Web.Components.CardDialogComponent();
+
+ MochiKit.Signal.connect(this._cardDialogComponent, 'cancel', this, 'handleCancel');
+ MochiKit.Signal.connect(this._cardDialogComponent, 'save', this, 'handleSave');
+
+ MochiKit.Signal.connect(this._cardDialogComponent, 'addField', this, 'handleAddField');
+ MochiKit.Signal.connect(this._cardDialogComponent, 'changedValue', this, 'handleChangedValue');
+
+ MochiKit.Signal.connect(this._cardDialogComponent, 'addDirectLogin',this, 'handleAddDirectLogin');
+ MochiKit.Signal.connect(this._cardDialogComponent, 'keyPressed', this, 'handleCardDialogComponentKeyPressed');
+ }
+
+ return this._cardDialogComponent;
+ },
+
+ //=========================================================================
+
+ 'directLoginWizardController': function () {
+ if (this._directLoginWizardController == null) {
+ this._directLoginWizardController = new Clipperz.PM.UI.Web.Controllers.DirectLoginWizardController({
+ 'cardLabel': this.cardDialogComponent().title(),
+ 'directLoginEditingComponent': this.directLoginEditingComponent()
+ })
+
+ MochiKit.Signal.connect(this._directLoginWizardController, 'exit', this, 'handleHideDirectLoginEditingComponent');
+ MochiKit.Signal.connect(this._directLoginWizardController, 'done', this, 'handleCompleteDirectLoginEditingComponent');
+ }
+
+ return this._directLoginWizardController;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'directLoginEditingComponent': function () {
+ if (this._directLoginEditingComponent == null) {
+ this._directLoginEditingComponent = new Clipperz.PM.UI.Web.Components.DirectLoginEditingComponent();
+
+ this.cardDialogComponent().renderDirectLoginEditingComponent(this._directLoginEditingComponent);
+
+// MochiKit.Signal.connect(this._directLoginEditingComponent, 'back', this, 'handleHideDirectLoginEditingComponent')
+// MochiKit.Signal.connect(this._directLoginEditingComponent, 'changedValue', this, 'handleChangedValue');
+// MochiKit.Signal.connect(this.__directLoginEditingComponent, 'keyPressed', this, 'handleDirectLoginEditingComponentKeyPressed');
+ }
+
+ return this._directLoginEditingComponent;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isDirectLoginEditingComponentVisible': function () {
+ return this._isDirectLoginEditingComponentVisible;
+ },
+
+ 'setIsDirectLoginEditingComponentVisible': function (aValue) {
+ this._isDirectLoginEditingComponentVisible = aValue;
+ },
+
+ //=========================================================================
+
+ 'run': function (anElement) {
+ var deferredResult;
+
+ this.setReferenceElement(anElement);
+
+ deferredResult = new Clipperz.Async.Deferred("CardDialogController.run", {trace:false});
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress', {'steps':11});
+
+ deferredResult.addMethod(this.cardDialogComponent(), 'deferredShowModal', {openFromElement:this.referenceElement()});
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+
+ deferredResult.addMethod(this.record(), 'label');
+ deferredResult.addMethod(this.cardDialogComponent(), 'setTitle');
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+
+ deferredResult.addMethod(this, 'updateComponentState');
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'advanceProgress');
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'progressDone');
+
+ deferredResult.addMethod(this.cardDialogComponent(), 'fixRendering');
+ deferredResult.addMethod(this.cardDialogComponent(), 'hideProgressMask');
+
+ if (this.record().isBrandNew()) {
+ deferredResult.addMethod(this.cardDialogComponent(), 'setHintMode', 'ON');
+ deferredResult.addMethod(this.cardDialogComponent(), 'setFocusOnTitleField');
+ }
+
+ deferredResult.addErrback(MochiKit.Base.method(this.cardDialogComponent(), 'showError'));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'updateComponentState': function () {
+ return Clipperz.Async.callbacks("CardDialogController.updateComponentState", [
+ MochiKit.Base.method(this.record(), 'hasPendingChanges'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'setShouldEnableSaving'),
+
+ MochiKit.Base.method(this.record(), 'label'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'setTitle'),
+ MochiKit.Base.method(this.record(), 'notes'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'setNotes'),
+
+ MochiKit.Base.method(this.record(), 'fields'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'addCardDialogComponentWithField')),
+
+ MochiKit.Base.method(this.record(), 'directLogins'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'addCardDialogComponentWithDirectLogin')),
+
+ MochiKit.Base.method(this.cardDialogComponent(), 'resetNewFieldInputs'),
+ MochiKit.Base.noop
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addCardDialogComponentWithField': function (aField) {
+ var fieldComponent;
+
+ fieldComponent = new Clipperz.PM.UI.Web.Components.CardDialogRecordFieldComponent({reference: aField.reference()});
+ MochiKit.Signal.connect(fieldComponent, 'changedValue', this, 'handleChangedValue');
+ MochiKit.Signal.connect(fieldComponent, 'performAction',this, 'handlePerformFieldAction');
+ MochiKit.Signal.connect(fieldComponent, 'deleteField', this, 'handleDeleteField');
+
+// this.fieldsReferences().push({'field':aField, 'component':fieldComponent});
+ this.fieldsReferences()[aField.reference()] = {'field':aField, 'component':fieldComponent};
+
+ return Clipperz.Async.callbacks("CardDialogController.addCardDialogComponentWithField", [
+ MochiKit.Base.method(this.cardDialogComponent(), 'addFieldRowComponent', fieldComponent),
+
+ MochiKit.Base.method(aField, 'label'),
+ MochiKit.Base.method(fieldComponent, 'setLabel'),
+ MochiKit.Base.method(aField, 'value'),
+ MochiKit.Base.method(fieldComponent, 'setValue'),
+ MochiKit.Base.method(aField, 'actionType'),
+ MochiKit.Base.method(fieldComponent, 'setActionType'),
+ MochiKit.Base.method(aField, 'isHidden'),
+ MochiKit.Base.method(fieldComponent, 'setIsHidden')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addCardDialogComponentWithDirectLogin': function (aDirectLogin) {
+ var directLoginComponent;
+
+ directLoginComponent = new Clipperz.PM.UI.Web.Components.CardDialogRecordDirectLoginComponent({reference: aDirectLogin.reference()});
+ MochiKit.Signal.connect(directLoginComponent, 'changedValue', this, 'handleChangedValue');
+ MochiKit.Signal.connect(directLoginComponent, 'deleteDirectLogin', this, 'handleDeleteDirectLogin');
+ MochiKit.Signal.connect(directLoginComponent, 'editDirectLogin', this, 'handleEditDirectLogin');
+ MochiKit.Signal.connect(directLoginComponent, 'openDirectLogin', this, 'handleOpenDirectLogin');
+
+ this.directLoginReferences()[aDirectLogin.reference()] = {'directLogin':aDirectLogin, 'component':directLoginComponent};
+
+ return Clipperz.Async.callbacks("CardDialogController.addCardDialogComponentWithDirectLogin", [
+ MochiKit.Base.method(this.cardDialogComponent(), 'addDirectLoginComponent', directLoginComponent),
+ MochiKit.Base.method(this, 'refreshDirectLoginComponent', this.directLoginReferences()[aDirectLogin.reference()])
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'refreshDirectLoginComponent': function (aDirectLoginReference) {
+ return Clipperz.Async.callbacks("CardDialogController.refreshDirectLoginComponent", [
+ MochiKit.Base.method(aDirectLoginReference['directLogin'], 'favicon'),
+// MochiKit.Base.method(aDirectLoginReference['directLogin'], 'faviconData'),
+ MochiKit.Base.method(aDirectLoginReference['component'], 'setFavicon'),
+ MochiKit.Base.method(aDirectLoginReference['directLogin'], 'label'),
+ MochiKit.Base.method(aDirectLoginReference['component'], 'setLabel')
+ ], {trace:false});
+ },
+
+ 'refreshDirectLoginComponents': function () {
+ return Clipperz.Async.callbacks("CardDialogController.refreshDirectLoginComponents", [
+ MochiKit.Base.method(this, 'directLoginReferences'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'refreshDirectLoginComponent')),
+ Clipperz.Async.collectAll
+ ])
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateRecordValues': function () {
+ return Clipperz.Async.callbacks('CardDialogController.updateRecordValues', [
+ MochiKit.Base.method(this.cardDialogComponent(), 'title'),
+ MochiKit.Base.method(this.record(), 'setLabel'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'notes'),
+ MochiKit.Base.method(this.record(), 'setNotes'),
+
+ MochiKit.Base.method(this, 'fieldsReferences'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'updateRecordFieldValues')),
+
+ MochiKit.Base.method(this, 'directLoginReferences'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.method(this, 'updateRecordDirectLoginValues')),
+
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'directLoginReference'),
+ MochiKit.Base.method(this.record(), 'directLoginWithReference'),
+ MochiKit.Base.method(this, 'updateRecordDirectLoginDetails'),
+
+ MochiKit.Base.noop
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateRecordFieldValues': function (aFieldReference) {
+ var deferredResult;
+
+ deferredResult = Clipperz.Async.callbacks('CardDialogController.updateRecordFieldValues', [
+ MochiKit.Base.method(aFieldReference['component'], 'label'),
+ MochiKit.Base.method(aFieldReference['field'], 'setLabel'),
+
+ MochiKit.Base.method(aFieldReference['component'], 'value'),
+ MochiKit.Base.method(aFieldReference['field'], 'setValue'),
+
+ MochiKit.Base.method(aFieldReference['component'], 'isHidden'),
+ MochiKit.Base.method(aFieldReference['field'], 'setIsHidden'),
+
+ MochiKit.Base.method(aFieldReference['field'], 'actionType'),
+ MochiKit.Base.method(aFieldReference['component'], 'setActionType')
+ ], {trace:false});
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateRecordDirectLoginValues': function (aDirectLoginReference) {
+ var deferredResult;
+
+ deferredResult = Clipperz.Async.callbacks('CardDialogController.updateRecordDirectLoginValues', [
+ MochiKit.Base.method(aDirectLoginReference['component'], 'label'),
+ MochiKit.Base.method(aDirectLoginReference['directLogin'], 'setLabel')
+ ], {trace:false});
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'updateRecordDirectLoginDetails': function (aDirectLogin) {
+ var result;
+
+ if (MochiKit.Base.isUndefinedOrNull(aDirectLogin)) {
+ result = MochiKit.Async.succeed();
+ } else {
+ result = Clipperz.Async.callbacks("CardDialogController.updateRecordDirectLoginDetails", [
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'label'),
+ MochiKit.Base.method(aDirectLogin, 'setLabel'),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'favicon'),
+ MochiKit.Base.method(aDirectLogin, 'setFavicon')
+ ], {trace:false});
+ }
+
+ return result;
+ },
+
+ //=========================================================================
+
+ 'addField': function () {
+ return this.record().addField({
+ 'label':this.cardDialogComponent().newFieldLabel(),
+ 'value':this.cardDialogComponent().newFieldValue(),
+ 'isHidden':this.cardDialogComponent().newFieldIsHidden()
+ });
+ },
+
+ 'handleAddField': function () {
+ return Clipperz.Async.callbacks("CardDialogController.handleAddField", [
+ MochiKit.Base.method(this, 'addField'),
+
+ MochiKit.Base.method(this, 'addCardDialogComponentWithField'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'resetNewFieldInputs'),
+
+ MochiKit.Base.method(this.cardDialogComponent(), 'fixRendering'),
+ MochiKit.Base.method(this, 'handleChangedValue')
+ ], {trace:false})
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handlePerformFieldAction': function (aFieldID, aTargetElement) {
+//console.log("### targetElement", aTargetElement);
+ return Clipperz.Async.callbacks("CardDialogController.handleDeleteField", [
+ MochiKit.Base.method(this.record(), 'fields'),
+ MochiKit.Base.itemgetter(aFieldID),
+ Clipperz.Async.collectResults("CardDialogController.handleDeleteField <collect results>", {
+ 'value': MochiKit.Base.methodcaller('value'),
+ 'type': MochiKit.Base.methodcaller('actionType')
+ }, {trace:false}),
+ MochiKit.Base.bind(function (someValues) {
+ switch (someValues['type']) {
+ case 'NONE':
+ throw "this event handler should not be triggered for fields with type 'NONE'";
+ break;
+ case 'URL':
+ var url;
+
+ url = someValues['value'];
+ if (/^https?\:\/\//.test(url) == false) {
+ url = 'http://' + url;
+ }
+
+ window.open(url);
+ break;
+ case 'EMAIL':
+ var url;
+
+ url = 'mailto:' + someValues['value'];
+
+ MochiKit.DOM.currentWindow().location = url;
+ break;
+ case 'PASSWORD':
+//Clipperz.log("SHOW PASSWORD " + someValues['value']);
+ this.showPasswordTooltip(someValues['value'], aTargetElement);
+ break;
+ }
+ }, this)
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleDeleteField': function (aFieldID) {
+ return Clipperz.Async.callbacks("CardDialogController.handleDeleteField", [
+ MochiKit.Base.method(this.record(), 'fields'),
+ MochiKit.Base.itemgetter(aFieldID),
+ MochiKit.Base.method(this.record(), 'removeField'),
+
+ MochiKit.Base.method(this, 'fieldsReferences'),
+ MochiKit.Base.itemgetter(aFieldID),
+ MochiKit.Base.itemgetter('component'),
+
+ function (aComponent) {
+ return Clipperz.Async.callbacks("CardDialogController.handleDeleteField [fade and remove]", [
+ MochiKit.Base.partial(Clipperz.Visual.deferredAnimation, MochiKit.Visual.fade, aComponent.element(), {from:1.0, to:0.0, duration:0.5}),
+// Clipperz.Visual.deferredAnimation(MochiKit.Visual.fade, aComponent.element(), {from:1.0, to:0.0, duration:0.5}),
+ MochiKit.Base.method(aComponent, 'remove')
+ ], {trace:false});
+ },
+
+ MochiKit.Base.bind(function () {
+ delete this.fieldsReferences()[aFieldID];
+ }, this),
+
+ MochiKit.Base.method(this.cardDialogComponent(), 'fixRendering'),
+ MochiKit.Base.method(this, 'handleChangedValue')
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'handleDeleteDirectLogin': function(aDirectLoginReference) {
+ var cardDialogComponent;
+
+ cardDialogComponent = this.cardDialogComponent();
+
+ return Clipperz.Async.callbacks("CardDialogController.handleDeleteDirectLogin", [
+ MochiKit.Base.method(this.record(), 'directLogins'),
+ MochiKit.Base.itemgetter(aDirectLoginReference),
+ MochiKit.Base.methodcaller('remove'),
+
+ MochiKit.Base.method(this, 'directLoginReferences'),
+ MochiKit.Base.itemgetter(aDirectLoginReference),
+ MochiKit.Base.itemgetter('component'),
+
+ function (aComponent) {
+ return Clipperz.Async.callbacks("CardDialogController.handleDeleteDirectLogin [fade and remove]", [
+ MochiKit.Base.partial(Clipperz.Visual.deferredAnimation, MochiKit.Visual.fade, aComponent.element(), {from:1.0, to:0.0, duration:0.5}),// Clipperz.Visual.deferredAnimation(MochiKit.Visual.fade, aComponent.element(), {from:1.0, to:0.0, duration:0.5}),
+/// MochiKit.Base.method(aComponent, 'remove')
+ MochiKit.Base.method(cardDialogComponent, 'removeDirectLoginComponent', aComponent)
+ ], {trace:false});
+ },
+
+ MochiKit.Base.bind(function () {
+ delete this.directLoginReferences()[aDirectLoginReference];
+ }, this),
+
+ MochiKit.Base.method(this.cardDialogComponent(), 'fixRendering'),
+ MochiKit.Base.method(this, 'handleChangedValue')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleOpenDirectLogin': function (aDirectLoginReference) {
+ return Clipperz.Async.callbacks("CardDialogController.handleOpenDirectLogin", [
+ MochiKit.Base.method(this.record(), 'directLoginWithReference', aDirectLoginReference),
+ Clipperz.PM.UI.Common.Controllers.DirectLoginRunner.openDirectLogin
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleEditDirectLogin': function (aDirectLoginReference) {
+ return Clipperz.Async.callbacks("CardDialogController.handleEditDirectLogin", [
+ MochiKit.Base.method(this, 'setIsDirectLoginEditingComponentVisible', true),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setDirectLoginReference', aDirectLoginReference),
+ MochiKit.Base.method(this.cardDialogComponent(), 'placeDirectLoginEditingComponent'),
+ MochiKit.Base.method(this.record(), 'directLoginWithReference', aDirectLoginReference),
+ MochiKit.Base.method(this.directLoginWizardController(), 'runWithDirectLogin'),
+ MochiKit.Base.method(this.directLoginWizardController(), 'fixRulerRendering', this.cardDialogComponent().displayMode()),
+ MochiKit.Base.method(this.cardDialogComponent(), 'showDirectLoginEditingComponent')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleHideDirectLoginEditingComponent': function () {
+ return Clipperz.Async.callbacks("CardDialogController.handleHideDirectLoginEditingComponent", [
+ MochiKit.Base.method(this, 'setIsDirectLoginEditingComponentVisible', false),
+ MochiKit.Base.method(this.directLoginWizardController(), 'hideRuler'),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setDirectLoginReference', null),
+ MochiKit.Base.method(this, 'refreshDirectLoginComponents'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'hideDirectLoginEditingComponent')
+ ], {trace:false})
+ },
+
+ 'handleCompleteDirectLoginEditingComponent': function (someParameters) {
+ return Clipperz.Async.callbacks("CardDialogController.handleCompleteDirectLoginEditingComponent", [
+ MochiKit.Base.method(this, 'setIsDirectLoginEditingComponentVisible', false),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setDirectLoginReference', null),
+ MochiKit.Base.partial(MochiKit.Async.succeed, someParameters['hasJustBeenAdded']),
+ Clipperz.Async.deferredIf("CardDialogController.handleCompleteDirectLoginEditingComponent - should addTheEditedDirectLogin", [
+ MochiKit.Base.method(this, 'addCardDialogComponentWithDirectLogin', someParameters['directLogin'])
+ ], []),
+ MochiKit.Base.method(this, 'refreshDirectLoginComponents'),
+ MochiKit.Base.method(this, 'handleChangedValue'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'hideDirectLoginEditingComponent')
+ ], {trace:false})
+ },
+
+ //=========================================================================
+
+ 'handleChangedValue': function () {
+ return Clipperz.Async.callbacks("CardDialogController.handleChangedValue", [
+ MochiKit.Base.method(this, 'updateRecordValues'),
+ MochiKit.Base.method(this.record(), 'hasPendingChanges'),
+ MochiKit.Base.method(this.cardDialogComponent(), 'setShouldEnableSaving')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleSave': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("CardDialogController.handleSave", {trace:false});
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress', {'steps':8});
+ deferredResult.addMethod(this.cardDialogComponent(), 'showProgressMask');
+ deferredResult.addMethod(this.cardDialogComponent(), 'newFieldHasPendingChanges');
+ deferredResult.addIf([
+ MochiKit.Base.method(this, 'addField')
+ ], [])
+ deferredResult.addMethod(this, 'saveChanges');
+ deferredResult.addMethod(this.cardDialogComponent(), 'deferredHideModal', {closeToElement:null});
+ deferredResult.addMethod(this.cardDialogComponent(), 'remove');
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'cardDialogComponentClosed');
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //.........................................................................
+
+ 'saveChanges': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("CardDialogController.handleSave", {trace:false});
+ deferredResult.addMethod(this.delegate(), 'saveChanges');
+deferredResult.addErrback(function (aValue) { Clipperz.log("SHIT HAPPENS!!"); return aValue; });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleCancel': function () {
+ var deferredResult;
+
+ if (this.isDirectLoginEditingComponentVisible()) {
+ deferredResult = this.handleHideDirectLoginEditingComponent();
+ } else {
+ deferredResult = new Clipperz.Async.Deferred("CardDialogController.handleCancel", {trace:false});
+ // deferredResult.addMethod(this.record(), 'hasPendingChanges'),
+ deferredResult.addMethod(this.delegate(), 'hasPendingChanges'),
+ deferredResult.addIf([
+ MochiKit.Base.method(this.cardDialogComponent(), 'askConfirmationForLoosingPendingChanges')
+ ], [])
+ deferredResult.addMethod(this.delegate(), 'revertChanges');
+ deferredResult.addMethod(this.cardDialogComponent(), 'deferredHideModal', {closeToElement:this.referenceElement()});
+ deferredResult.addMethod(this.cardDialogComponent(), 'remove');
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'cardDialogComponentClosed');
+
+ deferredResult.callback();
+ }
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleAddDirectLogin': function () {
+ return Clipperz.Async.callbacks("CardDialogController.handleAddDirectLogin", [
+ MochiKit.Base.method(this.record(), 'createNewDirectLogin'),
+ MochiKit.Base.bind(function (aDirectLogin) {
+ return Clipperz.Async.callbacks("CardDialogController.handleAddDirectLogin - directLogin", [
+ MochiKit.Base.method(this.cardDialogComponent(), 'newFieldHasPendingChanges'),
+ Clipperz.Async.deferredIf("cardDialogComponent.newFieldHasPendingChanges", [
+ MochiKit.Base.method(this, 'handleAddField')
+ ], []),
+
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setDirectLoginReference', aDirectLogin.reference()),
+ MochiKit.Base.method(this.cardDialogComponent(), 'placeDirectLoginEditingComponent'),
+ MochiKit.Base.method(this.directLoginWizardController(), 'runWithDirectLogin', aDirectLogin, true),
+ MochiKit.Base.method(this.directLoginWizardController(), 'fixRulerRendering', this.cardDialogComponent().displayMode()),
+ MochiKit.Base.method(this.cardDialogComponent(), 'showDirectLoginEditingComponent')
+ ], {trace:false});
+ }, this)
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'handleCardDialogComponentKeyPressed': function (anEvent) {
+ if ((anEvent.key().string == 'KEY_TAB') && this.cardDialogComponent().newFieldHasPendingChanges()) {
+ anEvent.preventDefault();
+
+// MochiKit.Signal.signal(this.cardDialogComponent(), 'addField');
+ this.handleAddField()
+ this.cardDialogComponent().focusOnNewFieldLabel();
+ }
+ },
+
+ //=========================================================================
+
+ 'showPasswordTooltip': function (aValue, anElement) {
+ var passwordTooltip;
+
+ passwordTooltip = new Clipperz.PM.UI.Web.Components.PasswordTooltip({
+ 'referebceElement': anElement,
+ 'text': aValue
+ });
+
+ passwordTooltip.show();
+
+
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardsController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardsController.js
new file mode 100644
index 0000000..b1a34b2
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/CardsController.js
@@ -0,0 +1,207 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.CardsController = function() {
+ Clipperz.PM.UI.Web.Controllers.CardsController.superclass.constructor.apply(this, arguments);
+
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'cardDialogComponentClosed', this, 'handleHideCard');
+
+ return this;
+}
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Controllers.CardsController, Clipperz.PM.UI.Web.Controllers.GridController, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.CardsController";
+ },
+
+ 'createGrid': function () {
+ var grid;
+
+ grid = new Clipperz.PM.UI.Web.Components.GridComponent({columnsManagers: [
+ new Clipperz.PM.UI.Web.Components.FaviconColumnManager({
+ 'name': 'Cards.favicon',
+ 'selector': MochiKit.Base.methodcaller('favicon'),
+ 'cssClass': 'favicon'
+ }),
+ new Clipperz.PM.UI.Web.Components.LinkColumnManager({
+ 'name': 'Cards.title',
+ 'selector': MochiKit.Base.methodcaller('label'),
+ 'label': 'title',
+ 'cssClass': 'title',
+ 'comparator': Clipperz.Base.caseInsensitiveCompare,
+ 'sortable': true,
+ 'sorted': 'ASCENDING',
+// 'actionMethod': function(anObject, anEvent) { MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'editCard', {objectData:anObject, element:anEvent.src()})}
+ 'actionMethod': MochiKit.Base.method(this, 'handleShowCard')
+ }),
+ new Clipperz.PM.UI.Web.Components.DirectLoginsColumnManager({
+ 'name': 'Cards.directLogins',
+ 'selector': MochiKit.Base.methodcaller('directLoginReferences'),
+ 'label': 'direct logins',
+ 'cssClass': 'directLogin'
+ }),
+ new Clipperz.PM.UI.Web.Components.DateColumnManager({
+ 'name': 'Cards.latestUpdate',
+ 'selector': MochiKit.Base.methodcaller('updateDate'),
+ 'label': 'latest update',
+ 'cssClass': 'latestUpdate',
+ 'format': 'd-m-Y',
+ 'comparator': MochiKit.Base.compare,
+ 'sortable': true,
+ 'sorted': 'UNSORTED'
+ }),
+ new Clipperz.PM.UI.Web.Components.DeleteObjectColumnManager({
+ 'name': 'Cards.delete',
+ 'selector': MochiKit.Base.noop,
+ 'cssClass': 'delete',
+// 'actionMethod': function(anObject, anEvent) { MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'deleteCard', {objectData:anObject, element:anEvent.src()})}
+ 'actionMethod': MochiKit.Base.method(this, 'handleDeleteCard')
+ })
+ ]});
+
+ grid.setComponentForSlotNamed(new Clipperz.PM.UI.Web.Components.BookmarkletComponent(), 'headerSlot');
+
+ return grid;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'getRows': function () {
+ //TODO relying on user() in GridController, bad code smell :|
+ return this.user().getRecords();
+ },
+
+ //=============================================================================
+
+ 'displayEmptyContent': function () {
+ var emptyGridComponent;
+
+ emptyGridComponent = new Clipperz.PM.UI.Web.Components.CreateNewCardSplashComponent();
+
+ return Clipperz.Async.callbacks("CardsController.displayEmptyContent", [
+ MochiKit.Base.method(this.grid(), 'setNoRowsGridComponent', emptyGridComponent),
+ MochiKit.Base.bind(Clipperz.PM.UI.Web.Controllers.CardsController.superclass.displayEmptyContent, this)
+ ], {trace:false});
+ },
+
+ 'displaySelectedRows': function (aFilter) {
+ this.columnManagerWithName('Cards.directLogins').hideDirectLoginListPopup();
+
+ return Clipperz.PM.UI.Web.Controllers.CardsController.superclass.displaySelectedRows.apply(this, arguments);
+ },
+
+ //=============================================================================
+
+ 'handleShowCard': function (anObject, anEvent) {
+ var cardDialogController;
+
+ cardDialogController = new Clipperz.PM.UI.Web.Controllers.CardDialogController({record:anObject, delegate:this});
+ this.grid().selectRow(anObject);
+
+ cardDialogController.run(anEvent.src());
+ },
+
+ //.........................................................................
+
+ 'handleHideCard': function () {
+ this.focus();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'addCard': function (aSourceElement) {
+ return Clipperz.Async.callbacks("CardsController.addCard", [
+ Clipperz.Async.collectResults("CardsController.addCard <inner results>", {
+ 'record': MochiKit.Base.method(this.user(), 'createNewRecord'),
+ 'delegate': MochiKit.Base.partial(MochiKit.Async.succeed, this)
+ }, {trace:false}),
+ function (someParameters) {
+ return new Clipperz.PM.UI.Web.Controllers.CardDialogController(someParameters);
+ },
+ MochiKit.Base.methodcaller('run', aSourceElement)
+ ], {trace:false});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleDeleteCard': function (anObject, anEvent) {
+ var deferredResult;
+ var confirmationDialog;
+
+// confirmationDialog = new Clipperz.PM.UI.Common.Components.SimpleMessagePanel({
+ confirmationDialog = new Clipperz.PM.UI.Common.Components.MessagePanelWithProgressBar({
+ 'title': "Delete Card",
+ 'text': "Do you want to delete …",
+ 'type': 'ALERT',
+ 'buttons': [
+ {text:"Cancel", result:'CANCEL'},
+ {text:"Delete", result:'OK', isDefault:true}
+ ],
+ 'canCancelWhileProcessing': false
+ });
+
+ deferredResult = new Clipperz.Async.Deferred("AppController.handleDeleteCard", {trace:false});
+ deferredResult.addCallback(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress', {'steps':5}),
+ deferredResult.addMethod(this.grid(), 'selectRow', anObject);
+ deferredResult.addMethod(confirmationDialog, 'deferredShowModal', {
+ 'openFromElement': anEvent.src(),
+ 'onOkCloseToElement': null, // MochiKit.DOM.currentDocument().body,
+ 'onCancelCloseToElement': anEvent.src()
+ });
+// deferredResult.addCallback(function () { Clipperz.log("DELETE: " + anObject.toString(), anObject); });
+ deferredResult.addMethod(this.user(), 'deleteRecord', anObject);
+ deferredResult.addBothPass(MochiKit.Base.method(this.grid(), 'unselectRow', anObject));
+ deferredResult.addMethod(this, 'saveChanges');
+ deferredResult.addMethod(confirmationDialog, 'deferredDone');
+ deferredResult.addErrbackPass(function (anError) {
+ var result;
+
+ if (! (anError instanceof MochiKit.Async.CancelledError)) {
+ result = confirmationDialog.deferredError({
+ 'type': 'ALERT',
+ 'title': "Error",
+ 'text': Clipperz.PM.Strings.errorDescriptionForException(anError),
+ 'buttons': [{text:"Close", result:'CANCEL', isDefault:true}]
+ })
+ } else {
+ result = anError;
+ }
+
+ return result;
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=============================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginWizardController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginWizardController.js
new file mode 100644
index 0000000..38fdc08
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginWizardController.js
@@ -0,0 +1,611 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.DirectLoginWizardController = function(args) {
+ this._directLoginEditingComponent = args.directLoginEditingComponent || Clipperz.Base.exception.raise('MandatoryParameter');
+ this._cardLabel = args.cardLabel || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ MochiKit.Signal.connect(this._directLoginEditingComponent, 'changedValue', this, 'handleChangedValue');
+ MochiKit.Signal.connect(this._directLoginEditingComponent, 'moveForward', this, 'handleMoveForward');
+ MochiKit.Signal.connect(this._directLoginEditingComponent, 'keyPressed', this, 'handleDirectLoginEditingComponentKeyPressed');
+
+ this._directLogin = null;
+ this._directLoginHasJustBeenAdded = false;
+
+ this._rulerComponent = null;
+
+ this._steps = null;
+ this._currentStepIndex = 0;
+ this._isNextEnabled = false;
+
+ this._recordFields = null;
+ this._originalBindings = null;
+
+ this._bindingComponents = [];
+ this._formValueComponents = [];
+
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.Web.Controllers.DirectLoginWizardController.prototype, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.DirectLoginWizardController";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'directLogin': function () {
+ return this._directLogin;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'directLoginHasJustBeenAdded': function () {
+ return this._directLoginHasJustBeenAdded;
+ },
+
+ 'setDirectLoginHasJustBeenAdded': function (aValue) {
+ this._directLoginHasJustBeenAdded = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'directLoginEditingComponent': function () {
+ return this._directLoginEditingComponent;
+ },
+
+ //=============================================================================
+
+ 'cardLabel': function () {
+ return this._cardLabel;
+ },
+
+ //=============================================================================
+
+ 'resetCurrentStepIndex': function () {
+ this._currentStepIndex = 0;
+ this.rulerComponent().resetStatus();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'enableNext': function (aValue) {
+ this.rulerComponent().enableNext(aValue);
+ this._isNextEnabled = aValue;
+ },
+
+ 'isNextEnabled': function () {
+ return this._isNextEnabled;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'enablePrevious': function (aValue) {
+ this.rulerComponent().enablePrevious(aValue);
+ },
+
+ //=============================================================================
+
+ 'bindingComponents': function () {
+ return this._bindingComponents;
+ },
+
+ 'resetBindingComponents': function () {
+ this.directLoginEditingComponent().clearAllBindingsComponents();
+ this._bindingComponents = [];
+ },
+
+ //=============================================================================
+
+ 'formValueComponents': function () {
+ return this._formValueComponents;
+ },
+
+ 'resetFormValueComponents': function () {
+ this.directLoginEditingComponent().clearAllFormValueComponents();
+ this._formValueComponents = [];
+ },
+
+ //=============================================================================
+
+ 'recordFields': function () {
+ return this._recordFields;
+ },
+
+ 'setRecordFields': function (aValue) {
+ this._recordFields = aValue;
+ },
+
+ 'recordFieldWithReference': function (aReference) {
+ var matchingValues;
+ var result;
+
+ matchingValues = MochiKit.Base.filter(function (aField) { return aField['reference'] == aReference; }, this.recordFields());
+
+ if (matchingValues.length == 0) {
+ result = null;
+ } else {
+ result = matchingValues[0];
+ }
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'originalBindings': function () {
+ return this._originalBindings;
+ },
+
+ 'setOriginalBindings': function (aValue) {
+//console.log("BINDINGS", aValue);
+ this._originalBindings = aValue;
+ },
+
+ //=============================================================================
+
+ 'rulerComponent': function () {
+ if (this._rulerComponent == null) {
+ this._rulerComponent = new Clipperz.PM.UI.Web.Components.RulerComponent({
+ translationContext:'Wizards.DirectLoginWizard'
+ });
+ this._rulerComponent.render();
+
+ MochiKit.Signal.connect(this._rulerComponent, 'exit', this, 'handleExit');
+ MochiKit.Signal.connect(this._rulerComponent, 'done', this, 'done');
+ MochiKit.Signal.connect(this._rulerComponent, 'moveForward', this, 'handleMoveForward');
+ MochiKit.Signal.connect(this._rulerComponent, 'moveBackward', this, 'handleMoveBackward');
+ MochiKit.Signal.connect(this._rulerComponent, 'cursorMoved', this, 'handleCursorMoved');
+ }
+
+ return this._rulerComponent;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'showRuler': function (someSteps) {
+ var rulerElement;
+
+ this.setSteps(someSteps);
+
+ rulerElement = this.rulerComponent().element();
+ this.directLoginEditingComponent().disableAllPanels();
+
+ MochiKit.Style.showElement(rulerElement);
+ MochiKit.Style.setElementPosition(rulerElement, {x:-1000, y:this.directLoginEditingComponent().bottomMargin()});
+ new MochiKit.Visual.Move(rulerElement, {
+ x:0, y:this.directLoginEditingComponent().bottomMargin(),
+ mode:'absolute',
+ duration:1,
+ afterFinish:MochiKit.Base.method(this, 'handleCursorMoved')
+ });
+ },
+
+ 'fixRulerRendering': function (aValue) {
+ this.rulerComponent().setDisplayMode(aValue);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'hideRuler': function () {
+ new MochiKit.Visual.Move(this.rulerComponent().element(), {x:-1000, mode:'relative', duration:1});
+ },
+
+ 'doneWithRuler': function () {
+ var rulerComponentElement;
+
+ rulerComponentElement = this.rulerComponent().element();
+ new MochiKit.Visual.Move(this.rulerComponent().element(), {
+ x:1000,
+ mode:'relative',
+ duration:1,
+// afterFinish:MochiKit.Base.partial(MochiKit.Style.hideElement, rulerComponentElement)
+ afterFinish:function () { MochiKit.Style.hideElement(rulerComponentElement); }
+ });
+ },
+
+ //=============================================================================
+
+ 'addNewDirectLoginRulerSteps': function () {
+ return MochiKit.Base.concat([ 'LABEL'], this.editDirectLoginRulerSteps());
+
+ },
+
+ 'editDirectLoginRulerSteps': function () {
+ return [ /*'TYPE',*/ 'CONFIGURATION', 'BINDINGS','FAVICON', 'DONE'];
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'runWithDirectLogin': function (aDirectLogin, hasJustBeenAdded) {
+ this._directLogin = aDirectLogin;
+ this.setDirectLoginHasJustBeenAdded(hasJustBeenAdded);
+
+ return Clipperz.Async.callbacks("DirectLoginWizardController.runWithDirectLogin", [
+ MochiKit.Base.method(aDirectLogin, 'label'),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setLabel'),
+
+ MochiKit.Base.method(aDirectLogin, 'favicon'),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setDirectLoginFavicon'),
+
+ MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setBookmarkletConfiguration'),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.method(this, 'setOriginalBindings'),
+
+ MochiKit.Base.method(aDirectLogin, 'record'),
+ MochiKit.Base.methodcaller('fields'),
+ MochiKit.Base.values,
+ MochiKit.Base.partial(MochiKit.Base.map, Clipperz.Async.collectResults("Record.directLoginReferences - collectResults", {
+ 'reference': MochiKit.Base.methodcaller('reference'),
+ 'label': MochiKit.Base.methodcaller('label'),
+ 'isHidden': MochiKit.Base.methodcaller('isHidden'),
+ 'value': MochiKit.Base.methodcaller('value')
+ }, {trace:false})),
+ Clipperz.Async.collectAll,
+
+ MochiKit.Base.method(this, 'setRecordFields'),
+
+ MochiKit.Base.partial(MochiKit.Async.succeed, hasJustBeenAdded),
+ Clipperz.Async.deferredIf("Direct login has just been added", [
+ MochiKit.Base.method(this, 'addNewDirectLoginRulerSteps')
+ ], [
+ MochiKit.Base.method(this, 'editDirectLoginRulerSteps')
+ ]),
+ MochiKit.Base.method(this, 'showRuler')
+ ], {trace:false});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'checkState': function () {
+ var enablePrevious;
+ var enableNext;
+
+ enablePrevious = true;
+ enableNext = false;
+
+ this.directLoginEditingComponent().disableAllPanels();
+
+ switch(this.currentStep()) {
+ case 'LABEL':
+ this.directLoginEditingComponent().enableLabelField();
+
+ enableNext = (this.directLoginEditingComponent().label() != '');
+ enablePrevious = false;
+ break;
+ case 'TYPE':
+ this.directLoginEditingComponent().enableTypeField();
+
+ enableNext = true;
+ enablePrevious = true;
+ break
+ case 'CONFIGURATION':
+ this.directLoginEditingComponent().enableConfigurationField();
+
+ enableNext = (this.directLoginEditingComponent().bookmarkletConfiguration() != '');
+
+ if (enableNext == true) {
+ try {
+ Clipperz.PM.DataModel.DirectLogin.checkBookmarkletConfiguration(this.directLoginEditingComponent().bookmarkletConfiguration());
+ this.directLoginEditingComponent().removeHighlightConfigurationSyntaxError();
+ } catch (e) {
+ this.directLoginEditingComponent().highlightConfigurationSyntaxError();
+ enableNext = false;
+ }
+ }
+ break;
+ case 'BINDINGS':
+ enableNext = MochiKit.Iter.every(this.bindingComponents(), function (aBindingComponent) { return aBindingComponent.selectedValue() != null; })
+ this.directLoginEditingComponent().enableBindingFields();
+ break;
+ case 'FAVICON':
+ enableNext = true;
+ this.directLoginEditingComponent().enableFaviconField();
+ break;
+ case 'DONE':
+ enableNext = true;
+ this.directLoginEditingComponent().enableDonePanel();
+ break;
+ }
+
+ if (this.currentStepIndex() > 0) {
+ this.enablePrevious(enablePrevious);
+ } else {
+ this.enablePrevious(false);
+ }
+ this.enableNext(enableNext);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'setFocus': function () {
+ switch(this.currentStep()) {
+ case 'LABEL':
+ this.directLoginEditingComponent().focusOnLabelElement();
+ break;
+ case 'TYPE':
+ break;
+ case 'CONFIGURATION':
+ this.directLoginEditingComponent().focusOnBookmarkletConfigurationElement();
+ break;
+ case 'BINDINGS':
+// this.directLoginEditingComponent().getElement('???').focus();
+ break;
+ case 'FAVICON':
+ this.directLoginEditingComponent().focusOnFaviconElement();
+ break;
+ case 'DONE':
+ break;
+ }
+ },
+
+ //=============================================================================
+
+ 'steps': function () {
+ return this._steps;
+ },
+
+ 'setSteps': function (aValue) {
+ this._steps = aValue;
+
+ this.rulerComponent().setSteps(aValue);
+ this.resetCurrentStepIndex();
+ },
+
+ 'currentStepIndex': function () {
+ return this._currentStepIndex;
+ },
+
+ 'currentStep': function () {
+ return this.steps()[this.currentStepIndex()];
+ },
+
+ //=============================================================================
+
+ 'handleExit': function () {
+ MochiKit.Signal.signal(this, 'exit');
+ },
+
+ 'done': function () {
+ this.doneWithRuler();
+
+ Clipperz.Async.callbacks("DirectLoginWizardController.done", [
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'label'),
+ MochiKit.Base.method(this.directLogin(), 'setLabel'),
+
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'bookmarkletConfiguration'),
+ MochiKit.Base.method(this.directLogin(), 'setBookmarkletConfiguration'),
+
+ // Bindings
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'bindingComponents'),
+// MochiKit.Base.partial(MochiKit.Base.map, MochiKit.Base.bind(function (aBindingComponent) {
+ Clipperz.Async.forEach(MochiKit.Base.bind(function (aBindingComponent) {
+//console.log("aBindingComponent", aBindingComponent);
+// this.directLogin().
+ return Clipperz.Async.callbacks("DirectLoginWizardController.done - update directLogin bindings", [
+ MochiKit.Base.method(this.directLogin(), 'bindings'),
+ MochiKit.Base.itemgetter(aBindingComponent.formFieldName()),
+ MochiKit.Base.methodcaller('setFieldKey', aBindingComponent.selectedValue())
+ ], {trace:false});
+ }, this)),
+
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'favicon'),
+ MochiKit.Base.method(this.directLogin(), 'setFavicon'),
+
+ MochiKit.Base.partial(MochiKit.Signal.signal, this, 'done', {
+ 'directLogin': this.directLogin(),
+ 'hasJustBeenAdded': this.directLoginHasJustBeenAdded()
+ })
+ ], {trace:false});
+ },
+
+ //=============================================================================
+
+ 'handleMoveBackward': function () {
+ if (this._currentStepIndex > 0) {
+ var afterMoveAction;
+
+ this._currentStepIndex --;
+ afterMoveAction = MochiKit.Base.noop;
+
+ switch(this.currentStep()) {
+ case 'LABEL':
+ break;
+ case 'TYPE':
+ break;
+ case 'CONFIGURATION':
+ break;
+ case 'BINDINGS':
+ break;
+ case 'FAVICON':
+ break;
+ case 'DONE':
+ break;
+ };
+
+ this.rulerComponent().moveBackward(afterMoveAction);
+ }
+
+ if (this._currentStepIndex == 0) {
+ this.enablePrevious(false);
+ }
+ },
+
+ 'handleMoveForward': function () {
+ if (this.isNextEnabled()) {
+ var afterMoveAction;
+
+ this._currentStepIndex ++;
+ afterMoveAction = MochiKit.Base.noop;
+
+ switch(this.currentStep()) {
+ case 'LABEL':
+ break;
+ case 'TYPE':
+ break;
+ case 'CONFIGURATION':
+ break;
+ case 'BINDINGS':
+ this.resetBindingComponents();
+ this.resetFormValueComponents();
+
+ afterMoveAction = MochiKit.Base.partial(Clipperz.Async.callbacks, "DirectLoginWizardController.handleMoveForward - BINDINGS", [
+ MochiKit.Base.method(this.directLogin(), 'setBookmarkletConfiguration', this.directLoginEditingComponent().bookmarkletConfiguration()),
+
+ MochiKit.Base.method(this.directLogin(), 'favicon'),
+ MochiKit.Base.method(this.directLoginEditingComponent(), 'setDirectLoginFavicon'),
+
+ MochiKit.Base.method(this.directLogin(), 'bindings'),
+ MochiKit.Base.values,
+ Clipperz.Async.forEach(MochiKit.Base.bind(function (aBinding) {
+ var bindingComponent;
+
+ bindingComponent = new Clipperz.PM.UI.Web.Components.DirectLoginEditingBindingComponent({
+ formFieldName: aBinding.key(),
+ fields: this.recordFields(),
+ selectedFieldKey: aBinding.fieldKey()
+ });
+
+ this.bindingComponents().push(bindingComponent);
+
+ MochiKit.Signal.connect(bindingComponent, 'bindChange', this, 'handleBindChange', bindingComponent);
+ this.directLoginEditingComponent().addBindingComponent(bindingComponent);
+
+ }, this)),
+
+ MochiKit.Base.method(this.directLogin(), 'formValues'),
+ MochiKit.Base.values,
+ Clipperz.Async.forEach(MochiKit.Base.bind(function (aFormValue) {
+ var formValueComponent;
+
+ formValueComponent = new Clipperz.PM.UI.Web.Components.DirectLoginEditingFormValueComponent({
+ 'formFieldName': aFormValue.key(),
+ 'fieldOptions': aFormValue.fieldOptions(),
+ 'initialValue': aFormValue.value()
+ });
+
+ this.formValueComponents().push(formValueComponent);
+
+ MochiKit.Signal.connect(formValueComponent, 'formValueChange', this, 'handleFormValueChange', formValueComponent);
+ this.directLoginEditingComponent().addFormValueComponent(formValueComponent);
+ }, this))
+
+ ], {trace:false});
+
+ break;
+ case 'FAVICON':
+ break;
+ case 'DONE':
+ this.directLoginEditingComponent().setDoneDescriptionWithKeys({
+ '__cardName__': this.cardLabel(),
+ '__directLoginName__': this.directLoginEditingComponent().label()
+ });
+ break;
+ };
+
+ this.rulerComponent().moveForward(afterMoveAction);
+ };
+ },
+
+ 'handleCursorMoved': function () {
+ this.checkState();
+ this.setFocus();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleChangedValue': function (anEvent) {
+ this.checkState();
+ },
+
+ //.........................................................................
+
+ 'handleBindChange': function (aDirectLoginEditingBindingComponent) {
+ var selectedField;
+
+ selectedField = this.recordFieldWithReference(aDirectLoginEditingBindingComponent.selectedValue());
+
+ return Clipperz.Async.callbacks("DirectLoginWizardController.handleBindChange", [
+ MochiKit.Base.method(this.directLogin(), 'bindings'),
+ MochiKit.Base.itemgetter(aDirectLoginEditingBindingComponent.formFieldName()),
+ MochiKit.Base.methodcaller('setFieldKey', selectedField['reference']),
+ function () {
+ if (selectedField != null) {
+ aDirectLoginEditingBindingComponent.setFieldValue(selectedField['value']);
+ aDirectLoginEditingBindingComponent.setIsHidden(selectedField['isHidden']);
+ } else {
+ aDirectLoginEditingBindingComponent.setFieldValue('');
+ aDirectLoginEditingBindingComponent.setIsHidden(false);
+ }
+ },
+ MochiKit.Base.method(this, 'checkState')
+ ], {trace:false});
+ },
+
+ //.........................................................................
+
+ 'handleFormValueChange': function (someOptions) {
+ return Clipperz.Async.callbacks("DirectLoginWizardController.handleFormValueChange", [
+ MochiKit.Base.method(this.directLogin(), 'formValues'),
+ MochiKit.Base.itemgetter(someOptions['fieldName']),
+ MochiKit.Base.methodcaller('setValue', someOptions['selectedValue']),
+ MochiKit.Base.method(this, 'checkState')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleDirectLoginEditingComponentKeyPressed': function (anEvent) {
+ if (anEvent.key().string == 'KEY_ENTER') {
+ if (anEvent.target().nodeName != 'TEXTAREA') {
+ anEvent.preventDefault();
+ this.handleMoveForward();
+ }
+ } else if (anEvent.key().string == 'KEY_TAB') {
+ this.handleMoveForward();
+ if ((anEvent.target().nodeName == 'INPUT') || (anEvent.target().nodeName == 'TEXTAREA')) {
+ anEvent.preventDefault();
+ }
+ } else if ((anEvent.key().string == 'KEY_ARROW_RIGHT') && (anEvent.modifier().meta == true)) {
+ this.handleMoveForward();
+ } else if ((anEvent.key().string == 'KEY_ARROW_LEFT') && (anEvent.modifier().meta == true)) {
+ this.handleMoveBackward();
+ } else if (anEvent.key().string == 'KEY_ESCAPE') {
+ anEvent.stop();
+ this.handleExit();
+ }
+ },
+
+ //=============================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginsController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginsController.js
new file mode 100644
index 0000000..28401a2
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/DirectLoginsController.js
@@ -0,0 +1,145 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+/*
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.DirectLoginsController = function() {
+ Clipperz.PM.UI.Web.Controllers.DirectLoginsController.superclass.constructor.apply(this, arguments);
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Controllers.DirectLoginsController, Clipperz.PM.UI.Web.Controllers.GridController, {
+
+ 'createGrid': function () {
+ return new Clipperz.PM.UI.Web.Components.GridComponent({columnsManagers: [
+ new Clipperz.PM.UI.Web.Components.FaviconColumnManager({
+ 'name': 'DirectLogins.favicon',
+ 'selector': MochiKit.Base.methodcaller('favicon'),
+ 'cssClass': 'favicon'
+ }),
+// new Clipperz.PM.UI.Web.Components.LinkColumnManager({
+ new Clipperz.PM.UI.Web.Components.DirectLoginColumnManager({
+ 'name': 'DirectLogins.title',
+ 'selector': MochiKit.Base.methodcaller('label'),
+ 'label': 'title',
+ 'cssClass': 'title',
+ 'comparator': Clipperz.Base.caseInsensitiveCompare,
+ 'sortable': true,
+ 'sorted': 'ASCENDING',
+ 'actionMethod': MochiKit.Base.methodcaller('runDirectLogin')
+ }),
+// new Clipperz.PM.UI.Web.Components.TextColumnManager({ //should be StrengthColumnManager
+// 'label': 'strength',
+// 'cssClass': 'title',
+// 'selector': MochiKit.Base.methodcaller('label') //should be 'strength' or a strenght evaluation function
+// }),
+ new Clipperz.PM.UI.Web.Components.LinkColumnManager({
+ 'name': 'DirectLogins.cardTitle',
+ 'selector': MochiKit.Base.compose(MochiKit.Base.methodcaller('label'), MochiKit.Base.methodcaller('record')),
+ 'label': 'card',
+ 'cssClass': 'cardTitle',
+ 'comparator': Clipperz.Base.caseInsensitiveCompare,
+ 'sortable': true,
+ 'sorted': 'UNSORTED',
+ 'actionMethod': MochiKit.Base.method(this, 'handleShowCard')
+ }),
+// new Clipperz.PM.UI.Web.Components.TextColumnManager({ //should be StrengthColumnManager
+// 'label': 'last access',
+// 'cssClass': 'title',
+// 'selector': MochiKit.Base.methodcaller('label')
+// // 'sortable': true,
+// // 'sorted': 'UNSORTED'
+// }),
+// new Clipperz.PM.UI.Web.Components.TextColumnManager({
+// 'label': 'commands',
+// 'cssClass': 'title',
+// 'selector': MochiKit.Base.methodcaller('label'), //should be a function for commands display
+// }),
+ new Clipperz.PM.UI.Web.Components.DeleteObjectColumnManager({
+ 'name': 'DirectLogins.delete',
+ 'selector': MochiKit.Base.noop,
+ 'cssClass': 'delete',
+// 'actionMethod': function(anObject, anEvent) { MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'deleteDirectLogin', {objectData:anObject, element:anEvent.src()})}
+ 'actionMethod': MochiKit.Base.method(this, 'handleDeleteDirectLogin')
+ })
+ ]});
+
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'getRows': function () {
+ // TODO: relying on user() in GridController, bad code smell :|
+ return this.user().getDirectLogins();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleShowCard': function (anObject, anEvent) {
+ var cardDialogController;
+
+ cardDialogController = new Clipperz.PM.UI.Web.Controllers.CardDialogController({record:anObject.record()})
+ cardDialogController.run(anEvent.src());
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleDeleteDirectLogin': function (anObject, anEvent) {
+ var deferredResult;
+ var confirmationDialog;
+
+ confirmationDialog = new Clipperz.PM.UI.Common.Components.SimpleMessagePanel({
+ title: "Delete DirectLogin",
+ text: "Do you want to delete …",
+ type: 'ALERT',
+ buttons: [
+ {text:"Cancel", result:'CANCEL', isDefault:true},
+ {text:"Delete", result:'OK'}
+ ]
+ });
+
+ deferredResult = new Clipperz.Async.Deferred("AppController.handleDeleteCard", {trace:false});
+// deferredResult = confirmationDialog.deferredShow({openFromElement:anEvent.src(), onOkCloseToElement:MochiKit.DOM.currentDocument().body, onCancelCloseToElement:anEvent.src()});
+ deferredResult.addMethod(confirmationDialog, 'deferredShow', {
+ 'openFromElement': anEvent.src(),
+ 'onOkCloseToElement': null, // MochiKit.DOM.currentDocument().body,
+ 'onCancelCloseToElement': anEvent.src()
+ });
+ deferredResult.addCallback(function () { Clipperz.log("DELETE: " + anObject.toString(), anObject); });
+ deferredResult.addErrbackPass(function () { Clipperz.log("skip deletion: " + anObject.toString(), anObject); });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+*/ \ No newline at end of file
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/FilterController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/FilterController.js
new file mode 100644
index 0000000..13e02bc
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/FilterController.js
@@ -0,0 +1,158 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.FilterController = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Controllers.FilterController.superclass.constructor.call(this, args);
+
+ this._filterElements = [];
+ this._filter = "";
+
+ this._pendingSearchClicks = 0;
+
+ return this;
+};
+
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Controllers.FilterController, Object, {
+
+ //-----------------------------------------------------------------------------
+
+ 'getFilter': function () {
+ return this._filter;
+ },
+
+ '_setFilter': function (aFilterElement, aFilter) {
+ if (aFilter != this._filter) {
+ this._filter = aFilter;
+ MochiKit.Signal.signal(this, 'filterUpdated', aFilter);
+ this.updateFilterElements(aFilterElement, aFilter);
+ }
+ },
+
+ 'setFilter': function (aFilter) {
+ this._setFilter(null, aFilter);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'filterElements': function () {
+ return this._filterElements;
+ },
+
+ 'registerFilterElement': function (aFilterElement) {
+//Clipperz.log("=== FilterController.registerFilterElement", aFilterElement);
+ this._filterElements.push(aFilterElement);
+ MochiKit.Signal.connect(aFilterElement, 'onkeydown', this, 'searchClickHandler');
+ MochiKit.Signal.connect(aFilterElement, 'onfocus', this, 'searchClickHandler');
+ },
+
+ 'removeFilterElement': function (aFilterElement) {
+ var i;
+ var filterElements;
+ for (i=0; i < filterElements; i++) {
+ if (filterElements[i] == aFilterElement);
+ filterElements.splice(i, 1);
+// TODO unregister/disconnect filterElement ?? MochiKit.Signal.disconnect(this.grid().filterElement(), 'updateFilter', this.filterController(), 'handleUpdateFilter');
+ }
+ },
+
+ 'updateFilterElements': function (aSourceElement, aFilterString) {
+ MochiKit.Iter.forEach(this.filterElements(),
+ function (aFilterElement) {
+ if (aFilterElement != aSourceElement) {
+ aFilterElement.value = aFilterString;
+ }
+ }
+ );
+
+ if (aSourceElement != null) {
+ aSourceElement.focus();
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'run': function () {
+//Clipperz.log("=== FilterController.run");
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'pendingSearchClicks': function () {
+ return this._pendingSearchClicks;
+ },
+
+ 'incrementPendingSearchClicks': function () {
+ this._pendingSearchClicks++;
+ },
+
+ 'decrementPendingSearchClicks': function () {
+ this._pendingSearchClicks--;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'searchClickHandler': function (anEvent) {
+ if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ENTER')) {
+ anEvent.preventDefault();
+ } else {
+ var value;
+
+ if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ESCAPE')) {
+ value = ""
+ } else if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ARROW_UP')) {
+ } else if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ARROW_DOWN')) {
+ } else {
+ value = null;
+ }
+
+ this.incrementPendingSearchClicks();
+ MochiKit.Async.callLater(0.1, MochiKit.Base.method(this, "searchClickDeferredHandler", anEvent.src(), value));
+ }
+ },
+
+ //.........................................................................
+
+ 'searchClickDeferredHandler': function (aFilterElement, aValue) {
+ if (aValue != null) {
+ aFilterElement.value = aValue;
+ }
+
+ this.decrementPendingSearchClicks();
+ if (this.pendingSearchClicks()==0) {
+ this._setFilter(aFilterElement, aFilterElement.value);
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+ 'syntaxFix': 'syntax fix'
+}); \ No newline at end of file
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js
new file mode 100644
index 0000000..740a091
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/GridController.js
@@ -0,0 +1,374 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.GridController = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.Web.Controllers.GridController.superclass.constructor.call(this, args);
+
+ this._grid = null;
+ this._user = null;
+ this._sortedColumnManager = null;
+ this._cachedObjects = null;
+ this._filterController = args.filterController || null;
+
+ this._deferredDisplaySelectedRowsInvocation = null;
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.PM.UI.Web.Controllers.GridController, Object, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.GridController";
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'createGrid': function () {
+ throw Clipperz.Base.exception.AbstractMethod;
+ },
+
+ 'setupWithGrid': function (aGrid) {
+ this._grid = aGrid;
+
+ if (this._grid != null) {
+ MochiKit.Iter.forEach(this.columnsManagers(), function (aColumnManager) {
+ if (aColumnManager.isSortable()) {
+ if (aColumnManager.isSorted()) {
+ this.setSortedColumnManager(aColumnManager);
+ }
+ MochiKit.Signal.connect(aColumnManager, 'sort', this, 'handleColumnManagerSort');
+ }
+ MochiKit.Signal.connect(aColumnManager, 'selectRow', this, 'handleColumnManagerSelectRow');
+ MochiKit.Signal.connect(aColumnManager, 'unselectRow', this, 'handleColumnManagerUnselectRow');
+ }, this);
+ }
+ },
+
+ 'grid': function() {
+ if (this._grid == null) {
+ this.setupWithGrid(this.createGrid());
+ }
+
+ return this._grid;
+ },
+
+ 'filterController': function () {
+//Clipperz.log('GridController.filterController >>>', this._filterController);
+ if (this._filterController == null) {
+ this._filterController = new Clipperz.PM.UI.Web.Controllers.FilterController();
+ }
+//Clipperz.log('GridController.filterController <<<', this._filterController);
+ return this._filterController;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'columnsManagers': function () {
+ return this.grid().columnsManagers();
+ },
+
+ 'columnManagerWithName': function (aName) {
+ var managers;
+ var result;
+
+ managers = MochiKit.Base.filter(function (aManager) { return aManager.name() == aName; } , this.columnsManagers());
+
+ if (managers.length == 1) {
+ result = managers[0];
+ } else if (managers.length == 0) {
+ result = null;
+ } else {
+ throw "WTF!!!";
+ }
+
+ return result;
+ },
+
+ 'sortedColumnManager': function () {
+ return this._sortedColumnManager;
+ },
+
+ 'setSortedColumnManager': function(aValue) {
+ if (aValue.sorted() != 'UNSORTED') {
+ this._sortedColumnManager = aValue;
+ } else {
+ this._sortedColumnManager = null;
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleColumnManagerSort': function(aSelectedColumnManager) {
+ MochiKit.Iter.forEach(this.columnsManagers(), function(aColumnManager) {
+ if (aSelectedColumnManager != aColumnManager) {
+ if (aColumnManager.isSortable()) {
+ aColumnManager.setSorted('UNSORTED');
+ }
+ }
+ });
+
+ aSelectedColumnManager.toggleSorting();
+ this.setSortedColumnManager(aSelectedColumnManager);
+
+ this.displaySelectedRows(this.filterController().getFilter());
+ },
+
+ 'handleColumnManagerSelectRow': function (aRowObject) {
+ this.grid().selectRow(aRowObject);
+ },
+
+ 'handleColumnManagerUnselectRow': function (aRowObject) {
+ this.grid().unselectRow(aRowObject);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleFilterUpdated': function (aFilter) {
+ if (this.grid().isActive()) {
+ this.displaySelectedRows(aFilter);
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+ // TODO: relying on user() in GridController, bad code smell :|
+ // mhh: a controller should have access to business logic object too. Otherwise it will fail its controller role. [Giulio Cesare]
+
+ 'setUser': function(anUser) {
+ this._user = anUser;
+ },
+
+ 'user': function() {
+ return this._user;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'run': function(args) {
+//Clipperz.log("=== GridController.run");
+ var deferredResult;
+
+ this.setUser(args.user);
+ args.slot.setContent(this.grid());
+ this.filterController().registerFilterElement(this.grid().filterElement());
+ MochiKit.Signal.connect(this.filterController(), 'filterUpdated', this, 'handleFilterUpdated');
+
+ return this.displaySelectedRows();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleGenericError': function(anError) {
+ var result;
+
+ if (anError instanceof MochiKit.Async.CancelledError) {
+ result = anError;
+ } else {
+Clipperz.log("## GridController - GENERIC ERROR" + "\n" + "==>> " + anError + " <<==\n" + anError.stack);
+ result = new MochiKit.Async.CancelledError(anError);
+ }
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'getRows': function () {
+ throw Clipperz.Base.AbstractMethod;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'setDeferredDisplaySelectedRowsInvocation': function (aDeferred) {
+ if (this._deferredDisplaySelectedRowsInvocation != null) {
+ this._deferredDisplaySelectedRowsInvocation.cancel();
+ }
+
+ this._deferredDisplaySelectedRowsInvocation = aDeferred;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'resetDeferredDisplaySelectedRowsInvocation': function () {
+ if (this._deferredDisplaySelectedRowsInvocation != null) {
+ this._deferredDisplaySelectedRowsInvocation.cancel();
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ '_displaySelectedRows': function (aFilter, someRows) {
+ var result;
+ var delay;
+
+ if ((aFilter != null) && (aFilter != '')) {
+ var filter;
+ var filterRegExp;
+
+ filter = aFilter.replace(/[^A-Za-z0-9]/g, "\\$&");
+ filterRegExp = new RegExp(filter, "i");
+ result = MochiKit.Base.filter(function (aCachedResult) { return filterRegExp.test(aCachedResult['_searchableContent'])}, someRows);
+ delay = 0.002*result.length;
+
+ this.setDeferredDisplaySelectedRowsInvocation(MochiKit.Async.callLater(delay, MochiKit.Base.method(this, "deferredDisplaySelectedRows", result)));
+ } else {
+ result = someRows;
+
+ this.resetDeferredDisplaySelectedRowsInvocation();
+ this.deferredDisplaySelectedRows(result);
+ }
+
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'deferredDisplaySelectedRows': function (someRows) {
+ if (this.sortedColumnManager() != null) {
+ var comparator;
+ var fieldName;
+
+ fieldName = this.sortedColumnManager().name();
+ comparator = this.sortedColumnManager().comparator();
+ if (this.sortedColumnManager().sorted() == 'DESCENDING') {
+ comparator = Clipperz.Base.reverseComparator(comparator);
+ }
+
+ someRows.sort(MochiKit.Base.partial(function(aKey, aComparator, aObject, bObject){
+ return comparator(aObject[aKey], bObject[aKey]);
+ }, this.sortedColumnManager().name(), comparator));
+ }
+
+ this.grid().update(someRows);
+ this.grid().endSearch();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'getCachedValues': function () {
+ var deferredResult;
+
+ if (this._cachedObjects != null) {
+ deferredResult = MochiKit.Async.succeed(this._cachedObjects);
+ } else {
+ var objectCollectResultsConfiguration;
+
+ objectCollectResultsConfiguration = {
+ '_rowObject': MochiKit.Async.succeed,
+ '_reference': MochiKit.Base.methodcaller('reference'),
+ '_searchableContent': MochiKit.Base.methodcaller('searchableContent')
+ };
+
+ MochiKit.Base.map(function (aColumnManager) {
+ objectCollectResultsConfiguration[aColumnManager.name()] = aColumnManager.selector();
+ }, this.columnsManagers());
+
+ deferredResult = new Clipperz.Async.Deferred("GridController.getCachedValues", {trace:false});
+ deferredResult.addMethod(this, 'getRows');
+ deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("GridController.getCachedValues - collectResults", objectCollectResultsConfiguration, {trace:false}));
+ deferredResult.addCallback(Clipperz.Async.collectAll);
+ deferredResult.addCallback(MochiKit.Base.bind(function (someRows) {
+ this._cachedObjects = someRows;
+ return this._cachedObjects;
+ }, this));
+ deferredResult.callback();
+ }
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'hasPendingChanges': function () {
+ return this.user().hasPendingChanges();
+ },
+
+ 'saveChanges': function () {
+ this._cachedObjects = null;
+
+ return Clipperz.Async.callbacks("GridController.saveChanges", [
+ MochiKit.Base.method(this.user(), 'saveChanges'),
+ MochiKit.Base.method(this, 'focus')
+ ], {trace:false});
+ },
+
+ 'revertChanges': function () {
+ return this.user().revertChanges();
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'displayEmptyContent': function () {
+ },
+
+ 'hideEmptyContent': function () {
+ this.grid().removeNoRowsGridComponent();
+ },
+
+ 'displaySelectedRows': function (aFilter) {
+ if ((aFilter != null) && (aFilter != '')){
+ this.grid().startSearch();
+ }
+
+ return Clipperz.Async.callbacks("GridController.displaySelectedrows", [
+ MochiKit.Base.method(this, 'getCachedValues'),
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.deferredIf("There are some items to show in the grid", [
+ MochiKit.Base.method(this, 'hideEmptyContent'),
+ MochiKit.Base.method(this, 'getCachedValues'),
+ MochiKit.Base.method(this, '_displaySelectedRows', aFilter)
+ ], [
+ MochiKit.Base.method(this, 'displayEmptyContent'),
+ MochiKit.Base.method(this.grid(), 'endSearch')
+ ])
+ ], {trace:false});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'focus': function () {
+ return Clipperz.Async.callbacks("GridController.focus", [
+ MochiKit.Base.method(this, 'displaySelectedRows', this.filterController().getFilter()),
+ MochiKit.Base.method(this.grid(), 'focus')
+ ], {trace:false})
+//*##*/ this.displaySelectedRows(this.filterController().getFilter());
+// this.grid().focus();
+ },
+
+ //=============================================================================
+
+ 'deleteAllCleanTextData': function () {
+ this._cachedObjects = null;
+ this.grid().drawEmpty();
+ },
+
+ //=============================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/LoginController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/LoginController.js
new file mode 100644
index 0000000..d88af41
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/LoginController.js
@@ -0,0 +1,259 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.LoginController = function(args) {
+ this._args = args || {};
+
+ this._loginPage = null;
+
+ this._newUserWizardController = null;
+ this._newUserCreationComponent = null;
+
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.Web.Controllers.LoginController.prototype, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.LoginController";
+ },
+
+ 'args': function () {
+ return this._args;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'loginPage': function() {
+ if (this._loginPage == null) {
+ this._loginPage = new Clipperz.PM.UI.Web.Components.LoginPage();
+
+ MochiKit.Signal.connect(this._loginPage, 'createNewAccountClick', this, 'handleCreateNewAccountClick')
+ }
+
+ return this._loginPage;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'run': function(args) {
+ var slot;
+ var loginPage;
+ var loginForm;
+
+ slot = args.slot;
+
+ loginForm = new Clipperz.PM.UI.Web.Components.LoginForm({'autocomplete': this.args()['autocomplete']});
+
+ slot.setContent(this.loginPage());
+ this.loginPage().slotNamed('loginForm').setContent(loginForm);
+
+ MochiKit.Signal.connect(loginForm, 'doLogin', MochiKit.Base.method(this, 'doLogin', loginForm));
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'doLogin', MochiKit.Base.method(this, 'doLogin', loginForm));
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'doLogin': function(aLoginForm, anEvent) {
+ var deferredResult;
+ var parameters;
+// var shouldUseOTP;
+ var loginProgress;
+ var user;
+ var getPassphraseDelegate;
+
+ parameters = anEvent;
+// shouldUseOTP = (typeof(parameters.passphrase) == 'undefined');
+
+ getPassphraseDelegate = MochiKit.Base.partial(MochiKit.Async.succeed, parameters.passphrase);
+ user = new Clipperz.PM.DataModel.User({'username':parameters.username, 'getPassphraseFunction':MochiKit.Base.method(Clipperz.PM.RunTime.mainController, 'getPassphrase')});
+
+ loginProgress = new Clipperz.PM.UI.Web.Components.LoginProgress();
+
+ deferredResult = new Clipperz.Async.Deferred("LoginController.doLogin", {trace:false});
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress', {'steps':4});
+ deferredResult.addMethod(Clipperz.PM.RunTime.mainController, 'setPassphraseDelegate', getPassphraseDelegate);
+ deferredResult.addMethod(loginProgress, 'deferredShowModal', {deferredObject:deferredResult, openFromElement:aLoginForm.submitButtonElement()});
+ deferredResult.addMethod(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'deferredEntropyCollection');
+// if (shouldUseOTP == false) {
+ deferredResult.addMethod(user, 'login');
+// } else {
+// deferredResult.addMethod(user, 'loginUsingOTP', parameters.username, parameters.otp);
+// }
+ deferredResult.addCallback(function(aLoginProgress, res) {
+ aLoginProgress.disableCancel();
+ return res;
+ }, loginProgress);
+ deferredResult.addCallback(function () {
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'CARDS_CONTROLLER_DID_RUN', MochiKit.Base.method(loginProgress, 'deferredHideModalAndRemove', {closeToElement:MochiKit.DOM.currentDocument().body}));
+ })
+ deferredResult.addMethod(this, 'userLoggedIn', user, loginProgress, aLoginForm);
+ deferredResult.addErrback (MochiKit.Base.method(this, 'handleFailedLogin', loginProgress));
+
+ deferredResult.addErrback (MochiKit.Base.method(loginProgress, 'deferredHideModalAndRemove', {closeToElement:aLoginForm.submitButtonElement()}));
+ deferredResult.addErrbackPass (MochiKit.Base.method(aLoginForm, 'focusOnPassphraseField'));
+ deferredResult.addBoth(MochiKit.Base.method(Clipperz.PM.RunTime.mainController, 'removePassphraseDelegate', getPassphraseDelegate));
+ deferredResult.callback();
+
+ MochiKit.Signal.connect(loginProgress, 'cancelEvent', deferredResult, 'cancel');
+
+ return deferredResult;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'userLoggedIn': function(aUser) {
+//Clipperz.log(">>> LoginController.userLoggedIn");
+ MochiKit.Signal.signal(this, 'userLoggedIn', {user: aUser});
+//Clipperz.log("<<< LoginController.userLoggedIn");
+ },
+
+ //=========================================================================
+
+ 'handleCreateNewAccountClick': function (aComponent) {
+// return Clipperz.PM.DataModel.User.registerNewAccount("new", "user");
+ return Clipperz.Async.callbacks("LoginController.handleCreateNewAccountClick", [
+//' MochiKit.Base.method(this, 'newUserCreationComponent'),
+// MochiKit.Base.methodcaller('deferredShowModal', {openFromElement:aComponent}),
+// MochiKit.Base.method(this.newUserWizardController(), 'run')
+
+
+ MochiKit.Base.method(this, 'newUserCreationComponent'),
+ Clipperz.Async.forkAndJoin("Async.test succeedingForkedAndWaitDeferrer", [
+ MochiKit.Base.method(this.newUserCreationComponent(), 'deferredShowModal', {openFromElement:aComponent, duration:0.5}),
+ MochiKit.Base.method(this.newUserWizardController(), 'run')
+ ], {trace:false}),
+// MochiKit.Base.method(this.newUserCreationComponent(), 'enableCredentialsField')
+ ], {trace:false});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'newUserWizardController': function () {
+ if (this._newUserWizardController == null) {
+ this._newUserWizardController = new Clipperz.PM.UI.Web.Controllers.NewUserWizardController({
+ 'newUserCreationComponent': this.newUserCreationComponent()
+ })
+
+// MochiKit.Signal.connect(this._newUserWizardController, 'exit', this, 'handleHideNewUserCreationComponent');
+ MochiKit.Signal.connect(this._newUserWizardController, 'done', this, 'handleCompleteNewUserCreationComponent');
+ }
+
+ return this._newUserWizardController;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'newUserCreationComponent': function () {
+ if (this._newUserCreationComponent == null) {
+ this._newUserCreationComponent = new Clipperz.PM.UI.Web.Components.NewUserCreationComponent();
+ }
+
+ return this._newUserCreationComponent;
+ },
+
+ 'clearNewUserCreationComponent': function () {
+ if (this._newUserCreationComponent != null) {
+ this._newUserCreationComponent.clear();
+ }
+ this._newUserCreationComponent = null;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleHideNewUserCreationComponent': function () {
+ this.clearNewUserCreationComponent();
+ },
+
+ 'handleCompleteNewUserCreationComponent': function (someParameters) {
+ var deferredResult;
+ var user;
+ var newUserCreationComponent;
+
+ user = someParameters.user;
+ newUserCreationComponent = this.newUserCreationComponent();
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'CARDS_CONTROLLER_DID_RUN', MochiKit.Base.method(newUserCreationComponent, 'deferredHideModal', {closeToElement:MochiKit.DOM.currentDocument().body})),
+
+ deferredResult = new Clipperz.Async.Deferred("LoginController.handleCompleteNewUserCreationComponent", {trace:false});
+
+ deferredResult.addCallbackList([
+ MochiKit.Base.method(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'deferredEntropyCollection'),
+ MochiKit.Base.method(user, 'login'),
+ MochiKit.Base.method(this, 'userLoggedIn', user),
+ MochiKit.Base.method(this, 'clearNewUserCreationComponent')
+ ]);
+ deferredResult.addErrback(function (aValue) { Clipperz.log("WTF!! Error doing the login after creating a new user" + aValue)});
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+
+ //=========================================================================
+
+ 'handleFailedLogin': function(aLoginProgress, anError) {
+ var result;
+
+//console.log("anError", anError);
+ if (anError instanceof MochiKit.Async.CancelledError) {
+ result = anError;
+ } else {
+ var deferredResult;
+
+MochiKit.Logging.logError("## MainController - FAILED LOGIN: " + anError);
+ deferredResult = new MochiKit.Async.Deferred();
+
+ aLoginProgress.showErrorMessage("failed login");
+// Clipperz.NotificationCenter.register(loginProgress, 'cancelEvent', deferredResult, 'callback');
+ MochiKit.Signal.connect(aLoginProgress, 'cancelEvent', deferredResult, 'callback');
+ deferredResult.addCallback(MochiKit.Async.fail, anError)
+ result = deferredResult;
+ }
+
+ return result;
+ },
+
+ 'handleGenericError': function(anError) {
+ var result;
+
+ if (anError instanceof MochiKit.Async.CancelledError) {
+ result = anError;
+ } else {
+MochiKit.Logging.logError("## MainController - GENERIC ERROR" + "\n" + "==>> " + anError + " <<==\n" + anError.stack);
+//console.log(anError);
+ result = new MochiKit.Async.CancelledError(anError);
+ }
+
+ return result;
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/MainController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/MainController.js
new file mode 100644
index 0000000..aa0d6ad
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/MainController.js
@@ -0,0 +1,218 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.MainController = function(args) {
+ this._args = args;
+
+ // controllers
+ this._loginController = null;
+ this._appController = null;
+
+ // components
+ this._headerComponent = null;
+ this._pageComponent = null;
+ this._footerComponent = null;
+
+ this._passphraseDelegateLock = new MochiKit.Async.DeferredLock();
+ this._passphraseDelegateLock.acquire();
+//Clipperz.log('MainController init _passphraseDelegateLock', this._passphraseDelegateLock);
+ this._passphraseDelegate = null;
+
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'remoteRequestSent', this, 'handleRemoteRequestSent');
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'remoteRequestReceived', this, 'handleRemoteRequestReceived');
+
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.Web.Controllers.MainController.prototype, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.MainController";
+ },
+
+ 'args': function () {
+ return this._args;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'headerComponent': function() {
+ if (this._headerComponent == null) {
+ this._headerComponent = new Clipperz.PM.UI.Web.Components.PageHeader();
+ }
+
+ return this._headerComponent;
+ },
+
+ 'footerComponent': function() {
+ if (this._footerComponent == null) {
+ this._footerComponent = new Clipperz.PM.UI.Web.Components.PageFooter();
+ }
+
+ return this._footerComponent;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'pageComponent': function() {
+ if (this._pageComponent == null) {
+ this._pageComponent = new Clipperz.PM.UI.Web.Components.Page({element:MochiKit.DOM.getElement('mainDiv')});
+ }
+
+ return this._pageComponent;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'loginController': function() {
+ if (this._loginController == null) {
+ this._loginController = new Clipperz.PM.UI.Web.Controllers.LoginController(this.args());
+
+ MochiKit.Signal.connect(this._loginController, 'userLoggedIn', this, 'loginControllerUserLoggedInCallback');
+ }
+
+ return this._loginController;
+ },
+
+ 'appController': function() {
+ if (this._appController == null) {
+ this._appController = new Clipperz.PM.UI.Web.Controllers.AppController();
+
+ MochiKit.Signal.connect(this._appController, 'logout', this, 'handleLogout');
+ }
+
+ return this._appController;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'run': function(shoudShowRegistrationForm) {
+ this.pageComponent().slotNamed('header').setContent(this.headerComponent());
+ this.pageComponent().slotNamed('footer').setContent(this.footerComponent());
+
+ this.pageComponent().render();
+
+ this.loginController().run({slot:this.pageComponent().slotNamed('body')});
+
+ if (shoudShowRegistrationForm) {
+ MochiKit.Signal.signal(this.loginController().loginPage(), 'createNewAccountClick');
+// this.loginController().handleCreateNewAccountClick();
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'getPassphrase': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("MainController.getPassphrase", {trace:false});
+
+ deferredResult.acquireLock(this._passphraseDelegateLock);
+ deferredResult.addMethod(this, 'invokePassphraseDelegate');
+ deferredResult.releaseLock(this._passphraseDelegateLock);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //.........................................................................
+
+ 'invokePassphraseDelegate': function () {
+ return this._passphraseDelegate();
+ },
+
+ 'passphraseDelegateLock': function () {
+ return this._passphraseDelegateLock;
+ },
+
+ //.........................................................................
+
+ 'setPassphraseDelegate': function (aDelegate) {
+ var shouldReleaseLock;
+
+ shouldReleaseLock = (this._passphraseDelegate == null);
+
+ this._passphraseDelegate = aDelegate;
+
+ if (shouldReleaseLock) {
+ this._passphraseDelegateLock.release();
+ }
+ },
+
+ //.........................................................................
+
+ 'removePassphraseDelegate': function (aDelegate) {
+ if (this._passphraseDelegate == aDelegate) {
+ this._passphraseDelegate = null;
+ this._passphraseDelegateLock.acquire();
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'loginControllerUserLoggedInCallback': function(anEvent) {
+//Clipperz.log(">>> loginControllerUserLoggedInCallback", anEvent);
+// this.setUser(anEvent.parameters()['user']);
+//console.log("--- loginControllerUserLoggedInCallback - 1");
+
+//console.log("--- loginControllerUserLoggedInCallback - 2");
+ this.headerComponent().switchToLoggedMode();
+ this.appController().run({slot:this.pageComponent().slotNamed('body'), user:anEvent['user']});
+//Clipperz.log("<<< loginControllerUserLoggedInCallback");
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleRemoteRequestSent': function () {
+//Clipperz.log("REMOTE REQUEST sent >>>");
+ },
+
+ 'handleRemoteRequestReceived': function () {
+//Clipperz.log("REMOTE REQUEST received <<<");
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleLogout': function(anEvent) {
+ this.exit('logout.html');
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'exit': function(aPageName) {
+//Clipperz.log("### exit " + aPageName);
+ MochiKit.Async.wait(0).addCallback(function() {
+ window.location.href = "./" + aPageName + "?ln=" + Clipperz.PM.Strings.selectedLanguage;
+ });
+ },
+
+ //-----------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/NewUserWizardController.js b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/NewUserWizardController.js
new file mode 100644
index 0000000..28d9d20
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/Web/Controllers/NewUserWizardController.js
@@ -0,0 +1,469 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.Web.Controllers');
+
+Clipperz.PM.UI.Web.Controllers.NewUserWizardController = function(args) {
+ this._newUserCreationComponent = args.newUserCreationComponent || Clipperz.Base.exception.raise('MandatoryParameter');
+
+ MochiKit.Signal.connect(this._newUserCreationComponent, 'changedValue', this, 'handleChangedValue');
+ MochiKit.Signal.connect(this._newUserCreationComponent, 'moveForward', this, 'handleMoveForward');
+ MochiKit.Signal.connect(this._newUserCreationComponent, 'keyPressed', this, 'handleNewUserCreationComponentKeyPressed');
+
+ this._rulerComponent = null;
+
+ this._steps = null;
+ this._currentStepIndex = 0;
+ this._isNextEnabled = false;
+
+ this._userCreationState = 'IDLE'; // 'IN PROGRESS', 'DONE', 'FAILED'
+ this._user = null;
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.Web.Controllers.NewUserWizardController.prototype, {
+
+ 'toString': function() {
+ return "Clipperz.PM.UI.Web.Controllers.NewUserWizardController";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'newUserCreationComponent': function () {
+ return this._newUserCreationComponent;
+ },
+
+ //=============================================================================
+
+ 'user': function () {
+ return this._user;
+ },
+
+ 'setUser': function (aValue) {
+ this._user = aValue;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'userCreationState': function () {
+ return this._userCreationState;
+ },
+
+ 'setUserCreationState': function (aValue) {
+//console.log("+++ NewUserWizardController.setUserCreationState", aValue);
+ this._userCreationState = aValue;
+ this.checkState();
+ },
+
+ //=============================================================================
+
+ 'resetCurrentStepIndex': function () {
+ this._currentStepIndex = 0;
+ this.rulerComponent().resetStatus({animateTransition:true});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'enableNext': function (aValue) {
+ this.rulerComponent().enableNext(aValue);
+ this._isNextEnabled = aValue;
+ },
+
+ 'isNextEnabled': function () {
+ return this._isNextEnabled;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'enablePrevious': function (aValue) {
+ this.rulerComponent().enablePrevious(aValue);
+ },
+
+ //=============================================================================
+
+ 'rulerComponent': function () {
+ if (this._rulerComponent == null) {
+ this._rulerComponent = new Clipperz.PM.UI.Web.Components.RulerComponent({
+ translationContext:'Wizards.NewUserWizard'
+ });
+ this._rulerComponent.render();
+
+ MochiKit.Signal.connect(this._rulerComponent, 'exit', this, 'handleExit');
+ MochiKit.Signal.connect(this._rulerComponent, 'done', this, 'done');
+ MochiKit.Signal.connect(this._rulerComponent, 'moveForward', this, 'handleMoveForward');
+ MochiKit.Signal.connect(this._rulerComponent, 'moveBackward', this, 'handleMoveBackward');
+ MochiKit.Signal.connect(this._rulerComponent, 'cursorMoved', this, 'handleCursorMoved');
+ }
+
+ return this._rulerComponent;
+ },
+
+ 'resetRuler': function () {
+// if (this._rulerComponent != null) {
+// this._rulerComponent.clear();
+// }
+// this._rulerComponent = null;
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'showRuler': function (someSteps) {
+ var rulerElement;
+
+ this.setSteps(someSteps);
+
+ rulerElement = this.rulerComponent().element();
+ this.newUserCreationComponent().disableAllPanels();
+
+ MochiKit.Style.showElement(rulerElement);
+ MochiKit.Style.setElementPosition(rulerElement, {x:-1000, y:this.newUserCreationComponent().bottomMargin()});
+ new MochiKit.Visual.Move(rulerElement, {
+ x:0, y:this.newUserCreationComponent().bottomMargin(),
+ mode:'absolute',
+ duration:0.5,
+// afterFinish:MochiKit.Base.method(this, 'handleCursorMoved')
+ afterFinish:MochiKit.Base.method(this, 'handleRulerShowed')
+ });
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'handleRulerShowed':function () {
+ return Clipperz.Async.callbacks("NewUserWizardController.handlerRulerShowed", [
+ MochiKit.Base.method(this.newUserCreationComponent(), 'waitUntilFullyRendered'),
+ MochiKit.Base.method(this, 'handleCursorMoved')
+ ], {trace:false});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'hideRuler': function () {
+ new MochiKit.Visual.Move(this.rulerComponent().element(), {x:-1000, mode:'relative', duration:0.5});
+ },
+
+ 'doneWithRuler': function () {
+ var rulerComponentElement;
+
+ rulerComponentElement = this.rulerComponent().element();
+ new MochiKit.Visual.Move(this.rulerComponent().element(), {
+ x:1000,
+ mode:'relative',
+ duration:1,
+// afterFinish:MochiKit.Base.partial(MochiKit.Style.hideElement, rulerComponentElement)
+ afterFinish:function () { MochiKit.Style.hideElement(rulerComponentElement); }
+ });
+ },
+
+ //=============================================================================
+
+ 'createNewUserRulerSteps': function () {
+ return [ 'CREDENTIALS', 'CHECK_CREDENTIALS', 'TERMS_OF_SERVICE', 'CREATE_USER'/*, 'LOGIN' */];
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'run': function () {
+ return Clipperz.Async.callbacks("NewUserWizardController.run", [
+ MochiKit.Base.method(this, 'createNewUserRulerSteps'),
+ MochiKit.Base.method(this, 'showRuler')
+ ], {trace:false});
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'checkState': function () {
+ var enablePrevious;
+ var enableNext;
+
+ enablePrevious = true;
+ enableNext = false;
+
+ this.newUserCreationComponent().disableAllPanels();
+
+ switch(this.currentStep()) {
+ case 'CREDENTIALS':
+ this.newUserCreationComponent().enableCredentialsPanel();
+
+ enableNext = (
+ (this.newUserCreationComponent().username() != '')
+ &&
+ (this.newUserCreationComponent().passphrase() != '')
+ );
+// enablePrevious = false;
+ break;
+ case 'CHECK_CREDENTIALS':
+ this.newUserCreationComponent().enableCheckCredentialsPanel();
+
+ enableNext = (this.newUserCreationComponent().passphrase() == this.newUserCreationComponent().rePassphrase());
+// enablePrevious = true;
+ break
+ case 'TERMS_OF_SERVICE':
+ this.newUserCreationComponent().enableTermsOfServicePanel();
+
+//console.log("awareOfUnrecoverablePassphrase", this.newUserCreationComponent().awareOfUnrecoverablePassphrase());
+//console.log("readTermsOfService", this.newUserCreationComponent().readTermsOfService());
+ enableNext = (
+ (this.newUserCreationComponent().awareOfUnrecoverablePassphrase() == 'on')
+ &&
+ (this.newUserCreationComponent().readTermsOfService() == 'on')
+ )
+ break;
+ case 'CREATE_USER':
+//console.log(">>> CREATE_USER", this.userCreationState());
+ this.newUserCreationComponent().enableCreateUserPanel();
+
+ switch (this.userCreationState()) {
+ case 'IDLE':
+ this.setUserCreationState('IN PROGRESS');
+ this.preformActualUserRegistration();
+
+ enablePrevious = false;
+ enableNext = false;
+ break;
+ case 'IN PROGRESS':
+ enablePrevious = false;
+ enableNext = false;
+ break;
+ case 'DONE':
+ enablePrevious = false;
+ enableNext = true;
+ break;
+ case 'FAILED':
+ enablePrevious = true;
+ enableNext = false;
+ break;
+ };
+ break;
+// case 'LOGIN':
+// this.newUserCreationComponent().enableLoginPanel();
+// break;
+ }
+
+ if (this.currentStepIndex() > 0) {
+ this.enablePrevious(enablePrevious);
+ } else {
+ this.enablePrevious(false);
+ }
+ this.enableNext(enableNext);
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'setFocus': function () {
+ switch(this.currentStep()) {
+ case 'CREDENTIALS':
+ this.newUserCreationComponent().focusOnUsernameElement();
+ break;
+ case 'CHECK_CREDENTIALS':
+ this.newUserCreationComponent().focusOnRePassphraseElement();
+ break
+ case 'TERMS_OF_SERVICE':
+ break;
+ case 'CREATE_USER':
+ break;
+// case 'LOGIN':
+// break;
+ }
+ },
+
+ //=============================================================================
+
+ 'steps': function () {
+ return this._steps;
+ },
+
+ 'setSteps': function (aValue) {
+ this._steps = aValue;
+
+ this.rulerComponent().setSteps(aValue);
+ this.resetCurrentStepIndex();
+ },
+
+ 'currentStepIndex': function () {
+ return this._currentStepIndex;
+ },
+
+ 'currentStep': function () {
+ return this.steps()[this.currentStepIndex()];
+ },
+
+ //=============================================================================
+
+ 'handleExit': function () {
+ return Clipperz.Async.callbacks("NewUserWizardController.handleExit", [
+// MochiKit.Base.method(this.newUserCreationComponent(), 'resetContent'),
+ Clipperz.Async.forkAndJoin("NewUserWizardController.handleExit - fork and join", [
+ MochiKit.Base.method(this, 'hideRuler'),
+ MochiKit.Base.method(this.newUserCreationComponent(), 'deferredHideModal')
+ ], {trace:false}),
+ MochiKit.Base.method(this, 'resetRuler'),
+// MochiKit.Base.method(this.newUserCreationComponent(), 'reset'),
+ MochiKit.Base.partial(MochiKit.Signal.signal, this, 'exit')
+ ], {trace:false})
+ },
+
+ 'done': function () {
+ this.doneWithRuler();
+ MochiKit.Signal.signal(this, 'done', {'user': this.user()});
+ },
+
+ //=============================================================================
+
+ 'handleMoveBackward': function () {
+ if (this._currentStepIndex > 0) {
+ var afterMoveAction;
+
+ afterMoveAction = MochiKit.Base.noop;
+
+//console.log("<-- backward", this.currentStep());
+ switch(this.currentStep()) {
+ case 'CREDENTIALS':
+ case 'CHECK_CREDENTIALS':
+ case 'TERMS_OF_SERVICE':
+ this._currentStepIndex --;
+ this.rulerComponent().moveBackward(afterMoveAction);
+ break;
+ case 'CREATE_USER':
+ this.setUser(null);
+ this.newUserCreationComponent().hideAllProgeressStates();
+ this.resetCurrentStepIndex();
+ this.setUserCreationState('IDLE');
+ break;
+// case 'LOGIN':
+// break;
+ };
+
+ }
+
+ if (this._currentStepIndex == 0) {
+ this.enablePrevious(false);
+ }
+ },
+
+ 'handleMoveForward': function () {
+ if (this.isNextEnabled()) {
+ var afterMoveAction;
+
+ this._currentStepIndex ++;
+ afterMoveAction = MochiKit.Base.noop;
+
+ switch(this.currentStep()) {
+ case 'CREDENTIALS':
+ break;
+ case 'CHECK_CREDENTIALS':
+ break
+ case 'TERMS_OF_SERVICE':
+ break;
+ case 'CREATE_USER':
+ break;
+// case 'LOGIN':
+// break;
+ };
+
+ this.rulerComponent().moveForward(afterMoveAction);
+ };
+ },
+
+ 'handleCursorMoved': function () {
+// this.checkState();
+// this.setFocus();
+
+ return Clipperz.Async.callbacks("NewUserWizardController.handleCursorMoved", [
+ MochiKit.Base.method(this.newUserCreationComponent(), 'waitUntilFullyRendered'),
+ MochiKit.Base.method(this, 'checkState'),
+ MochiKit.Base.method(this, 'setFocus')
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleChangedValue': function (anEvent) {
+ this.checkState();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'handleNewUserCreationComponentKeyPressed': function (anEvent) {
+//console.log(">>> handleNewUserCreationComponentKeyPressed", anEvent.key().string);
+ if (anEvent.key().string == 'KEY_ENTER') {
+ if (anEvent.target().nodeName != 'TEXTAREA') {
+ anEvent.preventDefault();
+ this.handleMoveForward();
+ }
+ } else if (anEvent.key().string == 'KEY_TAB') {
+ if (anEvent.target() == this.newUserCreationComponent().usernameElement()) {
+ } else {
+ this.handleMoveForward();
+ if ((anEvent.target().nodeName == 'INPUT') || (anEvent.target().nodeName == 'TEXTAREA')) {
+ anEvent.preventDefault();
+ }
+ }
+ } else if ((anEvent.key().string == 'KEY_ARROW_RIGHT') && (anEvent.modifier().meta == true)) {
+ this.handleMoveForward();
+ } else if ((anEvent.key().string == 'KEY_ARROW_LEFT') && (anEvent.modifier().meta == true)) {
+ this.handleMoveBackward();
+ } else if (anEvent.key().string == 'KEY_ESCAPE') {
+ anEvent.stop();
+ this.handleExit();
+ } else {
+ MochiKit.Async.callLater(0.1, MochiKit.Base.method(this, 'checkState'));
+ }
+ },
+
+ //=============================================================================
+
+ 'preformActualUserRegistration': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("NewUSerWizardController.preformActualUserRegistration", {trace:false});
+ deferredResult.addMethod(this.newUserCreationComponent(), 'showProgressOnUserCreation');
+ deferredResult.addMethod(Clipperz.PM.RunTime.mainController, 'setPassphraseDelegate', MochiKit.Base.method(this.newUserCreationComponent(), 'passphrase'));
+ deferredResult.addCallback(Clipperz.PM.DataModel.User.registerNewAccount,
+ this.newUserCreationComponent().username(),
+ MochiKit.Base.method(Clipperz.PM.RunTime.mainController, 'getPassphrase')
+ );
+ deferredResult.addMethod(this, 'setUser');
+ deferredResult.addMethod(this.newUserCreationComponent(), 'showUserCreationDone');
+ deferredResult.addMethod(this, 'setUserCreationState', 'DONE');
+
+// deferredResult.addErrback(MochiKit.Base.method(this.newUserCreationComponent(), 'showUserCreationFailed'));
+// deferredResult.addErrback(MochiKit.Base.method(this, 'setUser', null));
+// deferredResult.addErrback(MochiKit.Base.method(this, 'setUserCreationState', 'FAILED'));
+ deferredResult.addErrback(MochiKit.Base.bind(function (aValue) {
+ this.newUserCreationComponent().showUserCreationFailed();
+ this.setUser(null);
+ this.setUserCreationState('FAILED');
+ }, this));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=============================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardDetail.js b/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardDetail.js
new file mode 100644
index 0000000..23fd236
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardDetail.js
@@ -0,0 +1,166 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.iPhone.Components');
+
+Clipperz.PM.UI.iPhone.Components.CardDetail = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.iPhone.Components.CardDetail.superclass.constructor.apply(this, arguments);
+
+ this._cardReference = null;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.iPhone.Components.CardDetail, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.iPhone.Components.CardDetail component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'cardReference': function () {
+ return this._cardReference;
+ },
+
+ 'setCardReference': function (aValue) {
+ this._cardReference = aValue;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.append(this.element(), [
+ {tag:'div', cls:'cardDetail', id:this.getId('cardDetail'), children:[
+ {tag:'div', id:this.getId('progressBar')} //,
+// {tag:'h1', cls:'loading', html:"loading"}
+ ]}
+ ]);
+
+ this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')}));
+ MochiKit.Signal.signal(Clipperz.PM.UI.Common.Controllers.ProgressBarController.defaultController, 'updateProgress', 0);
+ },
+
+ //=========================================================================
+
+ 'showCardDetails': function (someData) {
+ this.element().innerHTML = '';
+ this.append(this.element(), [
+ {tag:'fieldset', id:this.getId('fields'), children:MochiKit.Base.map(function (aFieldData) {
+ return {tag:'div', cls:'row', children:[
+ {tag:'label', html:aFieldData['label']},
+// {tag:'span', cls:('fieldValue ' + (aFieldData['isHidden'] ? 'password' : 'text')), html:aFieldData['value']}
+ {tag:'div', cls:('fieldValue ' + (aFieldData['isHidden'] ? 'password' : 'text')), children:[
+ {tag:'div', children:[{tag:'p', html:aFieldData['value']}]}
+ ]}
+// {tag:'input', type:'text', cls:('fieldValue ' + (aFieldData['isHidden'] ? 'password' : 'text')), value:aFieldData['value'], disabled:true}
+
+ ]}
+ }, someData['fields'])}
+ ]);
+
+ MochiKit.Iter.forEach(MochiKit.Selector.findChildElements(this.element(), ['span.password']), MochiKit.Base.bind(function (aPasswordElement) {
+ MochiKit.Signal.connect(aPasswordElement, 'onclick', function (anEvent) { alert(MochiKit.DOM.scrapeText(anEvent.src())); })
+ }, this));
+
+ if (someData['directLogins'].length > 0) {
+ this.append(this.element(), [
+ {tag:'h2', html:"Direct logins"},
+ {tag:'fieldset', id:this.getId('directLogins'), children:MochiKit.Base.map(function (aDirectLoginData) {
+ return {tag:'div', cls:'row', id:('directLogin_' + aDirectLoginData['_reference']), children:[
+ {tag:'img', cls:'favicon', src:aDirectLoginData['favicon']},
+// {tag:'input', cls:'directLogin', disabled:'disabled', type:'text', name:aDirectLoginData['label'], value:aDirectLoginData['label']}
+ {tag:'span', cls:'directLogin', html:aDirectLoginData['label']}
+ ]}
+ }, someData['directLogins'])}
+ ]);
+
+ MochiKit.Base.map(MochiKit.Base.bind(function (aRowNode) {
+ MochiKit.Signal.connect(aRowNode, 'onclick', this, 'directLoginClickHandler');
+ }, this),
+ MochiKit.Selector.findChildElements(this.getElement('directLogins'), ['div.row'])
+ )
+ };
+
+ if (someData['notes'] != '') {
+ this.append(this.element(), [
+ {tag:'h2', html:"Notes"},
+ {tag:'fieldset', id:this.getId('fieldset'), children:[
+ {tag:'div', cls:'row notes', children:[
+ {tag:'span', html:someData['notes']}
+ ]}
+ ]}
+ ]);
+ };
+
+ return true;
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'toggleClickHandler': function (anEvent) {
+ var nextState;
+ var fieldValue;
+
+//console.log("TOGGLE");
+ anEvent.preventDefault;
+ fieldValue = MochiKit.Selector.findChildElements(anEvent.src().parentNode.parentNode, ['span.password'])[0];
+
+ nextState = (MochiKit.DOM.getNodeAttribute(anEvent.src(), 'toggled') != 'true');
+ if (nextState) {
+ MochiKit.DOM.removeElementClass(fieldValue, 'clear');
+ } else {
+ MochiKit.DOM.addElementClass(fieldValue, 'clear');
+ }
+
+ MochiKit.DOM.setNodeAttribute(anEvent.src(), 'toggled', nextState);
+ },
+*/
+ //=========================================================================
+
+ 'directLoginClickHandler': function (anEvent) {
+ anEvent.preventDefault();
+
+ if (/(directLogin_)/.test(anEvent.src().id)) {
+ var directLoginReference;
+
+ directLoginReference = anEvent.src().id.match(/(directLogin_)(.*)/)[2];
+ MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'selectedDirectLogin', {cardReference:this.cardReference(), directLoginReference:directLoginReference});
+ }
+ },
+
+ //=========================================================================
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardList.js b/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardList.js
new file mode 100644
index 0000000..770f983
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/CardList.js
@@ -0,0 +1,204 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.iPhone.Components');
+
+Clipperz.PM.UI.iPhone.Components.CardList = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.iPhone.Components.CardList.superclass.constructor.apply(this, arguments);
+
+ this._cardDetail = null;
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.iPhone.Components.CardList, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.iPhone.Components.CardList component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.append(this.element(), [
+ {tag:'div', cls:'toolbar', id:'toolbar', children:[
+ {tag:'h1', id:'pageTitle', html:"cards"},
+ {tag:'a', id:'backButton', cls:'button', href:'#', html:"cards"}
+ ]},
+ {tag:'div', cls:'cardList', id:this.getId('cardList'), children:[
+ {tag:'form', title:'search', cls:'panel cardListSearchForm', id:this.getId('cardListSearchForm'), children:[
+ {tag:'input', type:'search', name:'search', value:"", placeholder:"search", id:this.getId('searchField')}
+ ]},
+ {tag:'ul', cls:'panel cardListPanel', id:this.getId('cardListPanel'), children:[]}
+ ]},
+ {tag:'div', cls:'panel cardDetailPanel', id:this.getId('cardDetail')}
+ ]);
+
+ MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onsubmit', this, 'searchHandler');
+ MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onkeydown', this, 'searchHandler');
+ MochiKit.Signal.connect(this.getElement('cardListSearchForm'), 'onkeyup', this, 'searchHandler');
+
+ MochiKit.Signal.connect(this.getElement('cardListPanel'), 'onclick', this, 'cardListClickHandler');
+ MochiKit.Signal.connect('backButton', 'onclick', this, 'backButtonClickHandler');
+
+ MochiKit.Style.hideElement('backButton');
+ MochiKit.Style.hideElement(this.getElement('cardDetail'));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'searchHandler': function (anEvent) {
+ if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ENTER')) { // RETURN
+ anEvent.preventDefault();
+ } else {
+ if ((typeof(anEvent.key()) != 'undefined') && (anEvent.key().string == 'KEY_ESCAPE')) {
+ anEvent.target().value = "";
+ }
+
+ if (anEvent.type() == 'keyup') {
+ MochiKit.Signal.signal(this, 'searchEvent', anEvent.target().value);
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'update': function (someObjects) {
+ var cardListPanel;
+ var i,c;
+
+ cardListPanel = this.getElement('cardListPanel');
+ cardListPanel.innerHTML = '';
+
+ c = someObjects.length;
+
+ for (i=0; i<c; i++) {
+ this.append(cardListPanel, {tag:'li', cls:'cardListItem', id:('cardListItem_' + someObjects[i]['_reference']), children:[
+ {tag:'img', src:(someObjects[i]['favicon'] ? someObjects[i]['favicon'] : 'data:application/octet-stream;charset=utf-8;base64,AAABAAEAFxcAAAEAGAD8BgAAFgAAACgAAAAXAAAALgAAAAEAGAAAAAAAAAAAABIXAAASFwAAAAAAAAAAAAD///////////////////////////////////////////////////////////////////////////////////////////9zAC////////////////////////////////////////////////////////////////////////////////////////////9pAG////////////////////////////////////////////////////////////////////////////////////////////9rAC////////////////////////////////////////////////////////////////////////////////////////////9yAHP////////////////////////IyMizs7O6urrq6ur////////////Ozs6zs7Ozs7Pq6ur///////////////////////8AAAD////////////////////V1dWXl5eXl5eXl5elpaX4+Pj////Ozs6Xl5eXl5eXl5eenp7///////////////////////8AAAD////////////////////Ozs6Xl5eXl5eXl5eXl5fBwcHq6uqenp6Xl5eXl5eXl5eXl5f///////////////////////8AAAD////////////////////j4+OXl5eXl5eXl5eXl5eXl5elpaWXl5eXl5eXl5eXl5ezs7P///////////////////////8AAAD////////////////////////IyMiXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eenp7x8fH////////////////////////////////////////////////////4+PilpaWXl5eXl5eXl5eXl5eXl5eXl5eXl5fOzs7////////////////////////////////////////////////////////q6uq6urqXl5eXl5eXl5eXl5eXl5eXl5eenp7V1dX4+Pj///////////////////////8AAAD////////////4+PjOzs6lpaWXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5e6urrj4+P///////////////8AAAD////////////BwcGXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5fx8fH///////////8AAAD///////////+zs7OXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5fj4+P///////////8AAAD////////////IyMiXl5eXl5eXl5eXl5e6urqXl5eXl5eXl5eXl5esrKylpaWXl5eXl5eXl5eenp7x8fH///////////8AAAD////////////////Ozs7Ozs7V1dX4+Pj///+Xl5eXl5eXl5eXl5fOzs7////q6urOzs7Ozs7q6ur///////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD///////////////////////////////////+Xl5eXl5eXl5eXl5fOzs7///////////////////////////////////8AAAD////////////////////////////////////IyMiXl5eXl5eenp7x8fH///////////////////////////////////8AAAD////////////////////////////////////////j4+Pj4+Px8fH///////////////////////////////////////8AAAD///////////////////////////////////////////////////////////////////////////////////////////8AAAD///////////////////////////////////////////////////////////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo=')},
+ {tag:'a', id:('cardListReference_' + someObjects[i]['_reference']), href:'#', html:someObjects[i]['label']}
+ ]})
+
+ MochiKit.Signal.connect('cardListItem_' + someObjects[i]['_reference'], 'onclick', this, 'cardListClickHandler');
+ }
+
+ },
+
+ 'cardListClickHandler': function (anEvent) {
+ anEvent.preventDefault();
+
+ if (/(cardListReference_|cardListItem_)/.test(anEvent.target().id)) {
+ var cardListReference;
+
+ cardListReference = anEvent.target().id.match(/(cardListReference_|cardListItem_)(.*)/)[2];
+//console.log("Showing detail for card named", cardListReference);
+ MochiKit.Signal.signal(this, 'selectedCard', cardListReference);
+ }
+ },
+
+ //=========================================================================
+
+ 'cardDetail': function (someData) {
+ if (this._cardDetail == null) {
+ this._cardDetail = new Clipperz.PM.UI.iPhone.Components.CardDetail({element:this.getElement('cardDetail')});
+ }
+
+ return this._cardDetail;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'removeCardDetail': function () {
+ if (this._cardDetail != null) {
+ this._cardDetail.remove();
+ this._cardDetail = null;
+ }
+ },
+
+ //=========================================================================
+
+ 'showCard': function (someData) {
+ var deferredResult;
+ var offset;
+
+ offset = ((MochiKit.DOM.getNodeAttribute(MochiKit.DOM.currentDocument().body, 'orientation') == 'portrait') ? 320 : 480);
+ this.cardDetail().render();
+ this.cardDetail().setCardReference(someData['_reference']);
+ MochiKit.Style.setElementPosition(this.cardDetail().element(), {x:offset});
+ new MochiKit.Visual.Sequence([
+// new MochiKit.Visual.Move(this.cardDetail().element(), {x:offset, y:45, mode:'absolute', duration:0, sync:true}),
+ new MochiKit.Visual.Parallel([
+ new MochiKit.Visual.Move(this.getElement('cardList'), {x:-offset, y:0, mode:'relative', transition:MochiKit.Visual.Transitions.linear, sync:true}),
+ new MochiKit.Visual.Move(this.getElement('cardDetail'), {x:0, y:45, mode:'absolute', transition:MochiKit.Visual.Transitions.linear, sync:true}),
+// new MochiKit.Visual.ScrollTo('toolbar', {sync:true}),
+ MochiKit.Visual.appear ('backButton', { transition:MochiKit.Visual.Transitions.linear, sync:true})
+ ], {duration:1, sync:true}),
+ MochiKit.Visual.fade(this.getElement('cardList'), {duration:0, sync:true})
+ ], {})
+
+ MochiKit.DOM.getElement('pageTitle').innerHTML = someData['title'];
+
+ return true;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'showCardDetails': function (someData) {
+ return this.cardDetail().showCardDetails(someData);
+ },
+
+ //=========================================================================
+
+ 'backButtonClickHandler': function (anEvent) {
+ var offset;
+
+ anEvent.preventDefault();
+
+ MochiKit.DOM.getElement('pageTitle').innerHTML = "cards";
+
+ offset = ((MochiKit.DOM.getNodeAttribute(MochiKit.DOM.currentDocument().body, 'orientation') == 'portrait') ? 320 : 480);
+ MochiKit.Style.setElementPosition(this.getElement('cardList'), {x:-offset});
+ MochiKit.DOM.showElement(this.getElement('cardList'));
+
+ new MochiKit.Visual.Parallel([
+ new MochiKit.Visual.Move(this.getElement('cardList'), {x:offset, y:0, mode:'relative', transition:MochiKit.Visual.Transitions.linear, sync:true}),
+ new MochiKit.Visual.Move(this.getElement('cardDetail'), {x:offset, y:0, mode:'relative', transition:MochiKit.Visual.Transitions.linear, sync:true}),
+ MochiKit.Visual.fade (this.getElement('cardDetail'), { transition:MochiKit.Visual.Transitions.linear, sync:true}),
+ MochiKit.Visual.fade ('backButton', { transition:MochiKit.Visual.Transitions.linear, sync:true})
+ ], {duration:1, afterFinish:MochiKit.Base.method(this, 'removeCardDetail')})
+
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/LoginForm.js b/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/LoginForm.js
new file mode 100644
index 0000000..eec83b0
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/iPhone/Components/LoginForm.js
@@ -0,0 +1,181 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.iPhone.Components');
+
+Clipperz.PM.UI.iPhone.Components.LoginForm = function(args) {
+ args = args || {};
+
+ Clipperz.PM.UI.iPhone.Components.LoginForm.superclass.constructor.apply(this, arguments);
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.PM.UI.iPhone.Components.LoginForm, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.iPhone.Components.LoginForm component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'focusOnUsername': function () {
+ this.getElement('username').focus();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'username': function () {
+ return this.getElement('username').value;
+ },
+
+ 'passphrase': function () {
+ return this.getElement('passphrase').value;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.append(this.element(), [
+ {tag:'div', cls:'toolbar iPhoneClipperzToolbar', children:[
+ {tag:'h1', id:'pageTitle', html:'Clipperz'},
+ {tag:'a', id:'backButton', cls:'button', href:'#', html:"back"}
+ ]},
+ {tag:'form', title:'Theaters', cls:'panel toolbarlessPanel loginForm', id:this.getId('loginFormPanel'), children:[
+ {tag:'fieldset', id:this.getId('fieldset'), children:[
+ {tag:'div', cls:'row', children:[
+ {tag:'label', html:"username"},
+ {tag:'input', type:'text', name:'username', value:"", autocorrect:'off', autocapitalize:'off', id:this.getId('username')}
+ ]},
+ {tag:'div', cls:'row', children:[
+ {tag:'label', html:"passphrase"},
+ {tag:'input', type:'password', name:'passphrase', value:"", id:this.getId('passphrase')}
+ ]}
+ ]},
+ {tag:'a', cls:'whiteButton', type:'submit', href:'#', html:"Login", id:this.getId('submit')}
+ ]},
+ {tag:'div', cls:'panel toolbarlessPanel loginProgressPanel', id:this.getId('loginProgressPanel'), children:[
+ {tag:'div', id:this.getId('progressBar')} //,
+// {tag:'a', cls:'whiteButton', type:'submit', href:'#', html:"Cancel", id:this.getId('cancel')}
+ ]},
+ {tag:'div', cls:'panel loginErrorPanel', id:this.getId('loginErrorPanel'), children:[
+ {tag:'div', cls:'errorMessage', id:this.getId('errorMessageBox'), children:[
+ {tag:'h2', id:this.getId('errorMessage'), html:"Login failed"}
+ ]}
+ ]}
+ ]);
+
+ MochiKit.Signal.connect(this.getElement('submit'), 'onclick', this, 'submitHandler');
+ MochiKit.Signal.connect(this.getElement('loginFormPanel'), 'onsubmit', this, 'submitHandler');
+
+// MochiKit.Signal.connect(this.getElement('cancel'), 'onclick', this, 'cancelHandler');
+ MochiKit.Signal.connect('backButton', 'onclick', this, 'backHandler');
+
+ this.addComponent(new Clipperz.PM.UI.Common.Components.ProgressBar({'element':this.getElement('progressBar')}));
+
+// MochiKit.Style.hideElement(this.getElement('errorMessage'));
+
+ this.showLoginForm();
+// MochiKit.Async.callLater(0.2, MochiKit.Base.method(this, 'focusOnUsername'));
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'showLoginForm': function () {
+ MochiKit.Style.showElement(this.getElement('loginFormPanel'));
+ MochiKit.Style.hideElement(this.getElement('loginProgressPanel'));
+ MochiKit.Style.hideElement(this.getElement('loginErrorPanel'));
+ MochiKit.Style.hideElement('backButton');
+ },
+
+ 'slideInLoginForm': function () {
+ var offset;
+
+ offset = ((MochiKit.DOM.getNodeAttribute(MochiKit.DOM.currentDocument().body, 'orientation') == 'portrait') ? 320 : 480);
+
+ MochiKit.Style.showElement(this.getElement('loginFormPanel'));
+ MochiKit.Style.setElementPosition(this.getElement('loginFormPanel'), {x:-offset, y:0});
+
+ new MochiKit.Visual.Sequence([
+ new MochiKit.Visual.Parallel([
+ new MochiKit.Visual.Move(this.getElement('loginErrorPanel'), {x:offset, y:0, mode:'relative', transition:MochiKit.Visual.Transitions.linear, sync:true}),
+ new MochiKit.Visual.Move(this.getElement('loginFormPanel'), {x:0, y:0, mode:'absolute', transition:MochiKit.Visual.Transitions.linear, sync:true}),
+ MochiKit.Visual.fade ('backButton', { transition:MochiKit.Visual.Transitions.linear, sync:true})
+ ], {duration:0.5, sync:true}),
+ MochiKit.Visual.fade(this.getElement('loginErrorPanel'), {duration:0, sync:true})
+ ], {})
+ },
+
+ 'showLoginProgress': function () {
+ MochiKit.Style.hideElement(this.getElement('loginFormPanel'));
+ MochiKit.Style.showElement(this.getElement('loginProgressPanel'));
+ },
+
+ 'showLoginError': function (anError) {
+ this.getElement('errorMessage').innerHTML = "Login error";
+
+ MochiKit.Style.showElement('backButton');
+ MochiKit.Style.hideElement(this.getElement('loginProgressPanel'));
+ MochiKit.Style.showElement(this.getElement('loginErrorPanel'));
+ MochiKit.Style.setElementPosition(this.getElement('loginErrorPanel'), {x:0, y:45});
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'disableCancelButton': function () {
+ MochiKit.DOM.hideElement(this.getElement('cancel'));
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'submitHandler': function (anEvent) {
+ anEvent.preventDefault();
+
+ MochiKit.Signal.signal(this, 'doLogin', {'username':this.username(), 'passphrase':this.passphrase()});
+ },
+
+ 'cancelHandler': function (anEvent) {
+ anEvent.preventDefault();
+
+//console.log("CANCEL");
+ },
+
+ 'backHandler': function (anEvent) {
+ anEvent.preventDefault();
+
+ this.slideInLoginForm();
+ },
+
+ //-------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/js/Clipperz/PM/UI/iPhone/Controllers/MainController.js b/frontend/gamma/js/Clipperz/PM/UI/iPhone/Controllers/MainController.js
new file mode 100644
index 0000000..b43d877
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/PM/UI/iPhone/Controllers/MainController.js
@@ -0,0 +1,372 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.PM.UI.iPhone.Controllers');
+
+// Some parts of this controller have been derived from the iUI library.
+
+Clipperz.PM.UI.iPhone.Controllers.MainController = function() {
+ this._loginForm = null;
+ this._cardList = null;
+ this._cachedValues = null;
+ this._user = null;
+
+ if (typeof window.onorientationchange == 'object') {
+ MochiKit.Signal.connect(window, 'onorientationchange', this, 'orientationChangeHandler');
+ MochiKit.Async.callLater(0, MochiKit.Base.method(this, 'orientationChangeHandler'));
+ } else {
+ this.setOrientation('portrait');
+// this.setOrientation('landscape');
+ }
+
+ this.addMetaTag('viewport', 'width=devicewidth; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;');
+ this.addMetaTag('apple-mobile-web-app-capable', 'yes');
+ this.addMetaTag('apple-mobile-web-app-status-bar-style', 'black');
+
+ this.addLinkTag('apple-touch-icon', 'data:image/png;charset=utf-8;base64,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');
+// this.addLinkTag('apple-touch-startup-image', 'default.png');
+
+// if (!window.navigator.standalone) // not running as an installed app
+
+ MochiKit.Signal.connect(Clipperz.Signal.NotificationCenter, 'selectedDirectLogin', this, 'selectedDirectLoginHandler');
+
+ MochiKit.DOM.addElementClass(document.body, 'iPhone');
+ return this;
+}
+
+MochiKit.Base.update(Clipperz.PM.UI.iPhone.Controllers.MainController.prototype, {
+
+ 'toString': function () {
+ return "Clipperz.PM.UI.iPhone.Controllers.MainController";
+ },
+
+ //=========================================================================
+
+ 'user': function () {
+ return this._user;
+ },
+
+ 'setUser': function (aValue) {
+ this._user = aValue;
+ },
+
+ //=========================================================================
+
+ 'loginForm': function() {
+ if (this._loginForm == null) {
+ MochiKit.DOM.removeElement('mainDiv');
+ this._loginForm = new Clipperz.PM.UI.iPhone.Components.LoginForm({element:MochiKit.DOM.currentDocument().body});
+ MochiKit.Signal.connect(this._loginForm, 'doLogin', this, 'doLoginHandler')
+ }
+
+ return this._loginForm;
+ },
+
+ 'removeLoginForm': function () {
+ if (this._loginForm != null) {
+ this._loginForm.remove();
+ this._loginForm = null;
+ }
+ },
+
+ //-----------------------------------------------------------------------------
+
+ 'cardList': function () {
+ if (this._cardList == null) {
+ this._cardList = new Clipperz.PM.UI.iPhone.Components.CardList({element:MochiKit.DOM.currentDocument().body});
+ MochiKit.Signal.connect(this._cardList, 'searchEvent', this, 'searchEventHandler')
+ MochiKit.Signal.connect(this._cardList, 'selectedCard', this, 'selecetedCardHandler')
+ }
+
+ return this._cardList;
+ },
+
+ //=========================================================================
+
+ 'currentWidth': function () {
+ return this._currentWidth;
+ },
+
+ 'setCurrentWidth': function (aValue) {
+ this._currentWidth = aValue;
+ },
+
+ //=========================================================================
+
+ 'orientationChangeHandler': function () {
+ switch(window.orientation) {
+ case 0:
+ this.setOrientation('portrait');
+ break;
+ case 90:
+ case -90:
+ this.setOrientation('landscape');
+ break;
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setOrientation': function (anOrientation) {
+ document.body.setAttribute('orientation', anOrientation);
+ setTimeout(scrollTo, 100, 0, 1);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'slidePages': function (fromPage, toPage, backwards) {
+ var axis;
+ var slideDone;
+
+ slideDone = function () {
+ // console.log("slideDone");
+ if (!hasClass(toPage, "dialog")) {
+ fromPage.removeAttribute("selected");
+ }
+ checkTimer = setInterval(checkOrientAndLocation, 300);
+ setTimeout(updatePage, 0, toPage, fromPage);
+ fromPage.removeEventListener('webkitTransitionEnd', slideDone, false);
+ }
+
+ axis = (backwards ? fromPage : toPage).getAttribute("axis");
+
+ clearInterval(checkTimer);
+
+ if (canDoSlideAnim() && axis != 'y') {
+ slide2(fromPage, toPage, backwards, slideDone);
+ } else {
+ slide1(fromPage, toPage, backwards, axis, slideDone);
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getCachedValues': function () {
+ var deferredResult;
+
+ if (this._cachedObjects != null) {
+ deferredResult = MochiKit.Async.succeed(this._cachedObjects);
+ } else {
+ deferredResult = new Clipperz.Async.Deferred("MainController.getCachedValues", {trace:false});
+ deferredResult.addMethod(this.user(), 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("MainController.getCachedValues - collectResults", {
+ '_rowObject': MochiKit.Async.succeed,
+ '_reference': MochiKit.Base.methodcaller('reference'),
+ 'label': MochiKit.Base.methodcaller('label'),
+ 'favicon': MochiKit.Base.methodcaller('favicon'),
+ '_searchableContent': MochiKit.Base.methodcaller('searchableContent')
+ }, {trace:false}));
+ deferredResult.addCallback(Clipperz.Async.collectAll);
+ deferredResult.addCallback(MochiKit.Base.bind(function (someRows) {
+ this._cachedObjects = someRows;
+ return this._cachedObjects;
+ }, this));
+ deferredResult.callback();
+ }
+
+ return deferredResult;
+ },
+ //=========================================================================
+
+ 'run': function(shouldShowRegistrationForm) {
+ this.loginForm().render();
+ MochiKit.Async.callLater(1, MochiKit.Base.method(this.loginForm(), 'focusOnUsername'));
+ },
+
+ //=========================================================================
+
+ 'doLoginHandler': function (someArgs) {
+ var deferredResult;
+ var parameters;
+ var shouldUseOTP;
+// var loginProgress;
+ var user;
+ var getPassphraseDelegate;
+
+ parameters = someArgs;
+ shouldUseOTP = (typeof(parameters.passphrase) == 'undefined');
+
+ getPassphraseDelegate = MochiKit.Base.partial(MochiKit.Async.succeed, parameters.passphrase);
+ user = new Clipperz.PM.DataModel.User({'username':parameters.username, 'getPassphraseFunction':getPassphraseDelegate});
+
+ deferredResult = new Clipperz.Async.Deferred("MainController.doLogin", {trace:false});
+ deferredResult.addCallbackPass(MochiKit.Signal.signal, Clipperz.Signal.NotificationCenter, 'initProgress', {'steps':4});
+ deferredResult.addMethod(this.loginForm(), 'showLoginProgress');
+ deferredResult.addCallback(MochiKit.Async.wait, 0.1);
+ deferredResult.addMethod(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'deferredEntropyCollection');
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addMethod(this, 'setUser', user);
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addMethod(this, 'removeLoginForm');
+ deferredResult.addMethod(this.cardList(), 'render');
+ deferredResult.addMethod(this, 'displaySelectedRecords', '');
+ deferredResult.addErrback(MochiKit.Base.method(this.loginForm(), 'showLoginError'));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'searchEventHandler': function (aValue) {
+//console.log("searching for ... " + aValue);
+ return this.displaySelectedRecords(aValue);
+ },
+
+ //=========================================================================
+
+ '_displaySelectedRows': function (aFilter, someRows) {
+ var result;
+
+ result = someRows;
+
+ if (aFilter != null) {
+ var filter;
+ var filterRegExp;
+
+ filter = aFilter.replace(/[^A-Za-z0-9]/g, "\\$&");
+ filterRegExp = new RegExp(filter, "i");
+ result = MochiKit.Base.filter(function (aCachedResult) { return filterRegExp.test(aCachedResult['_searchableContent'])}, result);
+ }
+
+
+ result.sort(MochiKit.Base.partial(function (aKey, aComparator, aObject, bObject) {
+ return aComparator(aObject[aKey], bObject[aKey]);
+ }, 'label', Clipperz.Base.caseInsensitiveCompare));
+
+ this.cardList().update(result);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'displaySelectedRecords': function (aFilter) {
+ return Clipperz.Async.callbacks("MainController.displaySelectedrows", [
+ MochiKit.Base.method(this, 'getCachedValues'),
+ MochiKit.Base.method(this, '_displaySelectedRows', aFilter)
+ ], {trace:false});
+ },
+
+ //=========================================================================
+
+ 'selecetedCardHandler': function (aRecordReference) {
+ var deferredResult;
+ var recordData;
+
+ recordData = {};
+//console.log("Showing detail for card with reference", aRecordReference);
+ deferredResult = new Clipperz.Async.Deferred("MainController.selectedCardHandler", {trace:false});
+ deferredResult.addMethod(this.user(), 'getRecord', aRecordReference);
+ deferredResult.collectResults({
+ '_reference': MochiKit.Base.methodcaller('reference'),
+ 'title': MochiKit.Base.methodcaller('label'),
+ 'favicon': MochiKit.Base.methodcaller('favicon')
+ });
+ deferredResult.addCallback(function (someData) {
+ MochiKit.Base.update(recordData, someData);
+ })
+ deferredResult.addMethod(this.cardList(), 'showCard', recordData);
+
+ deferredResult.addMethod(this.user(), 'getRecord', aRecordReference);
+ deferredResult.addMethodcaller('notes');
+ deferredResult.addCallback(function (someNotes) {
+ recordData['notes'] = someNotes;
+ })
+
+ deferredResult.addMethod(this.user(), 'getRecord', aRecordReference);
+ deferredResult.addMethodcaller('getCurrentRecordVersion');
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("MainController.selectedCardHandler - fields", {
+ 'label': MochiKit.Base.methodcaller('label'),
+ 'value': MochiKit.Base.methodcaller('value'),
+ 'isHidden': MochiKit.Base.methodcaller('isHidden')
+ }, {trace:false}));
+ deferredResult.addCallback(Clipperz.Async.collectAll);
+ deferredResult.addCallback(function (someData) {
+ recordData['fields'] = someData;
+ });
+
+ deferredResult.addMethod(this.user(), 'getRecord', aRecordReference);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(MochiKit.Base.map, Clipperz.Async.collectResults("MainController.selectedCardHandler - directLogins", {
+ 'label': MochiKit.Base.methodcaller('label'),
+ 'favicon': MochiKit.Base.methodcaller('favicon'),
+ '_reference': MochiKit.Base.methodcaller('reference')
+ }, {trace:false}));
+ deferredResult.addCallback(Clipperz.Async.collectAll);
+ deferredResult.addCallback(function (someData) {
+ recordData['directLogins'] = someData;
+ });
+
+ deferredResult.addMethod(this.cardList(), 'showCardDetails', recordData);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'selectedDirectLoginHandler': function (someData) {
+ var deferredResult;
+
+//console.log("<<< signal - directLogin");
+ deferredResult = new Clipperz.Async.Deferred("MainController.selectedDirectLoginHandler", {trace:false});
+ deferredResult.addMethod(this.user(), 'getRecord', someData['cardReference']);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(someData['directLoginReference']));
+// deferredResult.addMethodcaller('runDirectLogin');
+ deferredResult.addCallback(Clipperz.PM.UI.Common.Controllers.DirectLoginRunner.openDirectLogin);
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'addMetaTag': function (aName, aContent) {
+ var metaTag;
+
+ metaTag = document.createElement('meta');
+ metaTag.name = aName;
+ metaTag.content = aContent;
+ document.getElementsByTagName('head')[0].appendChild(metaTag);
+ },
+
+ 'addLinkTag': function (aRel, anHref) {
+ var linkTag;
+
+ linkTag = document.createElement('link');
+ linkTag.rel = aRel;
+ linkTag.href = anHref;
+ document.getElementsByTagName('head')[0].appendChild(linkTag);
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+}); \ No newline at end of file
diff --git a/frontend/gamma/js/Clipperz/Set.js b/frontend/gamma/js/Clipperz/Set.js
new file mode 100644
index 0000000..61e0769
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Set.js
@@ -0,0 +1,167 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+
+if (typeof(Clipperz) == 'undefined') {
+ Clipperz = {};
+}
+
+//#############################################################################
+
+Clipperz.Set = function(args) {
+ args = args || {};
+// MochiKit.Base.bindMethods(this);
+
+ if (args.items != null) {
+ this._items = args.items.slice();
+ } else {
+ this._items = [];
+ }
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Set.prototype = MochiKit.Base.update(null, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function() {
+ return "Clipperz.Set";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'items': function() {
+ return this._items;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'popAnItem': function() {
+ var result;
+
+ if (this.size() > 0) {
+ result = this.items().pop();
+ } else {
+ result = null;
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'allItems': function() {
+ return this.items();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'contains': function(anItem) {
+ return (this.indexOf(anItem) != -1);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'indexOf': function(anItem) {
+ var result;
+ var i, c;
+
+ result = -1;
+
+ c = this.items().length;
+ for (i=0; (i<c) && (result == -1); i++) {
+ if (this.items()[i] === anItem) {
+ result = i;
+ }
+ }
+
+ return result;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'add': function(anItem) {
+ if (anItem.constructor == Array) {
+ MochiKit.Base.map(MochiKit.Base.bind(this,add, this), anItem);
+ } else {
+ if (! this.contains(anItem)) {
+ this.items().push(anItem);
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'debug': function() {
+ var i, c;
+
+ result = -1;
+
+ c = this.items().length;
+ for (i=0; i<c; i++) {
+ alert("[" + i + "] " + this.items()[i].label);
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'remove': function(anItem) {
+ if (anItem.constructor == Array) {
+ MochiKit.Base.map(MochiKit.Base.bind(this.remove, this), anItem);
+ } else {
+ var itemIndex;
+
+ itemIndex = this.indexOf(anItem);
+ if (itemIndex != -1) {
+ this.items().splice(itemIndex, 1);
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'size': function() {
+ return this.items().length;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'empty': function() {
+ this.items().splice(0, this.items().length);
+ },
+
+ //-------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+
+ //-------------------------------------------------------------------------
+});
+
diff --git a/frontend/gamma/js/Clipperz/Signal.js b/frontend/gamma/js/Clipperz/Signal.js
new file mode 100644
index 0000000..b82499a
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Signal.js
@@ -0,0 +1,71 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.Signal) == 'undefined') { Clipperz.Signal = {}; }
+
+Clipperz.Signal.VERSION = "0.1";
+Clipperz.Signal.NAME = "Clipperz.Signal";
+
+MochiKit.Base.update(Clipperz.Signal, {
+
+ //-------------------------------------------------------------------------
+
+ '__repr__': function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return this.__repr__();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'fireNativeEvent': function(element, eventName) {
+ if (element.fireEvent) {
+ // MSIE
+ element.fireEvent(eventName);
+ } else {
+ // W3C
+ var event;
+
+ event = document.createEvent("HTMLEvents");
+ event.initEvent(eventName.replace(/^on/, ""), true, true);
+ element.dispatchEvent(event);
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
+Clipperz.Signal.NotificationCenter = {};
+
diff --git a/frontend/gamma/js/Clipperz/Style.js b/frontend/gamma/js/Clipperz/Style.js
new file mode 100644
index 0000000..3717f61
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Style.js
@@ -0,0 +1,94 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.Style) == 'undefined') { Clipperz.Style = {}; }
+
+Clipperz.Style.VERSION = "0.1";
+Clipperz.Style.NAME = "Clipperz.DOM";
+
+MochiKit.Base.update(Clipperz.Style, {
+
+ //-------------------------------------------------------------------------
+
+ '__repr__': function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return this.__repr__();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'applyZebraStylesToTable': function(aTable) {
+ var tbody;
+ var tbodyRows;
+ var i,c;
+
+ tbody = MochiKit.DOM.getFirstElementByTagAndClassName('tbody', null, aTable);
+ tbodyRows = tbody.childNodes;
+// tbodyRows = MochiKit.DOM.getElementsByTagAndClassName('tr', null, tbody)
+ c = tbodyRows.length;
+ for (i=0; i<c; i++) {
+ var element;
+
+ element = YAHOO.Element.get(tbodyRows[i]);
+ element.addClass(((i%2 == 0) ? "zebra_odd": "zebra_even"));
+ element.removeClass(((i%2 == 1) ? "zebra_odd": "zebra_even"));
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getSizeAndPosition': function (anElement) {
+ var result;
+
+ if (anElement != null) {
+ result = { dimensions:MochiKit.Style.getElementDimensions(anElement), position:MochiKit.Style.getElementPosition(anElement)};
+ } else {
+ result = { dimensions:MochiKit.Style.getViewportDimensions(), position:MochiKit.Style.getViewportPosition()};
+ }
+
+ return result;
+ },
+
+ 'setBackgroundGradient': function (anElement, someParameters) {
+// background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ff9955), to(#ff6622), color-stop(1,#333333));
+// background: -moz-linear-gradient(0% 100% 90deg,#ff6622, #ff9955);
+ MochiKit.Style.setStyle(anElement, {'background': '-webkit-gradient(linear, 0% 0%, 0% 100%, from(' + someParameters['from'] + '), to(' + someParameters['to'] + '), color-stop(1,#333333))'});
+ MochiKit.Style.setStyle(anElement, {'background': '-moz-linear-gradient(0% 100% 90deg,' + someParameters['to'] + ', ' + someParameters['from'] + ')'});
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
diff --git a/frontend/gamma/js/Clipperz/Visual.js b/frontend/gamma/js/Clipperz/Visual.js
new file mode 100644
index 0000000..b907d5c
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/Visual.js
@@ -0,0 +1,368 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.Visual) == 'undefined') { Clipperz.Visual = {}; }
+
+Clipperz.Visual.VERSION = "0.1";
+Clipperz.Visual.NAME = "Clipperz.Visual";
+
+MochiKit.Base.update(Clipperz.Visual, {
+
+ //-------------------------------------------------------------------------
+
+ '__repr__': function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return this.__repr__();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredResize': function (anElement, someOptions) {
+ var deferredResult;
+ var moveTransition;
+ var scaleTransition;
+ var duration;
+
+ duration = someOptions.duration || 0.5;
+
+ deferredResult = new Clipperz.Async.Deferred("Visual.deferredResize", {trace:false});
+ deferredResult.addCallback(MochiKit.Async.succeed, arguments[arguments.length - 1]);
+
+ moveTransition = MochiKit.Visual.Transitions.linear; //MochiKit.Visual.Transitions.sinoidal;
+ scaleTransition = MochiKit.Visual.Transitions.linear; //MochiKit.Visual.Transitions.sinoidal;
+
+ MochiKit.Style.setElementPosition(anElement, {x:someOptions.from.position.x, y:someOptions.from.position.y }, 'px');
+
+ new MochiKit.Visual.Parallel([
+ new MochiKit.Visual.Move(anElement, {x:someOptions.to.position.x, y:someOptions.to.position.y, mode:'absolute', transition:moveTransition, sync:true}),
+ new Clipperz.Visual.Resize(anElement, {fromSize:{h:someOptions.from.dimensions.h, w:someOptions.from.dimensions.w}, toSize:{h:someOptions.to.dimensions.h, w:someOptions.to.dimensions.w}, transition:scaleTransition, scaleContent:false, scaleFromCenter:false, restoreAfterFinish:true, sync:true})
+ ], {duration:duration, afterFinish:MochiKit.Base.method(deferredResult, 'callback')})
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredAnimation': function (anAnimation, someParameters, someOptions) {
+ var deferredResult;
+ var afterFinishCallback;
+ var options;
+
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.Visual.deferredAnimation", {trace:false});
+ deferredResult.addCallback(MochiKit.Async.succeed, arguments[arguments.length - 1]);
+
+ if (MochiKit.Base.isUndefinedOrNull(someOptions)) {
+ options = {}
+ } else {
+ options = someOptions;
+ }
+
+ if (MochiKit.Base.isUndefinedOrNull(someOptions['afterFinish'])) {
+ options['afterFinish'] = MochiKit.Base.noop;
+ }
+
+ MochiKit.Base.update(options, {
+ 'afterFinish': MochiKit.Base.compose(options['afterFinish'], MochiKit.Base.method(deferredResult, 'callback'))
+ });
+
+ new anAnimation(someParameters, options);
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredAnimations': function (aSinchronizationType, someAnimations, someOptions) {
+ var deferredResult;
+ var options;
+
+ deferredResult = new Clipperz.Async.Deferred("Visual.deferredParallelAnimations", {trace:false});
+ deferredResult.addCallback(MochiKit.Async.succeed, arguments[arguments.length - 1]);
+
+ options = someOptions;
+ if (MochiKit.Base.isUndefinedOrNull(someOptions['afterFinish'])) {
+ options['afterFinish'] = MochiKit.Base.noop;
+ }
+ MochiKit.Base.update(options, {
+ 'afterFinish': MochiKit.Base.compose(options['afterFinish'], MochiKit.Base.method(deferredResult, 'callback'))
+ });
+
+ new aSinchronizationType(someAnimations, options)
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+
+});
+
+//#############################################################################
+
+/** @id Clipperz.Visual.Resize */
+Clipperz.Visual.Resize = function (element, percent, options) {
+ var cls = arguments.callee;
+ if (!(this instanceof cls)) {
+ return new cls(element, percent, options);
+ }
+ this.__init__(element, percent, options);
+};
+
+Clipperz.Visual.Resize.prototype = new MochiKit.Visual.Base();
+
+MochiKit.Base.update(Clipperz.Visual.Resize.prototype, {
+ __class__ : Clipperz.Visual.Resize,
+
+ __init__: function (element, options) {
+ this.element = MochiKit.DOM.getElement(element);
+ options = MochiKit.Base.update({
+ scaleX: true,
+ scaleY: true,
+ scaleContent: true,
+ scaleFromCenter: false,
+ scaleMode: 'box', // 'box' or 'contents' or {} with provided values
+ syntax_fix: 'syntax fix'
+ }, options);
+
+ this.start(options);
+ },
+
+ setup: function () {
+ this.restoreAfterFinish = this.options.restoreAfterFinish || false;
+ this.elementPositioning = MochiKit.Style.getStyle(this.element, 'position');
+
+ var ma = MochiKit.Base.map;
+ var b = MochiKit.Base.bind;
+ this.originalStyle = {};
+ ma(b(function (k) { this.originalStyle[k] = this.element.style[k]; }, this), ['top', 'left', 'width', 'height', 'fontSize']);
+
+ this.originalTop = this.element.offsetTop;
+ this.originalLeft = this.element.offsetLeft;
+
+ var fontSize = MochiKit.Style.getStyle(this.element, 'font-size') || '100%';
+ ma(b(function (fontSizeType) {
+ if (fontSize.indexOf(fontSizeType) > 0) {
+ this.fontSize = parseFloat(fontSize);
+ this.fontSizeType = fontSizeType;
+ }
+ }, this), ['em', 'px', '%']);
+
+ this.factor = 1;
+
+ this.dims = [this.options.fromSize.h, this.options.fromSize.w];
+ },
+
+ update: function (position) {
+ this.setDimensions( (this.options.toSize.h - this.options.fromSize.h) * position + this.options.fromSize.h,
+ (this.options.toSize.w - this.options.fromSize.w) * position + this.options.fromSize.w);
+ },
+
+ finish: function () {
+ if (this.restoreAfterFinish) {
+ MochiKit.Style.setStyle(this.element, this.originalStyle);
+ }
+ },
+
+ setDimensions: function (height, width) {
+ var d = {};
+ var r = Math.round;
+ if (/MSIE/.test(navigator.userAgent)) {
+ r = Math.ceil;
+ }
+ if (this.options.scaleX) {
+ d.width = r(width) + 'px';
+ }
+ if (this.options.scaleY) {
+ d.height = r(height) + 'px';
+ }
+ if (this.options.scaleFromCenter) {
+ var topd = (height - this.dims[0])/2;
+ var leftd = (width - this.dims[1])/2;
+ if (this.elementPositioning == 'absolute') {
+ if (this.options.scaleY) {
+ d.top = this.originalTop - topd + 'px';
+ }
+ if (this.options.scaleX) {
+ d.left = this.originalLeft - leftd + 'px';
+ }
+ } else {
+ if (this.options.scaleY) {
+ d.top = -topd + 'px';
+ }
+ if (this.options.scaleX) {
+ d.left = -leftd + 'px';
+ }
+ }
+ }
+ MochiKit.Style.setStyle(this.element, d);
+ }
+});
+
+//=============================================================================
+
+Clipperz.Visual.squize = function (element, /* optional */ options) {
+ var d = MochiKit.DOM;
+ var v = MochiKit.Visual;
+ var s = MochiKit.Style;
+
+ element = d.getElement(element);
+ options = MochiKit.Base.update({
+ moveTransition: v.Transitions.sinoidal,
+ scaleTransition: v.Transitions.sinoidal,
+ opacityTransition: v.Transitions.none,
+ scaleContent: true,
+ scaleFromCenter: false,
+ scaleX: true,
+ scaleY: true
+ }, options);
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: s.getStyle(element, 'opacity')
+ };
+
+ var dims = s.getElementDimensions(element, true);
+ var moveX, moveY;
+
+ moveX = options.scaleX ? dims.w/2 : 0;
+ moveY = options.scaleY ? dims.h/2 : 0;
+
+ var elemClip;
+
+ var optionsParallel = MochiKit.Base.update({
+ beforeStartInternal: function (effect) {
+ s.makePositioned(effect.effects[0].element);
+ elemClip = s.makeClipping(effect.effects[0].element);
+ },
+ afterFinishInternal: function (effect) {
+ s.hideElement(effect.effects[0].element);
+ s.undoClipping(effect.effects[0].element, elemClip);
+ s.undoPositioned(effect.effects[0].element);
+ s.setStyle(effect.effects[0].element, oldStyle);
+ }
+ }, options);
+
+ return new v.Parallel(
+ [new v.Opacity(element, {
+ sync: true, to: 0.0, from: 1.0,
+ transition: options.opacityTransition
+ }),
+ new v.Scale(element, /Opera/.test(navigator.userAgent) ? 1 : 0, {
+ scaleMode: {originalHeight: dims.h, originalWidth: dims.w},
+ sync: true, transition: options.scaleTransition,
+ scaleContent: options.scaleContent,
+ scaleFromCenter: options.scaleFromCenter,
+ restoreAfterFinish: true,
+ scaleX: options.scaleX,
+ scaleY: options.scaleY
+ }),
+ new v.Move(element, {
+ x: moveX, y: moveY, sync: true, transition: options.moveTransition
+ })
+ ], optionsParallel
+ );
+};
+
+//-----------------------------------------------------------------------------
+
+Clipperz.Visual.expand = function (element, /* optional */ options) {
+ var d = MochiKit.DOM;
+ var v = MochiKit.Visual;
+ var s = MochiKit.Style;
+
+ element = d.getElement(element);
+ options = MochiKit.Base.update({
+// direction: 'center',
+ moveTransition: v.Transitions.sinoidal,
+ scaleTransition: v.Transitions.sinoidal,
+ opacityTransition: v.Transitions.none,
+ scaleContent: true,
+ scaleFromCenter: false,
+ scaleX: true,
+ scaleY: true
+ }, options);
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: s.getStyle(element, 'opacity')
+ };
+
+ var dims = s.getElementDimensions(element, true);
+ var moveX, moveY;
+
+ moveX = options.scaleX ? dims.w/2 : 0;
+ moveY = options.scaleY ? dims.h/2 : 0;
+
+ var elemClip;
+
+ var optionsParallel = MochiKit.Base.update({
+ beforeStartInternal: function (effect) {
+ s.makePositioned(effect.effects[0].element);
+ elemClip = s.makeClipping(effect.effects[0].element);
+ },
+ afterFinishInternal: function (effect) {
+ s.hideElement(effect.effects[0].element);
+ s.undoClipping(effect.effects[0].element, elemClip);
+ s.undoPositioned(effect.effects[0].element);
+ s.setStyle(effect.effects[0].element, oldStyle);
+ }
+ }, options);
+
+ return new v.Parallel(
+ [new v.Opacity(element, {
+ sync: true, to: 0.0, from: 1.0,
+ transition: options.opacityTransition
+ }),
+ new v.Scale(element, /Opera/.test(navigator.userAgent) ? 1 : 0, {
+ scaleMode: {originalHeight: dims.h, originalWidth: dims.w},
+ sync: true, transition: options.scaleTransition,
+ scaleContent: options.scaleContent,
+ scaleFromCenter: options.scaleFromCenter,
+ restoreAfterFinish: true,
+ scaleX: options.scaleX,
+ scaleY: options.scaleY
+ }),
+ new v.Move(element, {
+ x: moveX, y: moveY, sync: true, transition: options.moveTransition
+ })
+ ], optionsParallel
+ );
+};
+
+//=============================================================================
+
diff --git a/frontend/gamma/js/Clipperz/YUI/DomHelper.js b/frontend/gamma/js/Clipperz/YUI/DomHelper.js
new file mode 100644
index 0000000..dbd8c93
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/YUI/DomHelper.js
@@ -0,0 +1,481 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.YUI) == 'undefined') { Clipperz.YUI = {}; }
+
+
+/**
+ * @class Clipperz.ext.DomHelper
+ * Utility class for working with DOM and/or Templates. It transparently supports using HTML fragments or DOM.
+ * For more information see <a href="http://www.jackslocum.com/yui/2006/10/06/domhelper-create-elements-using-dom-html-fragments-or-templates/">this blog post with examples</a>.
+ * @singleton
+ */
+Clipperz.YUI.DomHelper = new function(){
+ /**@private*/
+ var d = document;
+ var tempTableEl = null;
+ /** True to force the use of DOM instead of html fragments @type Boolean */
+ this.useDom = false;
+ var emptyTags = /^(?:base|basefont|br|frame|hr|img|input|isindex|link|meta|nextid|range|spacer|wbr|audioscope|area|param|keygen|col|limittext|spot|tab|over|right|left|choose|atop|of)$/i;
+ /**
+ * Applies a style specification to an element
+ * @param {String/HTMLElement} el The element to apply styles to
+ * @param {String/Object/Function} styles A style specification string eg "width:100px", or object in the form {width:"100px"}, or
+ * a function which returns such a specification.
+ */
+ this.applyStyles = function(el, styles){
+ if(styles){
+ var D = YAHOO.util.Dom;
+ if (typeof styles == "string"){
+ var re = /\s?([a-z\-]*)\:([^;]*);?/gi;
+ var matches;
+ while ((matches = re.exec(styles)) != null){
+ D.setStyle(el, matches[1], matches[2]);
+ }
+ }else if (typeof styles == "object"){
+ for (var style in styles){
+ D.setStyle(el, style, styles[style]);
+ }
+ }else if (typeof styles == "function"){
+ Clipperz.YUI.DomHelper.applyStyles(el, styles.call());
+ }
+ }
+ };
+
+ // build as innerHTML where available
+ /** @ignore */
+ var createHtml = function(o){
+ var b = '';
+
+ if(typeof(o['html']) != 'undefined') {
+ o['html'] = Clipperz.Base.sanitizeString(o['html']);
+ } else if (typeof(o['htmlString']) != 'undefined') {
+ o['html'] = o['htmlString'];
+ delete o.htmlString;
+ }
+
+ if (MochiKit.Base.isArrayLike(o)) {
+ for (var i = 0, l = o.length; i < l; i++) {
+ b += createHtml(o[i]);
+ }
+ return b;
+ }
+
+ b += '<' + o.tag;
+ for(var attr in o){
+ if(attr == 'tag' || attr == 'children' || attr == 'html' || typeof o[attr] == 'function') continue;
+ if(attr == 'style'){
+ var s = o['style'];
+ if(typeof s == 'function'){
+ s = s.call();
+ }
+ if(typeof s == 'string'){
+ b += ' style="' + s + '"';
+ }else if(typeof s == 'object'){
+ b += ' style="';
+ for(var key in s){
+ if(typeof s[key] != 'function'){
+ b += key + ':' + s[key] + ';';
+ }
+ }
+ b += '"';
+ }
+ }else{
+ if(attr == 'cls'){
+ b += ' class="' + o['cls'] + '"';
+ }else if(attr == 'htmlFor'){
+ b += ' for="' + o['htmlFor'] + '"';
+ }else{
+ b += ' ' + attr + '="' + o[attr] + '"';
+ }
+ }
+ }
+ if(emptyTags.test(o.tag)){
+ b += ' />';
+ }else{
+ b += '>';
+ if(o.children){
+ for(var i = 0, len = o.children.length; i < len; i++) {
+ b += createHtml(o.children[i], b);
+ }
+ }
+ if(o.html){
+ b += o.html;
+ }
+ b += '</' + o.tag + '>';
+ }
+ return b;
+ }
+
+ // build as dom
+ /** @ignore */
+ var createDom = function(o, parentNode){
+ var el = d.createElement(o.tag);
+ var useSet = el.setAttribute ? true : false; // In IE some elements don't have setAttribute
+ for(var attr in o){
+ if(attr == 'tag' || attr == 'children' || attr == 'html' || attr == 'style' || typeof o[attr] == 'function') continue;
+ if(attr=='cls'){
+ el.className = o['cls'];
+ }else{
+ if(useSet) el.setAttribute(attr, o[attr]);
+ else el[attr] = o[attr];
+ }
+ }
+ Clipperz.YUI.DomHelper.applyStyles(el, o.style);
+ if(o.children){
+ for(var i = 0, len = o.children.length; i < len; i++) {
+ createDom(o.children[i], el);
+ }
+ }
+ if(o.html){
+ el.innerHTML = o.html;
+ }
+ if(parentNode){
+ parentNode.appendChild(el);
+ }
+ return el;
+ };
+
+ /**
+ * @ignore
+ * Nasty code for IE's broken table implementation
+ */
+ var insertIntoTable = function(tag, where, el, html){
+ if(!tempTableEl){
+ tempTableEl = document.createElement('div');
+ }
+ var nodes;
+ if(tag == 'table' || tag == 'tbody'){
+ tempTableEl.innerHTML = '<table><tbody>'+html+'</tbody></table>';
+ nodes = tempTableEl.firstChild.firstChild.childNodes;
+ }else{
+ tempTableEl.innerHTML = '<table><tbody><tr>'+html+'</tr></tbody></table>';
+ nodes = tempTableEl.firstChild.firstChild.firstChild.childNodes;
+ }
+ if (where == 'beforebegin') {
+ nodes.reverse();
+// el.parentNode.insertBefore(node, el);
+ MochiKit.Base.map(function(aNode) {el.parentNode.insertBefore(aNode, el)}, nodes);
+ } else if (where == 'afterbegin') {
+ nodes.reverse();
+// el.insertBefore(node, el.firstChild);
+ MochiKit.Base.map(function(aNode) {el.insertBefore(aNode, el.firstChild)}, nodes);
+ } else if (where == 'beforeend') {
+// el.appendChild(node);
+ MochiKit.Base.map(function(aNode) {el.appendChild(aNode)}, nodes);
+ } else if (where == 'afterend') {
+// el.parentNode.insertBefore(node, el.nextSibling);
+ MochiKit.Base.map(function(aNode) {el.parentNode.insertBefore(aNode, el.nextSibling)}, nodes);
+ }
+
+ return nodes;
+ }
+
+ /**
+ * Inserts an HTML fragment into the Dom
+ * @param {String} where Where to insert the html in relation to el - beforeBegin, afterBegin, beforeEnd, afterEnd.
+ * @param {HTMLElement} el The context element
+ * @param {String} html The HTML fragmenet
+ * @return {HTMLElement} The new node
+ */
+ this.insertHtml = function(where, el, html){
+ where = where.toLowerCase();
+// if(el.insertAdjacentHTML){
+ if(Clipperz_IEisBroken){
+ var tag = el.tagName.toLowerCase();
+ if(tag == 'table' || tag == 'tbody' || tag == 'tr'){
+ return insertIntoTable(tag, where, el, html);
+ }
+ switch(where){
+ case 'beforebegin':
+ el.insertAdjacentHTML(where, html);
+ return el.previousSibling;
+ case 'afterbegin':
+ el.insertAdjacentHTML(where, html);
+ return el.firstChild;
+ case 'beforeend':
+ el.insertAdjacentHTML(where, html);
+ return el.lastChild;
+ case 'afterend':
+ el.insertAdjacentHTML(where, html);
+ return el.nextSibling;
+ }
+ throw 'Illegal insertion point -> "' + where + '"';
+ }
+ var range = el.ownerDocument.createRange();
+ var frag;
+ switch(where){
+ case 'beforebegin':
+ range.setStartBefore(el);
+ frag = range.createContextualFragment(html);
+ el.parentNode.insertBefore(frag, el);
+ return el.previousSibling;
+ case 'afterbegin':
+ if(el.firstChild){ // faster
+ range.setStartBefore(el.firstChild);
+ }else{
+ range.selectNodeContents(el);
+ range.collapse(true);
+ }
+ frag = range.createContextualFragment(html);
+ el.insertBefore(frag, el.firstChild);
+ return el.firstChild;
+ case 'beforeend':
+ if(el.lastChild){
+ range.setStartAfter(el.lastChild); // faster
+ }else{
+ range.selectNodeContents(el);
+ range.collapse(false);
+ }
+ frag = range.createContextualFragment(html);
+ el.appendChild(frag);
+ return el.lastChild;
+ case 'afterend':
+ range.setStartAfter(el);
+ frag = range.createContextualFragment(html);
+ el.parentNode.insertBefore(frag, el.nextSibling);
+ return el.nextSibling;
+ }
+ throw 'Illegal insertion point -> "' + where + '"';
+ };
+
+ /**
+ * Creates new Dom element(s) and inserts them before el
+ * @param {String/HTMLElement/Element} el The context element
+ * @param {Object} o The Dom object spec (and children)
+ * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
+ * @return {HTMLElement} The new node
+ */
+ this.insertBefore = function(el, o, returnElement){
+ el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
+ var newNode;
+ if(this.useDom){
+ newNode = createDom(o, null);
+ el.parentNode.insertBefore(newNode, el);
+ }else{
+ var html = createHtml(o);
+ newNode = this.insertHtml('beforeBegin', el, html);
+ }
+ return returnElement ? YAHOO.Element.get(newNode, true) : newNode;
+ };
+
+ /**
+ * Creates new Dom element(s) and inserts them after el
+ * @param {String/HTMLElement/Element} el The context element
+ * @param {Object} o The Dom object spec (and children)
+ * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
+ * @return {HTMLElement} The new node
+ */
+ this.insertAfter = function(el, o, returnElement){
+ el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
+ var newNode;
+ if(this.useDom){
+ newNode = createDom(o, null);
+ el.parentNode.insertBefore(newNode, el.nextSibling);
+ }else{
+ var html = createHtml(o);
+ newNode = this.insertHtml('afterEnd', el, html);
+ }
+ return returnElement ? YAHOO.Element.get(newNode, true) : newNode;
+ };
+
+ /**
+ * Creates new Dom element(s) and appends them to el
+ * @param {String/HTMLElement/Element} el The context element
+ * @param {Object} o The Dom object spec (and children)
+ * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
+ * @return {HTMLElement} The new node
+ */
+ this.append = function(el, o, returnElement){
+ el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
+ var newNode;
+ if(this.useDom){
+ newNode = createDom(o, null);
+ el.appendChild(newNode);
+ }else{
+ var html = createHtml(o);
+ newNode = this.insertHtml('beforeEnd', el, html);
+ }
+ return returnElement ? YAHOO.Element.get(newNode, true) : newNode;
+ };
+
+ /**
+ * Creates new Dom element(s) and overwrites the contents of el with them
+ * @param {String/HTMLElement/Element} el The context element
+ * @param {Object} o The Dom object spec (and children)
+ * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
+ * @return {HTMLElement} The new node
+ */
+ this.overwrite = function(el, o, returnElement){
+ el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
+ el.innerHTML = createHtml(o);
+ return returnElement ? YAHOO.Element.get(el.firstChild, true) : el.firstChild;
+ };
+
+ /**
+ * Creates a new Clipperz.YUI.DomHelper.Template from the Dom object spec
+ * @param {Object} o The Dom object spec (and children)
+ * @return {Clipperz.YUI.DomHelper.Template} The new template
+ */
+ this.createTemplate = function(o){
+ var html = createHtml(o);
+ return new Clipperz.YUI.DomHelper.Template(html);
+ };
+}();
+
+/**
+* @class Clipperz.YUI.DomHelper.Template
+* Represents an HTML fragment template.
+* For more information see <a href="http://www.jackslocum.com/yui/2006/10/06/domhelper-create-elements-using-dom-html-fragments-or-templates/">this blog post with examples</a>.
+* <br>
+* <b>This class is also available as Clipperz.YUI.Template</b>.
+* @constructor
+* @param {String/Array} html The HTML fragment or an array of fragments to join('') or multiple arguments to join('')
+*/
+Clipperz.YUI.DomHelper.Template = function(html){
+ if(html instanceof Array){
+ html = html.join('');
+ }else if(arguments.length > 1){
+ html = Array.prototype.join.call(arguments, '');
+ }
+ /**@private*/
+ this.html = html;
+};
+Clipperz.YUI.DomHelper.Template.prototype = {
+ /**
+ * Returns an HTML fragment of this template with the specified values applied
+ * @param {Object} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
+ * @return {String}
+ */
+ applyTemplate : function(values){
+ if(this.compiled){
+ return this.compiled(values);
+ }
+ var empty = '';
+ var fn = function(match, index){
+ if(typeof values[index] != 'undefined'){
+ return values[index];
+ }else{
+ return empty;
+ }
+ }
+ return this.html.replace(this.re, fn);
+ },
+
+ /**
+ * The regular expression used to match template variables
+ * @type RegExp
+ * @property
+ */
+ re : /\{([\w|-]+)\}/g,
+
+ /**
+ * Compiles the template into an internal function, eliminating the RegEx overhead
+ */
+ compile : function(){
+ var body = ["this.compiled = function(values){ return ['"];
+ body.push(this.html.replace(this.re, "', values['$1'], '"));
+ body.push("'].join('');};");
+ eval(body.join(''));
+ return this;
+ },
+
+ /**
+ * Applies the supplied values to the template and inserts the new node(s) before el
+ * @param {String/HTMLElement/Element} el The context element
+ * @param {Object} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
+ * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
+ * @return {HTMLElement} The new node
+ */
+ insertBefore: function(el, values, returnElement){
+ el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
+ var newNode = Clipperz.YUI.DomHelper.insertHtml('beforeBegin', el, this.applyTemplate(values));
+ return returnElement ? YAHOO.Element.get(newNode, true) : newNode;
+ },
+
+ /**
+ * Applies the supplied values to the template and inserts the new node(s) after el
+ * @param {String/HTMLElement/Element} el The context element
+ * @param {Object} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
+ * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
+ * @return {HTMLElement} The new node
+ */
+ insertAfter : function(el, values, returnElement){
+ el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
+ var newNode = Clipperz.YUI.DomHelper.insertHtml('afterEnd', el, this.applyTemplate(values));
+ return returnElement ? YAHOO.Element.get(newNode, true) : newNode;
+ },
+
+ /**
+ * Applies the supplied values to the template and append the new node(s) to el
+ * @param {String/HTMLElement/Element} el The context element
+ * @param {Object} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
+ * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
+ * @return {HTMLElement} The new node
+ */
+ append : function(el, values, returnElement){
+ var sanitizedValues;
+ var key;
+
+// sanitizedValues = MochiKit.Base.map(sanitizedValues)
+//console.log("values", values);
+ sanitizedValues = {};
+ for (key in values) {
+ sanitizedValues[key] = Clipperz.Base.sanitizeString(values[key]);
+ }
+//console.log("sanitizedValues", sanitizedValues);
+// el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
+ el = (typeof el == 'string') ? YAHOO.util.Dom.get(el) : el;
+//Clipperz.log(this.applyTemplate(sanitizedValues));
+ var newNode = Clipperz.YUI.DomHelper.insertHtml('beforeEnd', el, this.applyTemplate(sanitizedValues));
+// return returnElement ? YAHOO.Element.get(newNode, true) : newNode;
+ return newNode;
+ },
+
+ /**
+ * Applies the supplied values to the template and overwrites the content of el with the new node(s)
+ * @param {String/HTMLElement/Element} el The context element
+ * @param {Object} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
+ * @param {<i>Boolean</i>} returnElement (optional) true to return a YAHOO.Element
+ * @return {HTMLElement} The new node
+ */
+ overwrite : function(el, values, returnElement){
+ el = el.dom ? el.dom : YAHOO.util.Dom.get(el);
+ el.innerHTML = '';
+ var newNode = Clipperz.YUI.DomHelper.insertHtml('beforeEnd', el, this.applyTemplate(values));
+ return returnElement ? YAHOO.Element.get(newNode, true) : newNode;
+ }
+};
+/**
+ * Alias for applyTemplate
+ * @method
+ */
+Clipperz.YUI.DomHelper.Template.prototype.apply = Clipperz.YUI.DomHelper.Template.prototype.applyTemplate;
+
+Clipperz.YUI.Template = Clipperz.YUI.DomHelper.Template;
diff --git a/frontend/gamma/js/Clipperz/YUI/DomQuery.js b/frontend/gamma/js/Clipperz/YUI/DomQuery.js
new file mode 100644
index 0000000..4a143ab
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/YUI/DomQuery.js
@@ -0,0 +1,714 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof(Clipperz) == 'undefined') { Clipperz = {}; }
+if (typeof(Clipperz.YUI) == 'undefined') { Clipperz.YUI = {}; }
+
+
+/*
+ * yui-ext 0.40
+ * Copyright(c) 2006, Jack Slocum.
+ */
+
+/**
+ * @class Clipperz.YUI.DomQuery
+ * Provides high performance selector/xpath processing by compiling queries into reusable functions.
+ * New pseudo classes and matchers can be plugged. It works on HTML and XML documents (if a content node is passed in).
+ * @singleton
+ */
+Clipperz.YUI.DomQuery = function(){
+ var cache = {}, simpleCache = {}, valueCache = {};
+ var nonSpace = /\S/;
+ var trimRe = /^\s*(.*?)\s*$/;
+ var tplRe = /\{(\d+)\}/g;
+ var modeRe = /^(\s?[\/>]\s?|\s|$)/;
+ var clsRes = {};
+
+ function child(p, index){
+ var i = 0;
+ var n = p.firstChild;
+ while(n){
+ if(n.nodeType == 1){
+ i++;
+ if(i == index){
+ return n;
+ }
+ }
+ n = n.nextSibling;
+ }
+ return null;
+ };
+
+ function next(d){
+ var n = d.nextSibling;
+ while(n && n.nodeType != 1){
+ n = n.nextSibling;
+ }
+ return n;
+ };
+
+ function prev(d){
+ var n = d.previousSibling;
+ while(n && n.nodeType != 1){
+ n = n.previousSibling;
+ }
+ return n;
+ };
+
+ function clean(d){
+ var n = d.firstChild, ni = -1;
+ while(n){
+ var nx = n.nextSibling;
+ if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
+ d.removeChild(n);
+ }else{
+ n.nodeIndex = ++ni;
+ }
+ n = nx;
+ }
+ return this;
+ };
+
+ function byClassName(c, a, v){
+ if(!v){
+ return c;
+ }
+ var re = clsRes[v];
+ if(!re){
+ re = new RegExp('(?:^|\\s)(?:' + v + ')(?:\\s|$)');
+ clsRes[v] = re;
+ }
+ var r = [];
+ for(var i = 0, ci; ci = c[i]; i++){
+ if(re.test(ci.className)){
+ r[r.length] = ci;
+ }
+ }
+ return r;
+ };
+
+ function convert(c){
+ if(c.slice){
+ return c;
+ }
+ var r = [];
+ for(var i = 0, l = c.length; i < l; i++){
+ r[r.length] = c[i];
+ }
+ return r;
+ };
+
+ function attrValue(n, attr){
+ if(!n.tagName && typeof n.length != 'undefined'){
+ n = n[0];
+ }
+ if(!n){
+ return null;
+ }
+ if(attr == 'for'){
+ return n.htmlFor;
+ }
+ if(attr == 'class' || attr == 'className'){
+ return n.className;
+ }
+ return n.getAttribute(attr) || n[attr];
+
+ };
+
+ function getNodes(ns, mode, tagName){
+ var result = [], cs;
+ if(!ns){
+ return result;
+ }
+ mode = mode ? mode.replace(trimRe, '$1') : '';
+ tagName = tagName || '*';
+ if(ns.tagName || ns == document){
+ ns = [ns];
+ }
+ if(mode != '/' && mode != '>'){
+ for(var i = 0, ni; ni = ns[i]; i++){
+ cs = ni.getElementsByTagName(tagName);
+ result = concat(result, cs);
+ }
+ }else{
+ for(var i = 0, ni; ni = ns[i]; i++){
+ var cn = ni.getElementsByTagName(tagName);
+ for(var j = 0, cj; cj = cn[j]; j++){
+ if(cj.parentNode == ni){
+ result[result.length] = cj;
+ }
+ }
+ }
+
+ }
+ return result;
+ };
+
+ function concat(a, b){
+ if(b.slice){
+ return a.concat(b);
+ }
+ for(var i = 0, l = b.length; i < l; i++){
+ a[a.length] = b[i];
+ }
+ return a;
+ }
+
+ function byTag(cs, tagName){
+ if(cs.tagName || cs == document){
+ cs = [cs];
+ }
+ if(!tagName){
+ return cs;
+ }
+ var r = []; tagName = tagName.toLowerCase();
+ for(var i = 0, ci; ci = cs[i]; i++){
+ if(ci.nodeType == 1 && ci.tagName.toLowerCase()==tagName){
+ r[r.length] = ci;
+ }
+ }
+ return r;
+ };
+
+ function byId(cs, attr, id){
+ if(cs.tagName || cs == document){
+ cs = [cs];
+ }
+ if(!id){
+ return cs;
+ }
+ var r = [];
+ for(var i = 0, l = cs.length; i < l; i++){
+ var ci = cs[i];
+ if(ci && ci.id == id){
+ r[r.length] = ci;
+ }
+ }
+ return r;
+ };
+
+ function byAttribute(cs, attr, value, op, custom){
+ var r = [], st = custom=='{';
+ var f = Clipperz.YUI.DomQuery.operators[op];
+ for(var i = 0, l = cs.length; i < l; i++){
+ var a;
+ if(st){
+ a = Clipperz.YUI.DomQuery.getStyle(cs[i], attr);
+ }
+ else if(attr == 'class' || attr == 'className'){
+ a = cs[i].className;
+ }else if(attr == 'for'){
+ a = cs[i].htmlFor;
+ }else{
+ a = cs[i].getAttribute(attr);
+ }
+ if((f && f(a, value)) || (!f && a)){
+ r[r.length] = cs[i];
+ }
+ }
+ return r;
+ };
+
+ function byPseudo(cs, name, value){
+ return Clipperz.YUI.DomQuery.pseudos[name](cs, value);
+ };
+
+ // This is for IE MSXML which does not support expandos.
+ // IE runs the same speed using setAttribute, however FF slows way down
+ // and Safari completely fails so they need to continue to use expandos.
+ // Branched at load time for faster execution.
+ var isIE = window.ActiveXObject;
+ var addAttr = isIE ?
+ function(n, a, v){
+ n.setAttribute(a, v);
+ } :
+ function(n, a, v){
+ n[a] = v;
+ };
+ var getAttr = isIE ?
+ function(n, a){
+ return n.getAttribute(a);
+ } :
+ function(n, a){
+ return n[a];
+ };
+ var clearAttr = isIE ?
+ function(n, a){
+ n.removeAttribute(a);
+ } :
+ function(n, a, v){
+ delete n[a];
+ };
+
+ function nodup(cs){
+ if(!cs.length){
+ return cs;
+ }
+ addAttr(cs[0], '_nodup', true);
+ var r = [cs[0]];
+ for(var i = 1, len = cs.length; i < len; i++){
+ var c = cs[i];
+ if(!getAttr(c, '_nodup')){
+ addAttr(c, '_nodup', true);
+ r[r.length] = c;
+ }
+ }
+ for(var i = 0, len = cs.length; i < len; i++){
+ clearAttr(cs[i], '_nodup');
+ }
+ return r;
+ }
+
+ function quickDiff(c1, c2){
+ if(!c1.length){
+ return c2;
+ }
+ for(var i = 0, len = c1.length; i < len; i++){
+ addAttr(c1[i], '_qdiff', true);
+ }
+ var r = [];
+ for(var i = 0, len = c2.length; i < len; i++){
+ if(!getAttr(c2[i], '_qdiff')){
+ r[r.length] = c2[i];
+ }
+ }
+ for(var i = 0, len = c1.length; i < len; i++){
+ clearAttr(c1[i], '_qdiff');
+ }
+ return r;
+ }
+
+ function quickId(ns, mode, root, id){
+ if(ns == root){
+ var d = root.ownerDocument || root;
+ return d.getElementById(id);
+ }
+ ns = getNodes(ns, mode, '*');
+ return byId(ns, null, id);
+ }
+
+ return {
+ getStyle : function(el, name){
+ return YAHOO.util.Dom.getStyle(el, name);
+ },
+ /**
+ * Compiles a selector/xpath query into a reusable function. The returned function
+ * takes one parameter "root" (optional), which is the context node from where the query should start.
+ * @param {String} selector The selector/xpath query
+ * @param {String} type (optional) Either 'select' (the default) or 'simple' for a simple selector match
+ * @return {Function}
+ */
+ compile : function(path, type){
+ // strip leading slashes
+ while(path.substr(0, 1)=='/'){
+ path = path.substr(1);
+ }
+ type = type || 'select';
+
+ var fn = ['var f = function(root){\n var mode; var n = root || document;\n'];
+ var q = path, mode, lq;
+ var tk = Clipperz.YUI.DomQuery.matchers;
+ var tklen = tk.length;
+ var mm;
+ while(q && lq != q){
+ lq = q;
+ var tm = q.match(/^(#)?([\w-\*]+)/);
+ if(type == 'select'){
+ if(tm){
+ if(tm[1] == '#'){
+ fn[fn.length] = 'n = quickId(n, mode, root, "'+tm[2]+'");';
+ }else{
+ fn[fn.length] = 'n = getNodes(n, mode, "'+tm[2]+'");';
+ }
+ q = q.replace(tm[0], '');
+ }else{
+ fn[fn.length] = 'n = getNodes(n, mode, "*");';
+ }
+ }else{
+ if(tm){
+ if(tm[1] == '#'){
+ fn[fn.length] = 'n = byId(n, null, "'+tm[2]+'");';
+ }else{
+ fn[fn.length] = 'n = byTag(n, "'+tm[2]+'");';
+ }
+ q = q.replace(tm[0], '');
+ }
+ }
+ while(!(mm = q.match(modeRe))){
+ var matched = false;
+ for(var j = 0; j < tklen; j++){
+ var t = tk[j];
+ var m = q.match(t.re);
+ if(m){
+ fn[fn.length] = t.select.replace(tplRe, function(x, i){
+ return m[i];
+ });
+ q = q.replace(m[0], '');
+ matched = true;
+ break;
+ }
+ }
+ // prevent infinite loop on bad selector
+ if(!matched){
+ throw 'Error parsing selector, parsing failed at "' + q + '"';
+ }
+ }
+ if(mm[1]){
+ fn[fn.length] = 'mode="'+mm[1]+'";';
+ q = q.replace(mm[1], '');
+ }
+ }
+ fn[fn.length] = 'return nodup(n);\n}';
+ eval(fn.join(''));
+ return f;
+ },
+
+ /**
+ * Selects a group of elements.
+ * @param {String} selector The selector/xpath query
+ * @param {Node} root (optional) The start of the query (defaults to document).
+ * @return {Array}
+ */
+ select : function(path, root, type){
+ if(!root || root == document){
+ root = document;
+ }
+ if(typeof root == 'string'){
+ root = document.getElementById(root);
+ }
+ var paths = path.split(',');
+ var results = [];
+ for(var i = 0, len = paths.length; i < len; i++){
+ var p = paths[i].replace(trimRe, '$1');
+ if(!cache[p]){
+ cache[p] = Clipperz.YUI.DomQuery.compile(p);
+ if(!cache[p]){
+ throw p + ' is not a valid selector';
+ }
+ }
+ var result = cache[p](root);
+ if(result && result != document){
+ results = results.concat(result);
+ }
+ }
+ return results;
+ },
+
+ /**
+ * Selects a single element.
+ * @param {String} selector The selector/xpath query
+ * @param {Node} root (optional) The start of the query (defaults to document).
+ * @return {Element}
+ */
+ selectNode : function(path, root){
+ return Clipperz.YUI.DomQuery.select(path, root)[0];
+ },
+
+ /**
+ * Selects the value of a node, optionally replacing null with the defaultValue.
+ * @param {String} selector The selector/xpath query
+ * @param {Node} root (optional) The start of the query (defaults to document).
+ * @param {String} defaultValue
+ */
+ selectValue : function(path, root, defaultValue){
+ path = path.replace(trimRe, '$1');
+ if(!valueCache[path]){
+ valueCache[path] = Clipperz.YUI.DomQuery.compile(path, 'simple');
+ }
+ var n = valueCache[path](root);
+ n = n[0] ? n[0] : n;
+ var v = (n && n.firstChild ? n.firstChild.nodeValue : null);
+ return (v === null ? defaultValue : v);
+ },
+
+ /**
+ * Selects the value of a node, parsing integers and floats.
+ * @param {String} selector The selector/xpath query
+ * @param {Node} root (optional) The start of the query (defaults to document).
+ * @param {Number} defaultValue
+ * @return {Number}
+ */
+ selectNumber : function(path, root, defaultValue){
+ var v = Clipperz.YUI.DomQuery.selectValue(path, root, defaultValue || 0);
+ return parseFloat(v);
+ },
+
+ /**
+ * Returns true if the passed element(s) match the passed simple selector (e.g. div.some-class or span:first-child)
+ * @param {String/HTMLElement/Array} el An element id, element or array of elements
+ * @param {String} selector The simple selector to test
+ * @return {Boolean}
+ */
+ is : function(el, ss){
+ if(typeof el == 'string'){
+ el = document.getElementById(el);
+ }
+ var isArray = (el instanceof Array);
+ var result = Clipperz.YUI.DomQuery.filter(isArray ? el : [el], ss);
+ return isArray ? (result.length == el.length) : (result.length > 0);
+ },
+
+ /**
+ * Filters an array of elements to only include matches of a simple selector (e.g. div.some-class or span:first-child)
+ * @param {Array} el An array of elements to filter
+ * @param {String} selector The simple selector to test
+ * @param {Boolean} nonMatches If true, it returns the elements that DON'T match
+ * the selector instead of the ones that match
+ * @return {Array}
+ */
+ filter : function(els, ss, nonMatches){
+ ss = ss.replace(trimRe, '$1');
+ if(!simpleCache[ss]){
+ simpleCache[ss] = Clipperz.YUI.DomQuery.compile(ss, 'simple');
+ }
+ var result = simpleCache[ss](els);
+ return nonMatches ? quickDiff(result, els) : result;
+ },
+
+ /**
+ * Collection of matching regular expressions and code snippets.
+ */
+ matchers : [{
+ re: /^\.([\w-]+)/,
+ select: 'n = byClassName(n, null, "{1}");'
+ }, {
+ re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
+ select: 'n = byPseudo(n, "{1}", "{2}");'
+ },{
+ re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
+ select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
+ }, {
+ re: /^#([\w-]+)/,
+ select: 'n = byId(n, null, "{1}");'
+ },{
+ re: /^@([\w-]+)/,
+ select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
+ }
+ ],
+
+ /**
+ * Collection of operator comparison functions. The default operators are =, !=, ^=, $=, *= and %=.
+ * New operators can be added as long as the match the format <i>c</i>= where <i>c<i> is any character other than space, &gt; &lt;.
+ */
+ operators : {
+ '=' : function(a, v){
+ return a == v;
+ },
+ '!=' : function(a, v){
+ return a != v;
+ },
+ '^=' : function(a, v){
+ return a && a.substr(0, v.length) == v;
+ },
+ '$=' : function(a, v){
+ return a && a.substr(a.length-v.length) == v;
+ },
+ '*=' : function(a, v){
+ return a && a.indexOf(v) !== -1;
+ },
+ '%=' : function(a, v){
+ return (a % v) == 0;
+ }
+ },
+
+ /**
+ * Collection of "pseudo class" processors. Each processor is passed the current nodeset (array)
+ * and the argument (if any) supplied in the selector.
+ */
+ pseudos : {
+ 'first-child' : function(c){
+ var r = [];
+ for(var i = 0, l = c.length; i < l; i++){
+ var ci = c[i];
+ if(!prev(ci)){
+ r[r.length] = ci;
+ }
+ }
+ return r;
+ },
+
+ 'last-child' : function(c){
+ var r = [];
+ for(var i = 0, l = c.length; i < l; i++){
+ var ci = c[i];
+ if(!next(ci)){
+ r[r.length] = ci;
+ }
+ }
+ return r;
+ },
+
+ 'nth-child' : function(c, a){
+ var r = [];
+ if(a != 'odd' && a != 'even'){
+ for(var i = 0, ci; ci = c[i]; i++){
+ var m = child(ci.parentNode, a);
+ if(m == ci){
+ r[r.length] = m;
+ }
+ }
+ return r;
+ }
+ var p;
+ // first let's clean up the parent nodes
+ for(var i = 0, l = c.length; i < l; i++){
+ var cp = c[i].parentNode;
+ if(cp != p){
+ clean(cp);
+ p = cp;
+ }
+ }
+ // then lets see if we match
+ for(var i = 0, l = c.length; i < l; i++){
+ var ci = c[i], m = false;
+ if(a == 'odd'){
+ m = ((ci.nodeIndex+1) % 2 == 1);
+ }else if(a == 'even'){
+ m = ((ci.nodeIndex+1) % 2 == 0);
+ }
+ if(m){
+ r[r.length] = ci;
+ }
+ }
+ return r;
+ },
+
+ 'only-child' : function(c){
+ var r = [];
+ for(var i = 0, l = c.length; i < l; i++){
+ var ci = c[i];
+ if(!prev(ci) && !next(ci)){
+ r[r.length] = ci;
+ }
+ }
+ return r;
+ },
+
+ 'empty' : function(c){
+ var r = [];
+ for(var i = 0, l = c.length; i < l; i++){
+ var ci = c[i];
+ if(!ci.firstChild){
+ r[r.length] = ci;
+ }
+ }
+ return r;
+ },
+
+ 'contains' : function(c, v){
+ var r = [];
+ for(var i = 0, l = c.length; i < l; i++){
+ var ci = c[i];
+ if(ci.innerHTML.indexOf(v) !== -1){
+ r[r.length] = ci;
+ }
+ }
+ return r;
+ },
+
+ 'checked' : function(c){
+ var r = [];
+ for(var i = 0, l = c.length; i < l; i++){
+ if(c[i].checked == 'checked'){
+ r[r.length] = c[i];
+ }
+ }
+ return r;
+ },
+
+ 'not' : function(c, ss){
+ return Clipperz.YUI.DomQuery.filter(c, ss, true);
+ },
+
+ 'odd' : function(c){
+ return this['nth-child'](c, 'odd');
+ },
+
+ 'even' : function(c){
+ return this['nth-child'](c, 'even');
+ },
+
+ 'nth' : function(c, a){
+ return c[a-1];
+ },
+
+ 'first' : function(c){
+ return c[0];
+ },
+
+ 'last' : function(c){
+ return c[c.length-1];
+ },
+
+ 'has' : function(c, ss){
+ var s = Clipperz.YUI.DomQuery.select;
+ var r = [];
+ for(var i = 0, ci; ci = c[i]; i++){
+ if(s(ss, ci).length > 0){
+ r[r.length] = ci;
+ }
+ }
+ return r;
+ },
+
+ 'next' : function(c, ss){
+ var is = Clipperz.YUI.DomQuery.is;
+ var r = [];
+ for(var i = 0, ci; ci = c[i]; i++){
+ var n = next(ci);
+ if(n && is(n, ss)){
+ r[r.length] = ci;
+ }
+ }
+ return r;
+ },
+
+ 'prev' : function(c, ss){
+ var is = Clipperz.YUI.DomQuery.is;
+ var r = [];
+ for(var i = 0, ci; ci = c[i]; i++){
+ var n = prev(ci);
+ if(n && is(n, ss)){
+ r[r.length] = ci;
+ }
+ }
+ return r;
+ }
+ }
+ };
+}();
+
+/**
+ * Selects an array of DOM nodes by CSS/XPath selector. Shorthand of {@link Clipperz.YUI.DomQuery#select}
+ * @param {String} path The selector/xpath query
+ * @param {Node} root (optional) The start of the query (defaults to document).
+ * @return {Array}
+ * @member Ext
+ * @method query
+ */
+Clipperz.YUI.query = Clipperz.YUI.DomQuery.select;
diff --git a/frontend/gamma/js/Clipperz/YUI/Utils.js b/frontend/gamma/js/Clipperz/YUI/Utils.js
new file mode 100644
index 0000000..4d4a5f9
--- a/dev/null
+++ b/frontend/gamma/js/Clipperz/YUI/Utils.js
@@ -0,0 +1,98 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+if (typeof YAHOO == 'undefined') { YAHOO = {}; };
+if (typeof YAHOO.util == 'undefined') { YAHOO.util = {}; };
+if (typeof YAHOO.util.Dom == 'undefined') { YAHOO.util.Dom = {}; };
+
+YAHOO.extend = function(subc, superc, overrides) {
+ var F = function() {};
+ F.prototype=superc.prototype;
+ subc.prototype=new F();
+ subc.prototype.constructor=subc;
+ subc.superclass=superc.prototype;
+ if (superc.prototype.constructor == Object.prototype.constructor) {
+ superc.prototype.constructor=superc;
+ }
+
+ if (overrides) {
+ for (var i in overrides) {
+ subc.prototype[i]=overrides[i];
+ }
+ }
+};
+
+YAHOO.override = function(origclass, overrides){
+ if(overrides){
+ var p = origclass.prototype;
+ for(var method in overrides){
+ p[method] = overrides[method];
+ }
+ }
+};
+
+YAHOO.extendX = function(subclass, superclass, overrides){
+ YAHOO.extend(subclass, superclass);
+ subclass.override = function(o){
+ YAHOO.override(subclass, o);
+ };
+ if(!subclass.prototype.override){
+ subclass.prototype.override = function(o){
+ for(var method in o){
+ this[method] = o[method];
+ }
+ };
+ }
+ if(overrides){
+ subclass.override(overrides);
+ };
+
+};
+
+YAHOO.util.Dom.get = function(el) {
+ if (!el) { return null; } // nothing to work with
+
+ if (typeof el != 'string' && !(el instanceof Array) ) { // assuming HTMLElement or HTMLCollection, so pass back as is
+ return el;
+ }
+
+ if (typeof el == 'string') { // ID
+ return document.getElementById(el);
+ }
+ else { // array of ID's and/or elements
+ var collection = [];
+ for (var i = 0, len = el.length; i < len; ++i) {
+ collection[collection.length] = YAHOO.util.Dom.get(el[i]);
+ }
+
+ return collection;
+ }
+
+ return null; // safety, should never happen
+};
+
diff --git a/frontend/gamma/js/JSON/json2.js b/frontend/gamma/js/JSON/json2.js
new file mode 100644
index 0000000..b67e167
--- a/dev/null
+++ b/frontend/gamma/js/JSON/json2.js
@@ -0,0 +1,481 @@
+/*
+ http://www.JSON.org/json2.js
+ 2008-09-01
+
+ Public Domain.
+
+ NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+ See http://www.JSON.org/js.html
+
+ This file creates a global JSON object containing two methods: stringify
+ and parse.
+
+ JSON.stringify(value, replacer, space)
+ value any JavaScript value, usually an object or array.
+
+ replacer an optional parameter that determines how object
+ values are stringified for objects. It can be a
+ function or an array of strings.
+
+ space an optional parameter that specifies the indentation
+ of nested structures. If it is omitted, the text will
+ be packed without extra whitespace. If it is a number,
+ it will specify the number of spaces to indent at each
+ level. If it is a string (such as '\t' or '&nbsp;'),
+ it contains the characters used to indent at each level.
+
+ This method produces a JSON text from a JavaScript value.
+
+ When an object value is found, if the object contains a toJSON
+ method, its toJSON method will be called and the result will be
+ stringified. A toJSON method does not serialize: it returns the
+ value represented by the name/value pair that should be serialized,
+ or undefined if nothing should be serialized. The toJSON method
+ will be passed the key associated with the value, and this will be
+ bound to the object holding the key.
+
+ For example, this would serialize Dates as ISO strings.
+
+ Date.prototype.toJSON = function (key) {
+ function f(n) {
+ // Format integers to have at least two digits.
+ return n < 10 ? '0' + n : n;
+ }
+
+ return this.getUTCFullYear() + '-' +
+ f(this.getUTCMonth() + 1) + '-' +
+ f(this.getUTCDate()) + 'T' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + 'Z';
+ };
+
+ You can provide an optional replacer method. It will be passed the
+ key and value of each member, with this bound to the containing
+ object. The value that is returned from your method will be
+ serialized. If your method returns undefined, then the member will
+ be excluded from the serialization.
+
+ If the replacer parameter is an array of strings, then it will be used to
+ select the members to be serialized. It filters the results such
+ that only members with keys listed in the replacer array are
+ stringified.
+
+ Values that do not have JSON representations, such as undefined or
+ functions, will not be serialized. Such values in objects will be
+ dropped; in arrays they will be replaced with null. You can use
+ a replacer function to replace those with JSON values.
+ JSON.stringify(undefined) returns undefined.
+
+ The optional space parameter produces a stringification of the
+ value that is filled with line breaks and indentation to make it
+ easier to read.
+
+ If the space parameter is a non-empty string, then that string will
+ be used for indentation. If the space parameter is a number, then
+ the indentation will be that many spaces.
+
+ Example:
+
+ text = JSON.stringify(['e', {pluribus: 'unum'}]);
+ // text is '["e",{"pluribus":"unum"}]'
+
+
+ text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
+ // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+ text = JSON.stringify([new Date()], function (key, value) {
+ return this[key] instanceof Date ?
+ 'Date(' + this[key] + ')' : value;
+ });
+ // text is '["Date(---current time---)"]'
+
+
+ JSON.parse(text, reviver)
+ This method parses a JSON text to produce an object or array.
+ It can throw a SyntaxError exception.
+
+ The optional reviver parameter is a function that can filter and
+ transform the results. It receives each of the keys and values,
+ and its return value is used instead of the original value.
+ If it returns what it received, then the structure is not modified.
+ If it returns undefined then the member is deleted.
+
+ Example:
+
+ // Parse the text. Values that look like ISO date strings will
+ // be converted to Date objects.
+
+ myData = JSON.parse(text, function (key, value) {
+ var a;
+ if (typeof value === 'string') {
+ a =
+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+ if (a) {
+ return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+ +a[5], +a[6]));
+ }
+ }
+ return value;
+ });
+
+ myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+ var d;
+ if (typeof value === 'string' &&
+ value.slice(0, 5) === 'Date(' &&
+ value.slice(-1) === ')') {
+ d = new Date(value.slice(5, -1));
+ if (d) {
+ return d;
+ }
+ }
+ return value;
+ });
+
+
+ This is a reference implementation. You are free to copy, modify, or
+ redistribute.
+
+ This code should be minified before deployment.
+ See http://javascript.crockford.com/jsmin.html
+
+ USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+ NOT CONTROL.
+*/
+
+/*jslint evil: true */
+
+/*global JSON */
+
+/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", call,
+ charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, getUTCMinutes,
+ getUTCMonth, getUTCSeconds, hasOwnProperty, join, lastIndex, length,
+ parse, propertyIsEnumerable, prototype, push, replace, slice, stringify,
+ test, toJSON, toString, valueOf
+*/
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+if (!this.JSON) {
+ JSON = {};
+}
+(function () {
+
+ function f(n) {
+ // Format integers to have at least two digits.
+ return n < 10 ? '0' + n : n;
+ }
+
+ if (typeof Date.prototype.toJSON !== 'function') {
+
+ Date.prototype.toJSON = function (key) {
+
+ return this.getUTCFullYear() + '-' +
+ f(this.getUTCMonth() + 1) + '-' +
+ f(this.getUTCDate()) + 'T' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + 'Z';
+ };
+
+ String.prototype.toJSON =
+ Number.prototype.toJSON =
+ Boolean.prototype.toJSON = function (key) {
+ return this.valueOf();
+ };
+ }
+
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ escapeable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ gap,
+ indent,
+ meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ },
+ rep;
+
+
+ function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+ escapeable.lastIndex = 0;
+ return escapeable.test(string) ?
+ '"' + string.replace(escapeable, function (a) {
+ var c = meta[a];
+ if (typeof c === 'string') {
+ return c;
+ }
+ return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ }) + '"' :
+ '"' + string + '"';
+ }
+
+
+ function str(key, holder) {
+
+// Produce a string from holder[key].
+
+ var i, // The loop counter.
+ k, // The member key.
+ v, // The member value.
+ length,
+ mind = gap,
+ partial,
+ value = holder[key];
+
+// If the value has a toJSON method, call it to obtain a replacement value.
+
+ if (value && typeof value === 'object' &&
+ typeof value.toJSON === 'function') {
+ value = value.toJSON(key);
+ }
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+ if (typeof rep === 'function') {
+ value = rep.call(holder, key, value);
+ }
+
+// What happens next depends on the value's type.
+
+ switch (typeof value) {
+ case 'string':
+ return quote(value);
+
+ case 'number':
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+ return isFinite(value) ? String(value) : 'null';
+
+ case 'boolean':
+ case 'null':
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce 'null'. The case is included here in
+// the remote chance that this gets fixed someday.
+
+ return String(value);
+
+// If the type is 'object', we might be dealing with an object or an array or
+// null.
+
+ case 'object':
+
+// Due to a specification blunder in ECMAScript, typeof null is 'object',
+// so watch out for that case.
+
+ if (!value) {
+ return 'null';
+ }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+ gap += indent;
+ partial = [];
+
+// If the object has a dontEnum length property, we'll treat it as an array.
+
+ if (typeof value.length === 'number' &&
+ !value.propertyIsEnumerable('length')) {
+
+// The object is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+ length = value.length;
+ for (i = 0; i < length; i += 1) {
+ partial[i] = str(i, value) || 'null';
+ }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+ v = partial.length === 0 ? '[]' :
+ gap ? '[\n' + gap +
+ partial.join(',\n' + gap) + '\n' +
+ mind + ']' :
+ '[' + partial.join(',') + ']';
+ gap = mind;
+ return v;
+ }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+ if (rep && typeof rep === 'object') {
+ length = rep.length;
+ for (i = 0; i < length; i += 1) {
+ k = rep[i];
+ if (typeof k === 'string') {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+ for (k in value) {
+ if (Object.hasOwnProperty.call(value, k)) {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+ v = partial.length === 0 ? '{}' :
+ gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+ mind + '}' : '{' + partial.join(',') + '}';
+ gap = mind;
+ return v;
+ }
+ }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+ if (typeof JSON.stringify !== 'function') {
+ JSON.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+ var i;
+ gap = '';
+ indent = '';
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+ if (typeof space === 'number') {
+ for (i = 0; i < space; i += 1) {
+ indent += ' ';
+ }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+ } else if (typeof space === 'string') {
+ indent = space;
+ }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+ rep = replacer;
+ if (replacer && typeof replacer !== 'function' &&
+ (typeof replacer !== 'object' ||
+ typeof replacer.length !== 'number')) {
+ throw new Error('JSON.stringify');
+ }
+
+// Make a fake root object containing our value under the key of ''.
+// Return the result of stringifying the value.
+
+ return str('', {'': value});
+ };
+ }
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+ if (typeof JSON.parse !== 'function') {
+ JSON.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+ var j;
+
+ function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+ var k, v, value = holder[key];
+ if (value && typeof value === 'object') {
+ for (k in value) {
+ if (Object.hasOwnProperty.call(value, k)) {
+ v = walk(value, k);
+ if (v !== undefined) {
+ value[k] = v;
+ } else {
+ delete value[k];
+ }
+ }
+ }
+ }
+ return reviver.call(holder, key, value);
+ }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+ cx.lastIndex = 0;
+ if (cx.test(text)) {
+ text = text.replace(cx, function (a) {
+ return '\\u' +
+ ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ });
+ }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+ if (/^[\],:{}\s]*$/.
+test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
+replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+ j = eval('(' + text + ')');
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+ return typeof reviver === 'function' ?
+ walk({'': j}, '') : j;
+ }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+ throw new SyntaxError('JSON.parse');
+ };
+ }
+})(); \ No newline at end of file
diff --git a/frontend/gamma/js/MochiKit/Async.js b/frontend/gamma/js/MochiKit/Async.js
new file mode 100644
index 0000000..c7408e7
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Async.js
@@ -0,0 +1,640 @@
+/***
+
+MochiKit.Async 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('Async', '1.5', ['Base']);
+
+/** @id MochiKit.Async.Deferred */
+MochiKit.Async.Deferred = function (/* optional */ canceller) {
+ this.chain = [];
+ this.id = this._nextId();
+ this.fired = -1;
+ this.paused = 0;
+ this.results = [null, null];
+ this.canceller = canceller;
+ this.silentlyCancelled = false;
+ this.chained = false;
+};
+
+MochiKit.Async.Deferred.prototype = {
+ /** @id MochiKit.Async.Deferred.prototype.repr */
+ repr: function () {
+ var state;
+ if (this.fired == -1) {
+ state = 'unfired';
+ } else if (this.fired === 0) {
+ state = 'success';
+ } else {
+ state = 'error';
+ }
+ return 'Deferred(' + this.id + ', ' + state + ')';
+ },
+
+ toString: MochiKit.Base.forwardCall("repr"),
+
+ _nextId: MochiKit.Base.counter(),
+
+ /** @id MochiKit.Async.Deferred.prototype.cancel */
+ cancel: function () {
+ var self = MochiKit.Async;
+ if (this.fired == -1) {
+ if (this.canceller) {
+ this.canceller(this);
+ } else {
+ this.silentlyCancelled = true;
+ }
+ if (this.fired == -1) {
+ this.errback(new self.CancelledError(this));
+ }
+ } else if ((this.fired === 0) && (this.results[0] instanceof self.Deferred)) {
+ this.results[0].cancel();
+ }
+ },
+
+ _resback: function (res) {
+ /***
+
+ The primitive that means either callback or errback
+
+ ***/
+ this.fired = ((res instanceof Error) ? 1 : 0);
+ this.results[this.fired] = res;
+ this._fire();
+ },
+
+ _check: function () {
+ if (this.fired != -1) {
+ if (!this.silentlyCancelled) {
+ throw new MochiKit.Async.AlreadyCalledError(this);
+ }
+ this.silentlyCancelled = false;
+ return;
+ }
+ },
+
+ /** @id MochiKit.Async.Deferred.prototype.callback */
+ callback: function (res) {
+ this._check();
+ if (res instanceof MochiKit.Async.Deferred) {
+ throw new Error("Deferred instances can only be chained if they are the result of a callback");
+ }
+ this._resback(res);
+ },
+
+ /** @id MochiKit.Async.Deferred.prototype.errback */
+ errback: function (res) {
+ this._check();
+ var self = MochiKit.Async;
+ if (res instanceof self.Deferred) {
+ throw new Error("Deferred instances can only be chained if they are the result of a callback");
+ }
+ if (!(res instanceof Error)) {
+ res = new self.GenericError(res);
+ }
+ this._resback(res);
+ },
+
+ /** @id MochiKit.Async.Deferred.prototype.addBoth */
+ addBoth: function (fn) {
+ if (arguments.length > 1) {
+ fn = MochiKit.Base.partial.apply(null, arguments);
+ }
+ return this.addCallbacks(fn, fn);
+ },
+
+ /** @id MochiKit.Async.Deferred.prototype.addCallback */
+ addCallback: function (fn) {
+ if (arguments.length > 1) {
+ fn = MochiKit.Base.partial.apply(null, arguments);
+ }
+ return this.addCallbacks(fn, null);
+ },
+
+ /** @id MochiKit.Async.Deferred.prototype.addErrback */
+ addErrback: function (fn) {
+ if (arguments.length > 1) {
+ fn = MochiKit.Base.partial.apply(null, arguments);
+ }
+ return this.addCallbacks(null, fn);
+ },
+
+ /** @id MochiKit.Async.Deferred.prototype.addCallbacks */
+ addCallbacks: function (cb, eb) {
+ if (this.chained) {
+ throw new Error("Chained Deferreds can not be re-used");
+ }
+ this.chain.push([cb, eb]);
+ if (this.fired >= 0) {
+ this._fire();
+ }
+ return this;
+ },
+
+ _fire: function () {
+ /***
+
+ Used internally to exhaust the callback sequence when a result
+ is available.
+
+ ***/
+ var chain = this.chain;
+ var fired = this.fired;
+ var res = this.results[fired];
+ var self = this;
+ var cb = null;
+ while (chain.length > 0 && this.paused === 0) {
+ // Array
+ var pair = chain.shift();
+ var f = pair[fired];
+ if (f === null) {
+ continue;
+ }
+ try {
+ res = f(res);
+ fired = ((res instanceof Error) ? 1 : 0);
+ if (res instanceof MochiKit.Async.Deferred) {
+ cb = function (res) {
+ self._resback(res);
+ self.paused--;
+ if ((self.paused === 0) && (self.fired >= 0)) {
+ self._fire();
+ }
+ };
+ this.paused++;
+ }
+ } catch (err) {
+ fired = 1;
+ if (!(err instanceof Error)) {
+ err = new MochiKit.Async.GenericError(err);
+ }
+ res = err;
+ }
+ }
+ this.fired = fired;
+ this.results[fired] = res;
+ if (cb && this.paused) {
+ // this is for "tail recursion" in case the dependent deferred
+ // is already fired
+ res.addBoth(cb);
+ res.chained = true;
+ }
+ }
+};
+
+MochiKit.Base.update(MochiKit.Async, {
+ /** @id MochiKit.Async.evalJSONRequest */
+ evalJSONRequest: function (req) {
+ return MochiKit.Base.evalJSON(req.responseText);
+ },
+
+ /** @id MochiKit.Async.succeed */
+ succeed: function (/* optional */result) {
+ var d = new MochiKit.Async.Deferred();
+ d.callback.apply(d, arguments);
+ return d;
+ },
+
+ /** @id MochiKit.Async.fail */
+ fail: function (/* optional */result) {
+ var d = new MochiKit.Async.Deferred();
+ d.errback.apply(d, arguments);
+ return d;
+ },
+
+ /** @id MochiKit.Async.getXMLHttpRequest */
+ getXMLHttpRequest: function () {
+ var self = arguments.callee;
+ if (!self.XMLHttpRequest) {
+ var tryThese = [
+ function () { return new XMLHttpRequest(); },
+ function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
+ function () { return new ActiveXObject('Microsoft.XMLHTTP'); },
+ function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); },
+ function () {
+ throw new MochiKit.Async.BrowserComplianceError("Browser does not support XMLHttpRequest");
+ }
+ ];
+ for (var i = 0; i < tryThese.length; i++) {
+ var func = tryThese[i];
+ try {
+ self.XMLHttpRequest = func;
+ return func();
+ } catch (e) {
+ // pass
+ }
+ }
+ }
+ return self.XMLHttpRequest();
+ },
+
+ _xhr_onreadystatechange: function (d) {
+ // MochiKit.Logging.logDebug('this.readyState', this.readyState);
+ var m = MochiKit.Base;
+ if (this.readyState == 4) {
+ // IE SUCKS
+ try {
+ this.onreadystatechange = null;
+ } catch (e) {
+ try {
+ this.onreadystatechange = m.noop;
+ } catch (e) {
+ }
+ }
+ var status = null;
+ try {
+ status = this.status;
+ if (!status && m.isNotEmpty(this.responseText)) {
+ // 0 or undefined seems to mean cached or local
+ status = 304;
+ }
+ } catch (e) {
+ // pass
+ // MochiKit.Logging.logDebug('error getting status?', repr(items(e)));
+ }
+ // 200 is OK, 201 is CREATED, 204 is NO CONTENT
+ // 304 is NOT MODIFIED, 1223 is apparently a bug in IE
+ if (status == 200 || status == 201 || status == 204 ||
+ status == 304 || status == 1223) {
+ d.callback(this);
+ } else {
+ var err = new MochiKit.Async.XMLHttpRequestError(this, "Request failed");
+ if (err.number) {
+ // XXX: This seems to happen on page change
+ d.errback(err);
+ } else {
+ // XXX: this seems to happen when the server is unreachable
+ d.errback(err);
+ }
+ }
+ }
+ },
+
+ _xhr_canceller: function (req) {
+ // IE SUCKS
+ try {
+ req.onreadystatechange = null;
+ } catch (e) {
+ try {
+ req.onreadystatechange = MochiKit.Base.noop;
+ } catch (e) {
+ }
+ }
+ req.abort();
+ },
+
+
+ /** @id MochiKit.Async.sendXMLHttpRequest */
+ sendXMLHttpRequest: function (req, /* optional */ sendContent) {
+ if (typeof(sendContent) == "undefined" || sendContent === null) {
+ sendContent = "";
+ }
+
+ var m = MochiKit.Base;
+ var self = MochiKit.Async;
+ var d = new self.Deferred(m.partial(self._xhr_canceller, req));
+
+ try {
+ req.onreadystatechange = m.bind(self._xhr_onreadystatechange,
+ req, d);
+ req.send(sendContent);
+ } catch (e) {
+ try {
+ req.onreadystatechange = null;
+ } catch (ignore) {
+ // pass
+ }
+ d.errback(e);
+ }
+
+ return d;
+
+ },
+
+ /** @id MochiKit.Async.doXHR */
+ doXHR: function (url, opts) {
+ /*
+ Work around a Firefox bug by dealing with XHR during
+ the next event loop iteration. Maybe it's this one:
+ https://bugzilla.mozilla.org/show_bug.cgi?id=249843
+ */
+ var self = MochiKit.Async;
+ return self.callLater(0, self._doXHR, url, opts);
+ },
+
+ _doXHR: function (url, opts) {
+ var m = MochiKit.Base;
+ opts = m.update({
+ method: 'GET',
+ sendContent: ''
+ /*
+ queryString: undefined,
+ username: undefined,
+ password: undefined,
+ headers: undefined,
+ mimeType: undefined
+ */
+ }, opts);
+ var self = MochiKit.Async;
+ var req = self.getXMLHttpRequest();
+ if (opts.queryString) {
+ var qs = m.queryString(opts.queryString);
+ if (qs) {
+ url += "?" + qs;
+ }
+ }
+ // Safari will send undefined:undefined, so we have to check.
+ // We can't use apply, since the function is native.
+ if ('username' in opts) {
+ req.open(opts.method, url, true, opts.username, opts.password);
+ } else {
+ req.open(opts.method, url, true);
+ }
+ if (req.overrideMimeType && opts.mimeType) {
+ req.overrideMimeType(opts.mimeType);
+ }
+ req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ if (opts.headers) {
+ var headers = opts.headers;
+ if (!m.isArrayLike(headers)) {
+ headers = m.items(headers);
+ }
+ for (var i = 0; i < headers.length; i++) {
+ var header = headers[i];
+ var name = header[0];
+ var value = header[1];
+ req.setRequestHeader(name, value);
+ }
+ }
+ return self.sendXMLHttpRequest(req, opts.sendContent);
+ },
+
+ _buildURL: function (url/*, ...*/) {
+ if (arguments.length > 1) {
+ var m = MochiKit.Base;
+ var qs = m.queryString.apply(null, m.extend(null, arguments, 1));
+ if (qs) {
+ return url + "?" + qs;
+ }
+ }
+ return url;
+ },
+
+ /** @id MochiKit.Async.doSimpleXMLHttpRequest */
+ doSimpleXMLHttpRequest: function (url/*, ...*/) {
+ var self = MochiKit.Async;
+ url = self._buildURL.apply(self, arguments);
+ return self.doXHR(url);
+ },
+
+ /** @id MochiKit.Async.loadJSONDoc */
+ loadJSONDoc: function (url/*, ...*/) {
+ var self = MochiKit.Async;
+ url = self._buildURL.apply(self, arguments);
+ var d = self.doXHR(url, {
+ 'mimeType': 'text/plain',
+ 'headers': [['Accept', 'application/json']]
+ });
+ d = d.addCallback(self.evalJSONRequest);
+ return d;
+ },
+
+ /** @id MochiKit.Async.wait */
+ wait: function (seconds, /* optional */value) {
+ var d = new MochiKit.Async.Deferred();
+ var m = MochiKit.Base;
+ if (typeof(value) != 'undefined') {
+ d.addCallback(function () { return value; });
+ }
+ var timeout = setTimeout(
+ m.bind("callback", d),
+ Math.floor(seconds * 1000));
+ d.canceller = function () {
+ try {
+ clearTimeout(timeout);
+ } catch (e) {
+ // pass
+ }
+ };
+ return d;
+ },
+
+ /** @id MochiKit.Async.callLater */
+ callLater: function (seconds, func) {
+ var m = MochiKit.Base;
+ var pfunc = m.partial.apply(m, m.extend(null, arguments, 1));
+ return MochiKit.Async.wait(seconds).addCallback(
+ function (res) { return pfunc(); }
+ );
+ }
+});
+
+
+/** @id MochiKit.Async.DeferredLock */
+MochiKit.Async.DeferredLock = function () {
+ this.waiting = [];
+ this.locked = false;
+ this.id = this._nextId();
+};
+
+MochiKit.Async.DeferredLock.prototype = {
+ __class__: MochiKit.Async.DeferredLock,
+ /** @id MochiKit.Async.DeferredLock.prototype.acquire */
+ acquire: function () {
+ var d = new MochiKit.Async.Deferred();
+ if (this.locked) {
+ this.waiting.push(d);
+ } else {
+ this.locked = true;
+ d.callback(this);
+ }
+ return d;
+ },
+ /** @id MochiKit.Async.DeferredLock.prototype.release */
+ release: function () {
+ if (!this.locked) {
+ throw TypeError("Tried to release an unlocked DeferredLock");
+ }
+ this.locked = false;
+ if (this.waiting.length > 0) {
+ this.locked = true;
+ this.waiting.shift().callback(this);
+ }
+ },
+ _nextId: MochiKit.Base.counter(),
+ repr: function () {
+ var state;
+ if (this.locked) {
+ state = 'locked, ' + this.waiting.length + ' waiting';
+ } else {
+ state = 'unlocked';
+ }
+ return 'DeferredLock(' + this.id + ', ' + state + ')';
+ },
+ toString: MochiKit.Base.forwardCall("repr")
+
+};
+
+/** @id MochiKit.Async.DeferredList */
+MochiKit.Async.DeferredList = function (list, /* optional */fireOnOneCallback, fireOnOneErrback, consumeErrors, canceller) {
+
+ // call parent constructor
+ MochiKit.Async.Deferred.apply(this, [canceller]);
+
+ this.list = list;
+ var resultList = [];
+ this.resultList = resultList;
+
+ this.finishedCount = 0;
+ this.fireOnOneCallback = fireOnOneCallback;
+ this.fireOnOneErrback = fireOnOneErrback;
+ this.consumeErrors = consumeErrors;
+
+ var cb = MochiKit.Base.bind(this._cbDeferred, this);
+ for (var i = 0; i < list.length; i++) {
+ var d = list[i];
+ resultList.push(undefined);
+ d.addCallback(cb, i, true);
+ d.addErrback(cb, i, false);
+ }
+
+ if (list.length === 0 && !fireOnOneCallback) {
+ this.callback(this.resultList);
+ }
+
+};
+
+MochiKit.Async.DeferredList.prototype = new MochiKit.Async.Deferred();
+
+MochiKit.Async.DeferredList.prototype._cbDeferred = function (index, succeeded, result) {
+ this.resultList[index] = [succeeded, result];
+ this.finishedCount += 1;
+ if (this.fired == -1) {
+ if (succeeded && this.fireOnOneCallback) {
+ this.callback([index, result]);
+ } else if (!succeeded && this.fireOnOneErrback) {
+ this.errback(result);
+ } else if (this.finishedCount == this.list.length) {
+ this.callback(this.resultList);
+ }
+ }
+ if (!succeeded && this.consumeErrors) {
+ result = null;
+ }
+ return result;
+};
+
+/** @id MochiKit.Async.gatherResults */
+MochiKit.Async.gatherResults = function (deferredList) {
+ var d = new MochiKit.Async.DeferredList(deferredList, false, true, false);
+ d.addCallback(function (results) {
+ var ret = [];
+ for (var i = 0; i < results.length; i++) {
+ ret.push(results[i][1]);
+ }
+ return ret;
+ });
+ return d;
+};
+
+/** @id MochiKit.Async.maybeDeferred */
+MochiKit.Async.maybeDeferred = function (func) {
+ var self = MochiKit.Async;
+ var result;
+ try {
+ var r = func.apply(null, MochiKit.Base.extend([], arguments, 1));
+ if (r instanceof self.Deferred) {
+ result = r;
+ } else if (r instanceof Error) {
+ result = self.fail(r);
+ } else {
+ result = self.succeed(r);
+ }
+ } catch (e) {
+ result = self.fail(e);
+ }
+ return result;
+};
+
+
+MochiKit.Async.__new__ = function () {
+ var m = MochiKit.Base;
+ var ne = m.partial(m._newNamedError, this);
+
+ ne("AlreadyCalledError",
+ /** @id MochiKit.Async.AlreadyCalledError */
+ function (deferred) {
+ /***
+
+ Raised by the Deferred if callback or errback happens
+ after it was already fired.
+
+ ***/
+ this.deferred = deferred;
+ }
+ );
+
+ ne("CancelledError",
+ /** @id MochiKit.Async.CancelledError */
+ function (deferred) {
+ /***
+
+ Raised by the Deferred cancellation mechanism.
+
+ ***/
+ this.deferred = deferred;
+ }
+ );
+
+ ne("BrowserComplianceError",
+ /** @id MochiKit.Async.BrowserComplianceError */
+ function (msg) {
+ /***
+
+ Raised when the JavaScript runtime is not capable of performing
+ the given function. Technically, this should really never be
+ raised because a non-conforming JavaScript runtime probably
+ isn't going to support exceptions in the first place.
+
+ ***/
+ this.message = msg;
+ }
+ );
+
+ ne("GenericError",
+ /** @id MochiKit.Async.GenericError */
+ function (msg) {
+ this.message = msg;
+ }
+ );
+
+ ne("XMLHttpRequestError",
+ /** @id MochiKit.Async.XMLHttpRequestError */
+ function (req, msg) {
+ /***
+
+ Raised when an XMLHttpRequest does not complete for any reason.
+
+ ***/
+ this.req = req;
+ this.message = msg;
+ try {
+ // Strange but true that this can raise in some cases.
+ this.number = req.status;
+ } catch (e) {
+ // pass
+ }
+ }
+ );
+
+ m.nameFunctions(this);
+};
+
+MochiKit.Async.__new__();
+
+MochiKit.Base._exportSymbols(this, MochiKit.Async);
diff --git a/frontend/gamma/js/MochiKit/Base.js b/frontend/gamma/js/MochiKit/Base.js
new file mode 100644
index 0000000..d33c269
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Base.js
@@ -0,0 +1,1452 @@
+/***
+
+MochiKit.Base 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito. All rights Reserved.
+
+***/
+
+if (typeof(MochiKit) == 'undefined') {
+ MochiKit = {};
+}
+if (typeof(MochiKit.__export__) == "undefined") {
+ MochiKit.__export__ = true;
+}
+if (typeof(MochiKit.Base) == 'undefined') {
+ MochiKit.Base = {};
+}
+
+/**
+ * Registers a new MochiKit module. This function will insert a new
+ * property into the "MochiKit" object, making sure that all
+ * dependency modules have already been inserted. It will also make
+ * sure that the appropriate properties and default module functions
+ * are defined.
+ *
+ * @param {String} name the module name, e.g. "Base"
+ * @param {String} version the module version, e.g. "1.5"
+ * @param {Array} deps the array of module dependencies (as strings)
+ */
+MochiKit.Base._module = function (name, version, deps) {
+ if (!(name in MochiKit)) {
+ MochiKit[name] = {};
+ }
+ var module = MochiKit[name];
+ module.NAME = "MochiKit." + name;
+ module.VERSION = version;
+ module.__repr__ = function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+ };
+ module.toString = function () {
+ return this.__repr__();
+ };
+ for (var i = 0; i < deps.length; i++) {
+ if (!(deps[i] in MochiKit)) {
+ throw 'MochiKit.' + name + ' depends on MochiKit.' + deps[i] + '!';
+ }
+ }
+}
+
+MochiKit.Base._module("Base", "1.5", []);
+
+/** @id MochiKit.Base.update */
+MochiKit.Base.update = function (self, obj/*, ... */) {
+ if (self === null || self === undefined) {
+ self = {};
+ }
+ for (var i = 1; i < arguments.length; i++) {
+ var o = arguments[i];
+ if (typeof(o) != 'undefined' && o !== null) {
+ for (var k in o) {
+ self[k] = o[k];
+ }
+ }
+ }
+ return self;
+};
+
+MochiKit.Base.update(MochiKit.Base, {
+ /** @id MochiKit.Base.camelize */
+ camelize: function (selector) {
+ /* from dojo.style.toCamelCase */
+ var arr = selector.split('-');
+ var cc = arr[0];
+ for (var i = 1; i < arr.length; i++) {
+ cc += arr[i].charAt(0).toUpperCase() + arr[i].substring(1);
+ }
+ return cc;
+ },
+
+ /** @id MochiKit.Base.counter */
+ counter: function (n/* = 1 */) {
+ if (arguments.length === 0) {
+ n = 1;
+ }
+ return function () {
+ return n++;
+ };
+ },
+
+ /** @id MochiKit.Base.clone */
+ clone: function (obj) {
+ var me = arguments.callee;
+ if (arguments.length == 1) {
+ me.prototype = obj;
+ return new me();
+ }
+ },
+
+ _flattenArray: function (res, lst) {
+ for (var i = 0; i < lst.length; i++) {
+ var o = lst[i];
+ if (o instanceof Array) {
+ arguments.callee(res, o);
+ } else {
+ res.push(o);
+ }
+ }
+ return res;
+ },
+
+ /** @id MochiKit.Base.flattenArray */
+ flattenArray: function (lst) {
+ return MochiKit.Base._flattenArray([], lst);
+ },
+
+ /** @id MochiKit.Base.flattenArguments */
+ flattenArguments: function (lst/* ...*/) {
+ var res = [];
+ var m = MochiKit.Base;
+ var args = m.extend(null, arguments);
+ while (args.length) {
+ var o = args.shift();
+ if (o && typeof(o) == "object" && typeof(o.length) == "number") {
+ for (var i = o.length - 1; i >= 0; i--) {
+ args.unshift(o[i]);
+ }
+ } else {
+ res.push(o);
+ }
+ }
+ return res;
+ },
+
+ /** @id MochiKit.Base.extend */
+ extend: function (self, obj, /* optional */skip) {
+ // Extend an array with an array-like object starting
+ // from the skip index
+ if (!skip) {
+ skip = 0;
+ }
+ if (obj) {
+ // allow iterable fall-through, but skip the full isArrayLike
+ // check for speed, this is called often.
+ var l = obj.length;
+ if (typeof(l) != 'number' /* !isArrayLike(obj) */) {
+ if (typeof(MochiKit.Iter) != "undefined") {
+ obj = MochiKit.Iter.list(obj);
+ l = obj.length;
+ } else {
+ throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+ }
+ }
+ if (!self) {
+ self = [];
+ }
+ for (var i = skip; i < l; i++) {
+ self.push(obj[i]);
+ }
+ }
+ // This mutates, but it's convenient to return because
+ // it's often used like a constructor when turning some
+ // ghetto array-like to a real array
+ return self;
+ },
+
+
+ /** @id MochiKit.Base.updatetree */
+ updatetree: function (self, obj/*, ...*/) {
+ if (self === null || self === undefined) {
+ self = {};
+ }
+ for (var i = 1; i < arguments.length; i++) {
+ var o = arguments[i];
+ if (typeof(o) != 'undefined' && o !== null) {
+ for (var k in o) {
+ var v = o[k];
+ if (typeof(self[k]) == 'object' && typeof(v) == 'object') {
+ arguments.callee(self[k], v);
+ } else {
+ self[k] = v;
+ }
+ }
+ }
+ }
+ return self;
+ },
+
+ /** @id MochiKit.Base.setdefault */
+ setdefault: function (self, obj/*, ...*/) {
+ if (self === null || self === undefined) {
+ self = {};
+ }
+ for (var i = 1; i < arguments.length; i++) {
+ var o = arguments[i];
+ for (var k in o) {
+ if (!(k in self)) {
+ self[k] = o[k];
+ }
+ }
+ }
+ return self;
+ },
+
+ /** @id MochiKit.Base.keys */
+ keys: function (obj) {
+ var rval = [];
+ for (var prop in obj) {
+ rval.push(prop);
+ }
+ return rval;
+ },
+
+ /** @id MochiKit.Base.values */
+ values: function (obj) {
+ var rval = [];
+ for (var prop in obj) {
+ rval.push(obj[prop]);
+ }
+ return rval;
+ },
+
+ /** @id MochiKit.Base.items */
+ items: function (obj) {
+ var rval = [];
+ var e;
+ for (var prop in obj) {
+ var v;
+ try {
+ v = obj[prop];
+ } catch (e) {
+ continue;
+ }
+ rval.push([prop, v]);
+ }
+ return rval;
+ },
+
+
+ _newNamedError: function (module, name, func) {
+ func.prototype = new MochiKit.Base.NamedError(module.NAME + "." + name);
+ module[name] = func;
+ },
+
+
+ /** @id MochiKit.Base.operator */
+ operator: {
+ // unary logic operators
+ /** @id MochiKit.Base.truth */
+ truth: function (a) { return !!a; },
+ /** @id MochiKit.Base.lognot */
+ lognot: function (a) { return !a; },
+ /** @id MochiKit.Base.identity */
+ identity: function (a) { return a; },
+
+ // bitwise unary operators
+ /** @id MochiKit.Base.not */
+ not: function (a) { return ~a; },
+ /** @id MochiKit.Base.neg */
+ neg: function (a) { return -a; },
+
+ // binary operators
+ /** @id MochiKit.Base.add */
+ add: function (a, b) { return a + b; },
+ /** @id MochiKit.Base.sub */
+ sub: function (a, b) { return a - b; },
+ /** @id MochiKit.Base.div */
+ div: function (a, b) { return a / b; },
+ /** @id MochiKit.Base.mod */
+ mod: function (a, b) { return a % b; },
+ /** @id MochiKit.Base.mul */
+ mul: function (a, b) { return a * b; },
+
+ // bitwise binary operators
+ /** @id MochiKit.Base.and */
+ and: function (a, b) { return a & b; },
+ /** @id MochiKit.Base.or */
+ or: function (a, b) { return a | b; },
+ /** @id MochiKit.Base.xor */
+ xor: function (a, b) { return a ^ b; },
+ /** @id MochiKit.Base.lshift */
+ lshift: function (a, b) { return a << b; },
+ /** @id MochiKit.Base.rshift */
+ rshift: function (a, b) { return a >> b; },
+ /** @id MochiKit.Base.zrshift */
+ zrshift: function (a, b) { return a >>> b; },
+
+ // near-worthless built-in comparators
+ /** @id MochiKit.Base.eq */
+ eq: function (a, b) { return a == b; },
+ /** @id MochiKit.Base.ne */
+ ne: function (a, b) { return a != b; },
+ /** @id MochiKit.Base.gt */
+ gt: function (a, b) { return a > b; },
+ /** @id MochiKit.Base.ge */
+ ge: function (a, b) { return a >= b; },
+ /** @id MochiKit.Base.lt */
+ lt: function (a, b) { return a < b; },
+ /** @id MochiKit.Base.le */
+ le: function (a, b) { return a <= b; },
+
+ // strict built-in comparators
+ seq: function (a, b) { return a === b; },
+ sne: function (a, b) { return a !== b; },
+
+ // compare comparators
+ /** @id MochiKit.Base.ceq */
+ ceq: function (a, b) { return MochiKit.Base.compare(a, b) === 0; },
+ /** @id MochiKit.Base.cne */
+ cne: function (a, b) { return MochiKit.Base.compare(a, b) !== 0; },
+ /** @id MochiKit.Base.cgt */
+ cgt: function (a, b) { return MochiKit.Base.compare(a, b) == 1; },
+ /** @id MochiKit.Base.cge */
+ cge: function (a, b) { return MochiKit.Base.compare(a, b) != -1; },
+ /** @id MochiKit.Base.clt */
+ clt: function (a, b) { return MochiKit.Base.compare(a, b) == -1; },
+ /** @id MochiKit.Base.cle */
+ cle: function (a, b) { return MochiKit.Base.compare(a, b) != 1; },
+
+ // binary logical operators
+ /** @id MochiKit.Base.logand */
+ logand: function (a, b) { return a && b; },
+ /** @id MochiKit.Base.logor */
+ logor: function (a, b) { return a || b; },
+ /** @id MochiKit.Base.contains */
+ contains: function (a, b) { return b in a; }
+ },
+
+ /** @id MochiKit.Base.forwardCall */
+ forwardCall: function (func) {
+ return function () {
+ return this[func].apply(this, arguments);
+ };
+ },
+
+ /** @id MochiKit.Base.itemgetter */
+ itemgetter: function (func) {
+ return function (arg) {
+ return arg[func];
+ };
+ },
+
+ /** @id MochiKit.Base.bool */
+ bool: function (value) {
+ if (typeof(value) === "boolean" || value instanceof Boolean) {
+ return value.valueOf();
+ } else if (typeof(value) === "string" || value instanceof String) {
+ return value.length > 0 && value != "false" && value != "null" &&
+ value != "undefined" && value != "0";
+ } else if (typeof(value) === "number" || value instanceof Number) {
+ return !isNaN(value) && value != 0;
+ } else if (value != null && typeof(value.length) === "number") {
+ return value.length !== 0
+ } else {
+ return value != null;
+ }
+ },
+
+ /** @id MochiKit.Base.typeMatcher */
+ typeMatcher: function (/* typ */) {
+ var types = {};
+ for (var i = 0; i < arguments.length; i++) {
+ var typ = arguments[i];
+ types[typ] = typ;
+ }
+ return function () {
+ for (var i = 0; i < arguments.length; i++) {
+ if (!(typeof(arguments[i]) in types)) {
+ return false;
+ }
+ }
+ return true;
+ };
+ },
+
+ /** @id MochiKit.Base.isNull */
+ isNull: function (/* ... */) {
+ for (var i = 0; i < arguments.length; i++) {
+ if (arguments[i] !== null) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /** @id MochiKit.Base.isUndefinedOrNull */
+ isUndefinedOrNull: function (/* ... */) {
+ for (var i = 0; i < arguments.length; i++) {
+ var o = arguments[i];
+ if (!(typeof(o) == 'undefined' || o === null)) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /** @id MochiKit.Base.isEmpty */
+ isEmpty: function (obj) {
+ return !MochiKit.Base.isNotEmpty.apply(this, arguments);
+ },
+
+ /** @id MochiKit.Base.isNotEmpty */
+ isNotEmpty: function (obj) {
+ for (var i = 0; i < arguments.length; i++) {
+ var o = arguments[i];
+ if (!(o && o.length)) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /** @id MochiKit.Base.isArrayLike */
+ isArrayLike: function () {
+ for (var i = 0; i < arguments.length; i++) {
+ var o = arguments[i];
+ var typ = typeof(o);
+ if (
+ (typ != 'object' && !(typ == 'function' && typeof(o.item) == 'function')) ||
+ o === null ||
+ typeof(o.length) != 'number' ||
+ o.nodeType === 3 ||
+ o.nodeType === 4
+ ) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /** @id MochiKit.Base.isDateLike */
+ isDateLike: function () {
+ for (var i = 0; i < arguments.length; i++) {
+ var o = arguments[i];
+ if (typeof(o) != "object" || o === null
+ || typeof(o.getTime) != 'function') {
+ return false;
+ }
+ }
+ return true;
+ },
+
+
+ /** @id MochiKit.Base.xmap */
+ xmap: function (fn/*, obj... */) {
+ if (fn === null) {
+ return MochiKit.Base.extend(null, arguments, 1);
+ }
+ var rval = [];
+ for (var i = 1; i < arguments.length; i++) {
+ rval.push(fn(arguments[i]));
+ }
+ return rval;
+ },
+
+ /** @id MochiKit.Base.map */
+ map: function (fn, lst/*, lst... */) {
+ var m = MochiKit.Base;
+ var itr = MochiKit.Iter;
+ var isArrayLike = m.isArrayLike;
+ if (arguments.length <= 2) {
+ // allow an iterable to be passed
+ if (!isArrayLike(lst)) {
+ if (itr) {
+ // fast path for map(null, iterable)
+ lst = itr.list(lst);
+ if (fn === null) {
+ return lst;
+ }
+ } else {
+ throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+ }
+ }
+ // fast path for map(null, lst)
+ if (fn === null) {
+ return m.extend(null, lst);
+ }
+ // disabled fast path for map(fn, lst)
+ /*
+ if (false && typeof(Array.prototype.map) == 'function') {
+ // Mozilla fast-path
+ return Array.prototype.map.call(lst, fn);
+ }
+ */
+ var rval = [];
+ for (var i = 0; i < lst.length; i++) {
+ rval.push(fn(lst[i]));
+ }
+ return rval;
+ } else {
+ // default for map(null, ...) is zip(...)
+ if (fn === null) {
+ fn = Array;
+ }
+ var length = null;
+ for (var i = 1; i < arguments.length; i++) {
+ // allow iterables to be passed
+ if (!isArrayLike(arguments[i])) {
+ if (itr) {
+ return itr.list(itr.imap.apply(null, arguments));
+ } else {
+ throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+ }
+ }
+ // find the minimum length
+ var l = arguments[i].length;
+ if (length === null || length > l) {
+ length = l;
+ }
+ }
+ rval = [];
+ for (var i = 0; i < length; i++) {
+ var args = [];
+ for (var j = 1; j < arguments.length; j++) {
+ args.push(arguments[j][i]);
+ }
+ rval.push(fn.apply(this, args));
+ }
+ return rval;
+ }
+ },
+
+ /** @id MochiKit.Base.xfilter */
+ xfilter: function (fn/*, obj... */) {
+ var rval = [];
+ if (fn === null) {
+ fn = MochiKit.Base.operator.truth;
+ }
+ for (var i = 1; i < arguments.length; i++) {
+ var o = arguments[i];
+ if (fn(o)) {
+ rval.push(o);
+ }
+ }
+ return rval;
+ },
+
+ /** @id MochiKit.Base.filter */
+ filter: function (fn, lst, self) {
+ var rval = [];
+ // allow an iterable to be passed
+ var m = MochiKit.Base;
+ if (!m.isArrayLike(lst)) {
+ if (MochiKit.Iter) {
+ lst = MochiKit.Iter.list(lst);
+ } else {
+ throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
+ }
+ }
+ if (fn === null) {
+ fn = m.operator.truth;
+ }
+ if (typeof(Array.prototype.filter) == 'function') {
+ // Mozilla fast-path
+ return Array.prototype.filter.call(lst, fn, self);
+ } else if (typeof(self) == 'undefined' || self === null) {
+ for (var i = 0; i < lst.length; i++) {
+ var o = lst[i];
+ if (fn(o)) {
+ rval.push(o);
+ }
+ }
+ } else {
+ for (var i = 0; i < lst.length; i++) {
+ o = lst[i];
+ if (fn.call(self, o)) {
+ rval.push(o);
+ }
+ }
+ }
+ return rval;
+ },
+
+
+ _wrapDumbFunction: function (func) {
+ return function () {
+ // fast path!
+ switch (arguments.length) {
+ case 0: return func();
+ case 1: return func(arguments[0]);
+ case 2: return func(arguments[0], arguments[1]);
+ case 3: return func(arguments[0], arguments[1], arguments[2]);
+ }
+ var args = [];
+ for (var i = 0; i < arguments.length; i++) {
+ args.push("arguments[" + i + "]");
+ }
+ return eval("(func(" + args.join(",") + "))");
+ };
+ },
+
+ /** @id MochiKit.Base.methodcaller */
+ methodcaller: function (func/*, args... */) {
+ var args = MochiKit.Base.extend(null, arguments, 1);
+ if (typeof(func) == "function") {
+ return function (obj) {
+ return func.apply(obj, args);
+ };
+ } else {
+ return function (obj) {
+ return obj[func].apply(obj, args);
+ };
+ }
+ },
+
+ /** @id MochiKit.Base.method */
+ method: function (self, func) {
+ var m = MochiKit.Base;
+ return m.bind.apply(this, m.extend([func, self], arguments, 2));
+ },
+
+ /** @id MochiKit.Base.compose */
+ compose: function (f1, f2/*, f3, ... fN */) {
+ var fnlist = [];
+ var m = MochiKit.Base;
+ if (arguments.length === 0) {
+ throw new TypeError("compose() requires at least one argument");
+ }
+ for (var i = 0; i < arguments.length; i++) {
+ var fn = arguments[i];
+ if (typeof(fn) != "function") {
+ throw new TypeError(m.repr(fn) + " is not a function");
+ }
+ fnlist.push(fn);
+ }
+ return function () {
+ var args = arguments;
+ for (var i = fnlist.length - 1; i >= 0; i--) {
+ args = [fnlist[i].apply(this, args)];
+ }
+ return args[0];
+ };
+ },
+
+ /** @id MochiKit.Base.bind */
+ bind: function (func, self/* args... */) {
+ if (typeof(func) == "string") {
+ func = self[func];
+ }
+ var im_func = func.im_func;
+ var im_preargs = func.im_preargs;
+ var im_self = func.im_self;
+ var m = MochiKit.Base;
+ if (typeof(func) == "function" && typeof(func.apply) == "undefined") {
+ // this is for cases where JavaScript sucks ass and gives you a
+ // really dumb built-in function like alert() that doesn't have
+ // an apply
+ func = m._wrapDumbFunction(func);
+ }
+ if (typeof(im_func) != 'function') {
+ im_func = func;
+ }
+ if (typeof(self) != 'undefined') {
+ im_self = self;
+ }
+ if (typeof(im_preargs) == 'undefined') {
+ im_preargs = [];
+ } else {
+ im_preargs = im_preargs.slice();
+ }
+ m.extend(im_preargs, arguments, 2);
+ var newfunc = function () {
+ var args = arguments;
+ var me = arguments.callee;
+ if (me.im_preargs.length > 0) {
+ args = m.concat(me.im_preargs, args);
+ }
+ var self = me.im_self;
+ if (!self) {
+ self = this;
+ }
+ return me.im_func.apply(self, args);
+ };
+ newfunc.im_self = im_self;
+ newfunc.im_func = im_func;
+ newfunc.im_preargs = im_preargs;
+ return newfunc;
+ },
+
+ /** @id MochiKit.Base.bindLate */
+ bindLate: function (func, self/* args... */) {
+ var m = MochiKit.Base;
+ var args = arguments;
+ if (typeof(func) === "string") {
+ args = m.extend([m.forwardCall(func)], arguments, 1);
+ return m.bind.apply(this, args);
+ }
+ return m.bind.apply(this, args);
+ },
+
+ /** @id MochiKit.Base.bindMethods */
+ bindMethods: function (self) {
+ var bind = MochiKit.Base.bind;
+ for (var k in self) {
+ var func = self[k];
+ if (typeof(func) == 'function') {
+ self[k] = bind(func, self);
+ }
+ }
+ },
+
+ /** @id MochiKit.Base.registerComparator */
+ registerComparator: function (name, check, comparator, /* optional */ override) {
+ MochiKit.Base.comparatorRegistry.register(name, check, comparator, override);
+ },
+
+ _primitives: {'boolean': true, 'string': true, 'number': true},
+
+ /** @id MochiKit.Base.compare */
+ compare: function (a, b) {
+ if (a == b) {
+ return 0;
+ }
+ var aIsNull = (typeof(a) == 'undefined' || a === null);
+ var bIsNull = (typeof(b) == 'undefined' || b === null);
+ if (aIsNull && bIsNull) {
+ return 0;
+ } else if (aIsNull) {
+ return -1;
+ } else if (bIsNull) {
+ return 1;
+ }
+ var m = MochiKit.Base;
+ // bool, number, string have meaningful comparisons
+ var prim = m._primitives;
+ if (!(typeof(a) in prim && typeof(b) in prim)) {
+ try {
+ return m.comparatorRegistry.match(a, b);
+ } catch (e) {
+ if (e != m.NotFound) {
+ throw e;
+ }
+ }
+ }
+ if (a < b) {
+ return -1;
+ } else if (a > b) {
+ return 1;
+ }
+ // These types can't be compared
+ var repr = m.repr;
+ throw new TypeError(repr(a) + " and " + repr(b) + " can not be compared");
+ },
+
+ /** @id MochiKit.Base.compareDateLike */
+ compareDateLike: function (a, b) {
+ return MochiKit.Base.compare(a.getTime(), b.getTime());
+ },
+
+ /** @id MochiKit.Base.compareArrayLike */
+ compareArrayLike: function (a, b) {
+ var compare = MochiKit.Base.compare;
+ var count = a.length;
+ var rval = 0;
+ if (count > b.length) {
+ rval = 1;
+ count = b.length;
+ } else if (count < b.length) {
+ rval = -1;
+ }
+ for (var i = 0; i < count; i++) {
+ var cmp = compare(a[i], b[i]);
+ if (cmp) {
+ return cmp;
+ }
+ }
+ return rval;
+ },
+
+ /** @id MochiKit.Base.registerRepr */
+ registerRepr: function (name, check, wrap, /* optional */override) {
+ MochiKit.Base.reprRegistry.register(name, check, wrap, override);
+ },
+
+ /** @id MochiKit.Base.repr */
+ repr: function (o) {
+ if (typeof(o) == "undefined") {
+ return "undefined";
+ } else if (o === null) {
+ return "null";
+ }
+ try {
+ if (typeof(o.__repr__) == 'function') {
+ return o.__repr__();
+ } else if (typeof(o.repr) == 'function' && o.repr != arguments.callee) {
+ return o.repr();
+ }
+ return MochiKit.Base.reprRegistry.match(o);
+ } catch (e) {
+ if (typeof(o.NAME) == 'string' && (
+ o.toString == Function.prototype.toString ||
+ o.toString == Object.prototype.toString
+ )) {
+ return o.NAME;
+ }
+ }
+ try {
+ var ostring = (o + "");
+ } catch (e) {
+ return "[" + typeof(o) + "]";
+ }
+ if (typeof(o) == "function") {
+ ostring = ostring.replace(/^\s+/, "").replace(/\s+/g, " ");
+ ostring = ostring.replace(/,(\S)/, ", $1");
+ var idx = ostring.indexOf("{");
+ if (idx != -1) {
+ ostring = ostring.substr(0, idx) + "{...}";
+ }
+ }
+ return ostring;
+ },
+
+ /** @id MochiKit.Base.reprArrayLike */
+ reprArrayLike: function (o) {
+ var m = MochiKit.Base;
+ return "[" + m.map(m.repr, o).join(", ") + "]";
+ },
+
+ /** @id MochiKit.Base.reprString */
+ reprString: function (o) {
+ return ('"' + o.replace(/(["\\])/g, '\\$1') + '"'
+ ).replace(/[\f]/g, "\\f"
+ ).replace(/[\b]/g, "\\b"
+ ).replace(/[\n]/g, "\\n"
+ ).replace(/[\t]/g, "\\t"
+ ).replace(/[\v]/g, "\\v"
+ ).replace(/[\r]/g, "\\r");
+ },
+
+ /** @id MochiKit.Base.reprNumber */
+ reprNumber: function (o) {
+ return o + "";
+ },
+
+ /** @id MochiKit.Base.registerJSON */
+ registerJSON: function (name, check, wrap, /* optional */override) {
+ MochiKit.Base.jsonRegistry.register(name, check, wrap, override);
+ },
+
+
+ /** @id MochiKit.Base.evalJSON */
+ evalJSON: function () {
+ return eval("(" + MochiKit.Base._filterJSON(arguments[0]) + ")");
+ },
+
+ _filterJSON: function (s) {
+ var m = s.match(/^\s*\/\*(.*)\*\/\s*$/);
+ if (m) {
+ return m[1];
+ }
+ return s;
+ },
+
+ /** @id MochiKit.Base.serializeJSON */
+ serializeJSON: function (o) {
+ var objtype = typeof(o);
+ if (objtype == "number" || objtype == "boolean") {
+ return o + "";
+ } else if (o === null) {
+ return "null";
+ } else if (objtype == "string") {
+ var res = "";
+ for (var i = 0; i < o.length; i++) {
+ var c = o.charAt(i);
+ if (c == '\"') {
+ res += '\\"';
+ } else if (c == '\\') {
+ res += '\\\\';
+ } else if (c == '\b') {
+ res += '\\b';
+ } else if (c == '\f') {
+ res += '\\f';
+ } else if (c == '\n') {
+ res += '\\n';
+ } else if (c == '\r') {
+ res += '\\r';
+ } else if (c == '\t') {
+ res += '\\t';
+ } else if (o.charCodeAt(i) <= 0x1F) {
+ var hex = o.charCodeAt(i).toString(16);
+ if (hex.length < 2) {
+ hex = '0' + hex;
+ }
+ res += '\\u00' + hex.toUpperCase();
+ } else {
+ res += c;
+ }
+ }
+ return '"' + res + '"';
+ }
+ // recurse
+ var me = arguments.callee;
+ // short-circuit for objects that support "json" serialization
+ // if they return "self" then just pass-through...
+ var newObj;
+ if (typeof(o.__json__) == "function") {
+ newObj = o.__json__();
+ if (o !== newObj) {
+ return me(newObj);
+ }
+ }
+ if (typeof(o.json) == "function") {
+ newObj = o.json();
+ if (o !== newObj) {
+ return me(newObj);
+ }
+ }
+ // array
+ if (objtype != "function" && typeof(o.length) == "number") {
+ var res = [];
+ for (var i = 0; i < o.length; i++) {
+ var val = me(o[i]);
+ if (typeof(val) != "string") {
+ // skip non-serializable values
+ continue;
+ }
+ res.push(val);
+ }
+ return "[" + res.join(", ") + "]";
+ }
+ // look in the registry
+ var m = MochiKit.Base;
+ try {
+ newObj = m.jsonRegistry.match(o);
+ if (o !== newObj) {
+ return me(newObj);
+ }
+ } catch (e) {
+ if (e != m.NotFound) {
+ // something really bad happened
+ throw e;
+ }
+ }
+ // undefined is outside of the spec
+ if (objtype == "undefined") {
+ throw new TypeError("undefined can not be serialized as JSON");
+ }
+ // it's a function with no adapter, bad
+ if (objtype == "function") {
+ return null;
+ }
+ // generic object code path
+ res = [];
+ for (var k in o) {
+ var useKey;
+ if (typeof(k) == "number") {
+ useKey = '"' + k + '"';
+ } else if (typeof(k) == "string") {
+ useKey = me(k);
+ } else {
+ // skip non-string or number keys
+ continue;
+ }
+ val = me(o[k]);
+ if (typeof(val) != "string") {
+ // skip non-serializable values
+ continue;
+ }
+ res.push(useKey + ":" + val);
+ }
+ return "{" + res.join(", ") + "}";
+ },
+
+
+ /** @id MochiKit.Base.objEqual */
+ objEqual: function (a, b) {
+ return (MochiKit.Base.compare(a, b) === 0);
+ },
+
+ /** @id MochiKit.Base.arrayEqual */
+ arrayEqual: function (self, arr) {
+ if (self.length != arr.length) {
+ return false;
+ }
+ return (MochiKit.Base.compare(self, arr) === 0);
+ },
+
+ /** @id MochiKit.Base.concat */
+ concat: function (/* lst... */) {
+ var rval = [];
+ var extend = MochiKit.Base.extend;
+ for (var i = 0; i < arguments.length; i++) {
+ extend(rval, arguments[i]);
+ }
+ return rval;
+ },
+
+ /** @id MochiKit.Base.keyComparator */
+ keyComparator: function (key/* ... */) {
+ // fast-path for single key comparisons
+ var m = MochiKit.Base;
+ var compare = m.compare;
+ if (arguments.length == 1) {
+ return function (a, b) {
+ return compare(a[key], b[key]);
+ };
+ }
+ var compareKeys = m.extend(null, arguments);
+ return function (a, b) {
+ var rval = 0;
+ // keep comparing until something is inequal or we run out of
+ // keys to compare
+ for (var i = 0; (rval === 0) && (i < compareKeys.length); i++) {
+ var key = compareKeys[i];
+ rval = compare(a[key], b[key]);
+ }
+ return rval;
+ };
+ },
+
+ /** @id MochiKit.Base.reverseKeyComparator */
+ reverseKeyComparator: function (key) {
+ var comparator = MochiKit.Base.keyComparator.apply(this, arguments);
+ return function (a, b) {
+ return comparator(b, a);
+ };
+ },
+
+ /** @id MochiKit.Base.partial */
+ partial: function (func) {
+ var m = MochiKit.Base;
+ return m.bind.apply(this, m.extend([func, undefined], arguments, 1));
+ },
+
+ /** @id MochiKit.Base.listMinMax */
+ listMinMax: function (which, lst) {
+ if (lst.length === 0) {
+ return null;
+ }
+ var cur = lst[0];
+ var compare = MochiKit.Base.compare;
+ for (var i = 1; i < lst.length; i++) {
+ var o = lst[i];
+ if (compare(o, cur) == which) {
+ cur = o;
+ }
+ }
+ return cur;
+ },
+
+ /** @id MochiKit.Base.objMax */
+ objMax: function (/* obj... */) {
+ return MochiKit.Base.listMinMax(1, arguments);
+ },
+
+ /** @id MochiKit.Base.objMin */
+ objMin: function (/* obj... */) {
+ return MochiKit.Base.listMinMax(-1, arguments);
+ },
+
+ /** @id MochiKit.Base.findIdentical */
+ findIdentical: function (lst, value, start/* = 0 */, /* optional */end) {
+ if (typeof(end) == "undefined" || end === null) {
+ end = lst.length;
+ }
+ if (typeof(start) == "undefined" || start === null) {
+ start = 0;
+ }
+ for (var i = start; i < end; i++) {
+ if (lst[i] === value) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ /** @id MochiKit.Base.mean */
+ mean: function(/* lst... */) {
+ /* http://www.nist.gov/dads/HTML/mean.html */
+ var sum = 0;
+
+ var m = MochiKit.Base;
+ var args = m.extend(null, arguments);
+ var count = args.length;
+
+ while (args.length) {
+ var o = args.shift();
+ if (o && typeof(o) == "object" && typeof(o.length) == "number") {
+ count += o.length - 1;
+ for (var i = o.length - 1; i >= 0; i--) {
+ sum += o[i];
+ }
+ } else {
+ sum += o;
+ }
+ }
+
+ if (count <= 0) {
+ throw new TypeError('mean() requires at least one argument');
+ }
+
+ return sum/count;
+ },
+
+ /** @id MochiKit.Base.median */
+ median: function(/* lst... */) {
+ /* http://www.nist.gov/dads/HTML/median.html */
+ var data = MochiKit.Base.flattenArguments(arguments);
+ if (data.length === 0) {
+ throw new TypeError('median() requires at least one argument');
+ }
+ data.sort(compare);
+ if (data.length % 2 == 0) {
+ var upper = data.length / 2;
+ return (data[upper] + data[upper - 1]) / 2;
+ } else {
+ return data[(data.length - 1) / 2];
+ }
+ },
+
+ /** @id MochiKit.Base.findValue */
+ findValue: function (lst, value, start/* = 0 */, /* optional */end) {
+ if (typeof(end) == "undefined" || end === null) {
+ end = lst.length;
+ }
+ if (typeof(start) == "undefined" || start === null) {
+ start = 0;
+ }
+ var cmp = MochiKit.Base.compare;
+ for (var i = start; i < end; i++) {
+ if (cmp(lst[i], value) === 0) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ /** @id MochiKit.Base.nodeWalk */
+ nodeWalk: function (node, visitor) {
+ var nodes = [node];
+ var extend = MochiKit.Base.extend;
+ while (nodes.length) {
+ var res = visitor(nodes.shift());
+ if (res) {
+ extend(nodes, res);
+ }
+ }
+ },
+
+
+ /** @id MochiKit.Base.nameFunctions */
+ nameFunctions: function (namespace) {
+ var base = namespace.NAME;
+ if (typeof(base) == 'undefined') {
+ base = '';
+ } else {
+ base = base + '.';
+ }
+ for (var name in namespace) {
+ var o = namespace[name];
+ if (typeof(o) == 'function' && typeof(o.NAME) == 'undefined') {
+ try {
+ o.NAME = base + name;
+ } catch (e) {
+ // pass
+ }
+ }
+ }
+ },
+
+
+ /** @id MochiKit.Base.queryString */
+ queryString: function (names, values) {
+ // check to see if names is a string or a DOM element, and if
+ // MochiKit.DOM is available. If so, drop it like it's a form
+ // Ugliest conditional in MochiKit? Probably!
+ if (typeof(MochiKit.DOM) != "undefined" && arguments.length == 1
+ && (typeof(names) == "string" || (
+ typeof(names.nodeType) != "undefined" && names.nodeType > 0
+ ))
+ ) {
+ var kv = MochiKit.DOM.formContents(names);
+ names = kv[0];
+ values = kv[1];
+ } else if (arguments.length == 1) {
+ // Allow the return value of formContents to be passed directly
+ if (typeof(names.length) == "number" && names.length == 2) {
+ return arguments.callee(names[0], names[1]);
+ }
+ var o = names;
+ names = [];
+ values = [];
+ for (var k in o) {
+ var v = o[k];
+ if (typeof(v) == "function") {
+ continue;
+ } else if (MochiKit.Base.isArrayLike(v)){
+ for (var i = 0; i < v.length; i++) {
+ names.push(k);
+ values.push(v[i]);
+ }
+ } else {
+ names.push(k);
+ values.push(v);
+ }
+ }
+ }
+ var rval = [];
+ var len = Math.min(names.length, values.length);
+ var urlEncode = MochiKit.Base.urlEncode;
+ for (var i = 0; i < len; i++) {
+ v = values[i];
+ if (typeof(v) != 'undefined' && v !== null) {
+ rval.push(urlEncode(names[i]) + "=" + urlEncode(v));
+ }
+ }
+ return rval.join("&");
+ },
+
+
+ /** @id MochiKit.Base.parseQueryString */
+ parseQueryString: function (encodedString, useArrays) {
+ // strip a leading '?' from the encoded string
+ var qstr = (encodedString.charAt(0) == "?")
+ ? encodedString.substring(1)
+ : encodedString;
+ var pairs = qstr.replace(/\+/g, "%20").split(/\&amp\;|\&\#38\;|\&#x26;|\&/);
+ var o = {};
+ var decode;
+ if (typeof(decodeURIComponent) != "undefined") {
+ decode = decodeURIComponent;
+ } else {
+ decode = unescape;
+ }
+ if (useArrays) {
+ for (var i = 0; i < pairs.length; i++) {
+ var pair = pairs[i].split("=");
+ var name = decode(pair.shift());
+ if (!name) {
+ continue;
+ }
+ var arr = o[name];
+ if (!(arr instanceof Array)) {
+ arr = [];
+ o[name] = arr;
+ }
+ arr.push(decode(pair.join("=")));
+ }
+ } else {
+ for (var i = 0; i < pairs.length; i++) {
+ pair = pairs[i].split("=");
+ var name = pair.shift();
+ if (!name) {
+ continue;
+ }
+ o[decode(name)] = decode(pair.join("="));
+ }
+ }
+ return o;
+ }
+});
+
+/** @id MochiKit.Base.AdapterRegistry */
+MochiKit.Base.AdapterRegistry = function () {
+ this.pairs = [];
+};
+
+MochiKit.Base.AdapterRegistry.prototype = {
+ /** @id MochiKit.Base.AdapterRegistry.prototype.register */
+ register: function (name, check, wrap, /* optional */ override) {
+ if (override) {
+ this.pairs.unshift([name, check, wrap]);
+ } else {
+ this.pairs.push([name, check, wrap]);
+ }
+ },
+
+ /** @id MochiKit.Base.AdapterRegistry.prototype.match */
+ match: function (/* ... */) {
+ for (var i = 0; i < this.pairs.length; i++) {
+ var pair = this.pairs[i];
+ if (pair[1].apply(this, arguments)) {
+ return pair[2].apply(this, arguments);
+ }
+ }
+ throw MochiKit.Base.NotFound;
+ },
+
+ /** @id MochiKit.Base.AdapterRegistry.prototype.unregister */
+ unregister: function (name) {
+ for (var i = 0; i < this.pairs.length; i++) {
+ var pair = this.pairs[i];
+ if (pair[0] == name) {
+ this.pairs.splice(i, 1);
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+MochiKit.Base._exportSymbols = function (globals, module) {
+ if (MochiKit.__export__ === false || module.__export__ === false) {
+ return;
+ }
+ for (var k in module) {
+ var v = module[k];
+ if (v != null) {
+ var okName = (k[0] !== "_" && k !== "toString");
+ if (v.__export__ === true || (v.__export__ !== false && okName)) {
+ globals[k] = module[k];
+ }
+ }
+ }
+};
+
+/**
+ * Creates a deprecated function alias in the specified module. The
+ * deprecated function will forward all calls and arguments to a
+ * target function, while also logging a debug message on the first
+ * call (if MochiKit.Logging is loaded). The destination function may
+ * be located in another module, which must be loaded, or an
+ * exception will be thrown.
+ *
+ * @param {Object/String} module the source module or module name
+ * (e.g. 'DOM' or 'MochiKit.DOM')
+ * @param {String} name the deprecated function name (e.g. 'getStyle')
+ * @param {String} target the fully qualified name of the target
+ * function (e.g. 'MochiKit.Style.getStyle')
+ * @param {String} version the first version when the source function
+ * was deprecated (e.g. '1.4')
+ * @param {Boolean} [exportable] the exportable function flag,
+ * defaults to true
+ */
+MochiKit.Base._deprecated = function (module, name, target, version, exportable) {
+ if (typeof(module) === 'string') {
+ if (module.indexOf('MochiKit.') === 0) {
+ module = module.substring(9);
+ }
+ module = MochiKit[module];
+ }
+ var targetModule = target.split('.')[1];
+ var targetName = target.split('.')[2];
+ var func = function () {
+ var self = arguments.callee;
+ var msg = module.NAME + '.' + name + ' is deprecated since version ' +
+ version + '. Use ' + target + ' instead.';
+ if (self.logged !== true) {
+ self.logged = true;
+ if (MochiKit.Logging) {
+ MochiKit.Logging.logDebug(msg);
+ } else if (console && console.log) {
+ console.log(msg);
+ }
+ }
+ if (!MochiKit[targetModule]) {
+ throw new Error(msg);
+ }
+ return MochiKit[targetModule][targetName].apply(this, arguments);
+ };
+ if (exportable === false) {
+ func.__export__ = false;
+ }
+ module[name] = func;
+}
+
+MochiKit.Base.__new__ = function () {
+ var m = this;
+
+ /** @id MochiKit.Base.noop */
+ m.noop = m.operator.identity;
+
+ // Backwards compat
+ m._deprecated(m, 'forward', 'MochiKit.Base.forwardCall', '1.3', false);
+ m._deprecated(m, 'find', 'MochiKit.Base.findValue', '1.3', false);
+
+ if (typeof(encodeURIComponent) != "undefined") {
+ /** @id MochiKit.Base.urlEncode */
+ m.urlEncode = function (unencoded) {
+ return encodeURIComponent(unencoded).replace(/\'/g, '%27');
+ };
+ } else {
+ m.urlEncode = function (unencoded) {
+ return escape(unencoded
+ ).replace(/\+/g, '%2B'
+ ).replace(/\"/g,'%22'
+ ).rval.replace(/\'/g, '%27');
+ };
+ }
+
+ /** @id MochiKit.Base.NamedError */
+ m.NamedError = function (name) {
+ this.message = name;
+ this.name = name;
+ };
+ m.NamedError.prototype = new Error();
+ m.update(m.NamedError.prototype, {
+ repr: function () {
+ if (this.message && this.message != this.name) {
+ return this.name + "(" + m.repr(this.message) + ")";
+ } else {
+ return this.name + "()";
+ }
+ },
+ toString: m.forwardCall("repr")
+ });
+
+ /** @id MochiKit.Base.NotFound */
+ m.NotFound = new m.NamedError("MochiKit.Base.NotFound");
+
+
+ /** @id MochiKit.Base.listMax */
+ m.listMax = m.partial(m.listMinMax, 1);
+ /** @id MochiKit.Base.listMin */
+ m.listMin = m.partial(m.listMinMax, -1);
+
+ /** @id MochiKit.Base.isCallable */
+ m.isCallable = m.typeMatcher('function');
+ /** @id MochiKit.Base.isUndefined */
+ m.isUndefined = m.typeMatcher('undefined');
+
+ /** @id MochiKit.Base.merge */
+ m.merge = m.partial(m.update, null);
+ /** @id MochiKit.Base.zip */
+ m.zip = m.partial(m.map, null);
+
+ /** @id MochiKit.Base.average */
+ m.average = m.mean;
+
+ /** @id MochiKit.Base.comparatorRegistry */
+ m.comparatorRegistry = new m.AdapterRegistry();
+ m.registerComparator("dateLike", m.isDateLike, m.compareDateLike);
+ m.registerComparator("arrayLike", m.isArrayLike, m.compareArrayLike);
+
+ /** @id MochiKit.Base.reprRegistry */
+ m.reprRegistry = new m.AdapterRegistry();
+ m.registerRepr("arrayLike", m.isArrayLike, m.reprArrayLike);
+ m.registerRepr("string", m.typeMatcher("string"), m.reprString);
+ m.registerRepr("numbers", m.typeMatcher("number", "boolean"), m.reprNumber);
+
+ /** @id MochiKit.Base.jsonRegistry */
+ m.jsonRegistry = new m.AdapterRegistry();
+
+ m.nameFunctions(this);
+
+};
+
+MochiKit.Base.__new__();
+
+//
+// XXX: Internet Explorer blows
+//
+if (MochiKit.__export__) {
+ compare = MochiKit.Base.compare;
+ compose = MochiKit.Base.compose;
+ serializeJSON = MochiKit.Base.serializeJSON;
+ mean = MochiKit.Base.mean;
+ median = MochiKit.Base.median;
+}
+
+MochiKit.Base._exportSymbols(this, MochiKit.Base);
diff --git a/frontend/gamma/js/MochiKit/Color.js b/frontend/gamma/js/MochiKit/Color.js
new file mode 100644
index 0000000..27dc2d0
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Color.js
@@ -0,0 +1,832 @@
+/***
+
+MochiKit.Color 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito and others. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('Color', '1.5', ['Base', 'DOM', 'Style']);
+
+/** @id MochiKit.Color.Color */
+MochiKit.Color.Color = function (red, green, blue, alpha) {
+ if (typeof(alpha) == 'undefined' || alpha === null) {
+ alpha = 1.0;
+ }
+ this.rgb = {
+ r: red,
+ g: green,
+ b: blue,
+ a: alpha
+ };
+};
+
+
+// Prototype methods
+
+MochiKit.Color.Color.prototype = {
+
+ __class__: MochiKit.Color.Color,
+
+ /** @id MochiKit.Color.Color.prototype.colorWithAlpha */
+ colorWithAlpha: function (alpha) {
+ var rgb = this.rgb;
+ var m = MochiKit.Color;
+ return m.Color.fromRGB(rgb.r, rgb.g, rgb.b, alpha);
+ },
+
+ /** @id MochiKit.Color.Color.prototype.colorWithHue */
+ colorWithHue: function (hue) {
+ // get an HSL model, and set the new hue...
+ var hsl = this.asHSL();
+ hsl.h = hue;
+ var m = MochiKit.Color;
+ // convert back to RGB...
+ return m.Color.fromHSL(hsl);
+ },
+
+ /** @id MochiKit.Color.Color.prototype.colorWithSaturation */
+ colorWithSaturation: function (saturation) {
+ // get an HSL model, and set the new hue...
+ var hsl = this.asHSL();
+ hsl.s = saturation;
+ var m = MochiKit.Color;
+ // convert back to RGB...
+ return m.Color.fromHSL(hsl);
+ },
+
+ /** @id MochiKit.Color.Color.prototype.colorWithLightness */
+ colorWithLightness: function (lightness) {
+ // get an HSL model, and set the new hue...
+ var hsl = this.asHSL();
+ hsl.l = lightness;
+ var m = MochiKit.Color;
+ // convert back to RGB...
+ return m.Color.fromHSL(hsl);
+ },
+
+ /** @id MochiKit.Color.Color.prototype.darkerColorWithLevel */
+ darkerColorWithLevel: function (level) {
+ var hsl = this.asHSL();
+ hsl.l = Math.max(hsl.l - level, 0);
+ var m = MochiKit.Color;
+ return m.Color.fromHSL(hsl);
+ },
+
+ /** @id MochiKit.Color.Color.prototype.lighterColorWithLevel */
+ lighterColorWithLevel: function (level) {
+ var hsl = this.asHSL();
+ hsl.l = Math.min(hsl.l + level, 1);
+ var m = MochiKit.Color;
+ return m.Color.fromHSL(hsl);
+ },
+
+ /** @id MochiKit.Color.Color.prototype.blendedColor */
+ blendedColor: function (other, /* optional */ fraction) {
+ if (typeof(fraction) == 'undefined' || fraction === null) {
+ fraction = 0.5;
+ }
+ var sf = 1.0 - fraction;
+ var s = this.rgb;
+ var d = other.rgb;
+ var df = fraction;
+ return MochiKit.Color.Color.fromRGB(
+ (s.r * sf) + (d.r * df),
+ (s.g * sf) + (d.g * df),
+ (s.b * sf) + (d.b * df),
+ (s.a * sf) + (d.a * df)
+ );
+ },
+
+ /** @id MochiKit.Color.Color.prototype.compareRGB */
+ compareRGB: function (other) {
+ var a = this.asRGB();
+ var b = other.asRGB();
+ return MochiKit.Base.compare(
+ [a.r, a.g, a.b, a.a],
+ [b.r, b.g, b.b, b.a]
+ );
+ },
+
+ /** @id MochiKit.Color.Color.prototype.isLight */
+ isLight: function () {
+ return this.asHSL().b > 0.5;
+ },
+
+ /** @id MochiKit.Color.Color.prototype.isDark */
+ isDark: function () {
+ return (!this.isLight());
+ },
+
+ /** @id MochiKit.Color.Color.prototype.toHSLString */
+ toHSLString: function () {
+ var c = this.asHSL();
+ var ccc = MochiKit.Color.clampColorComponent;
+ var rval = this._hslString;
+ if (!rval) {
+ var mid = (
+ ccc(c.h, 360).toFixed(0)
+ + "," + ccc(c.s, 100).toPrecision(4) + "%"
+ + "," + ccc(c.l, 100).toPrecision(4) + "%"
+ );
+ var a = c.a;
+ if (a >= 1) {
+ a = 1;
+ rval = "hsl(" + mid + ")";
+ } else {
+ if (a <= 0) {
+ a = 0;
+ }
+ rval = "hsla(" + mid + "," + a + ")";
+ }
+ this._hslString = rval;
+ }
+ return rval;
+ },
+
+ /** @id MochiKit.Color.Color.prototype.toRGBString */
+ toRGBString: function () {
+ var c = this.rgb;
+ var ccc = MochiKit.Color.clampColorComponent;
+ var rval = this._rgbString;
+ if (!rval) {
+ var mid = (
+ ccc(c.r, 255).toFixed(0)
+ + "," + ccc(c.g, 255).toFixed(0)
+ + "," + ccc(c.b, 255).toFixed(0)
+ );
+ if (c.a != 1) {
+ rval = "rgba(" + mid + "," + c.a + ")";
+ } else {
+ rval = "rgb(" + mid + ")";
+ }
+ this._rgbString = rval;
+ }
+ return rval;
+ },
+
+ /** @id MochiKit.Color.Color.prototype.asRGB */
+ asRGB: function () {
+ return MochiKit.Base.clone(this.rgb);
+ },
+
+ /** @id MochiKit.Color.Color.prototype.toHexString */
+ toHexString: function () {
+ var m = MochiKit.Color;
+ var c = this.rgb;
+ var ccc = MochiKit.Color.clampColorComponent;
+ var rval = this._hexString;
+ if (!rval) {
+ rval = ("#" +
+ m.toColorPart(ccc(c.r, 255)) +
+ m.toColorPart(ccc(c.g, 255)) +
+ m.toColorPart(ccc(c.b, 255))
+ );
+ this._hexString = rval;
+ }
+ return rval;
+ },
+
+ /** @id MochiKit.Color.Color.prototype.asHSV */
+ asHSV: function () {
+ var hsv = this.hsv;
+ var c = this.rgb;
+ if (typeof(hsv) == 'undefined' || hsv === null) {
+ hsv = MochiKit.Color.rgbToHSV(this.rgb);
+ this.hsv = hsv;
+ }
+ return MochiKit.Base.clone(hsv);
+ },
+
+ /** @id MochiKit.Color.Color.prototype.asHSL */
+ asHSL: function () {
+ var hsl = this.hsl;
+ var c = this.rgb;
+ if (typeof(hsl) == 'undefined' || hsl === null) {
+ hsl = MochiKit.Color.rgbToHSL(this.rgb);
+ this.hsl = hsl;
+ }
+ return MochiKit.Base.clone(hsl);
+ },
+
+ /** @id MochiKit.Color.Color.prototype.toString */
+ toString: function () {
+ return this.toRGBString();
+ },
+
+ /** @id MochiKit.Color.Color.prototype.repr */
+ repr: function () {
+ var c = this.rgb;
+ var col = [c.r, c.g, c.b, c.a];
+ return this.__class__.NAME + "(" + col.join(", ") + ")";
+ }
+
+};
+
+// Constructor methods
+
+MochiKit.Base.update(MochiKit.Color.Color, {
+ /** @id MochiKit.Color.Color.fromRGB */
+ fromRGB: function (red, green, blue, alpha) {
+ // designated initializer
+ var Color = MochiKit.Color.Color;
+ if (arguments.length == 1) {
+ var rgb = red;
+ red = rgb.r;
+ green = rgb.g;
+ blue = rgb.b;
+ if (typeof(rgb.a) == 'undefined') {
+ alpha = undefined;
+ } else {
+ alpha = rgb.a;
+ }
+ }
+ return new Color(red, green, blue, alpha);
+ },
+
+ /** @id MochiKit.Color.Color.fromHSL */
+ fromHSL: function (hue, saturation, lightness, alpha) {
+ var m = MochiKit.Color;
+ return m.Color.fromRGB(m.hslToRGB.apply(m, arguments));
+ },
+
+ /** @id MochiKit.Color.Color.fromHSV */
+ fromHSV: function (hue, saturation, value, alpha) {
+ var m = MochiKit.Color;
+ return m.Color.fromRGB(m.hsvToRGB.apply(m, arguments));
+ },
+
+ /** @id MochiKit.Color.Color.fromName */
+ fromName: function (name) {
+ var Color = MochiKit.Color.Color;
+ // Opera 9 seems to "quote" named colors(?!)
+ if (name.charAt(0) == '"') {
+ name = name.substr(1, name.length - 2);
+ }
+ var htmlColor = Color._namedColors[name.toLowerCase()];
+ if (typeof(htmlColor) == 'string') {
+ return Color.fromHexString(htmlColor);
+ } else if (name == "transparent") {
+ return Color.transparentColor();
+ }
+ return null;
+ },
+
+ /** @id MochiKit.Color.Color.fromString */
+ fromString: function (colorString) {
+ var self = MochiKit.Color.Color;
+ var three = colorString.substr(0, 3);
+ if (three == "rgb") {
+ return self.fromRGBString(colorString);
+ } else if (three == "hsl") {
+ return self.fromHSLString(colorString);
+ } else if (colorString.charAt(0) == "#") {
+ return self.fromHexString(colorString);
+ }
+ return self.fromName(colorString);
+ },
+
+
+ /** @id MochiKit.Color.Color.fromHexString */
+ fromHexString: function (hexCode) {
+ if (hexCode.charAt(0) == '#') {
+ hexCode = hexCode.substring(1);
+ }
+ var components = [];
+ var i, hex;
+ if (hexCode.length == 3) {
+ for (i = 0; i < 3; i++) {
+ hex = hexCode.substr(i, 1);
+ components.push(parseInt(hex + hex, 16) / 255.0);
+ }
+ } else {
+ for (i = 0; i < 6; i += 2) {
+ hex = hexCode.substr(i, 2);
+ components.push(parseInt(hex, 16) / 255.0);
+ }
+ }
+ var Color = MochiKit.Color.Color;
+ return Color.fromRGB.apply(Color, components);
+ },
+
+
+ _fromColorString: function (pre, method, scales, colorCode) {
+ // parses either HSL or RGB
+ if (colorCode.indexOf(pre) === 0) {
+ colorCode = colorCode.substring(colorCode.indexOf("(", 3) + 1, colorCode.length - 1);
+ }
+ var colorChunks = colorCode.split(/\s*,\s*/);
+ var colorFloats = [];
+ for (var i = 0; i < colorChunks.length; i++) {
+ var c = colorChunks[i];
+ var val;
+ var three = c.substring(c.length - 3);
+ if (c.charAt(c.length - 1) == '%') {
+ val = 0.01 * parseFloat(c.substring(0, c.length - 1));
+ } else if (three == "deg") {
+ val = parseFloat(c) / 360.0;
+ } else if (three == "rad") {
+ val = parseFloat(c) / (Math.PI * 2);
+ } else {
+ val = scales[i] * parseFloat(c);
+ }
+ colorFloats.push(val);
+ }
+ return this[method].apply(this, colorFloats);
+ },
+
+ /** @id MochiKit.Color.Color.fromComputedStyle */
+ fromComputedStyle: function (elem, style) {
+ var d = MochiKit.DOM;
+ var cls = MochiKit.Color.Color;
+ for (elem = d.getElement(elem); elem; elem = elem.parentNode) {
+ var actualColor = MochiKit.Style.getStyle.apply(d, arguments);
+ if (!actualColor) {
+ continue;
+ }
+ var color = cls.fromString(actualColor);
+ if (!color) {
+ break;
+ }
+ if (color.asRGB().a > 0) {
+ return color;
+ }
+ }
+ return null;
+ },
+
+ /** @id MochiKit.Color.Color.fromBackground */
+ fromBackground: function (elem) {
+ var cls = MochiKit.Color.Color;
+ return cls.fromComputedStyle(
+ elem, "backgroundColor", "background-color") || cls.whiteColor();
+ },
+
+ /** @id MochiKit.Color.Color.fromText */
+ fromText: function (elem) {
+ var cls = MochiKit.Color.Color;
+ return cls.fromComputedStyle(
+ elem, "color", "color") || cls.blackColor();
+ },
+
+ /** @id MochiKit.Color.Color.namedColors */
+ namedColors: function () {
+ return MochiKit.Base.clone(MochiKit.Color.Color._namedColors);
+ }
+});
+
+
+// Module level functions
+
+MochiKit.Base.update(MochiKit.Color, {
+ /** @id MochiKit.Color.clampColorComponent */
+ clampColorComponent: function (v, scale) {
+ v *= scale;
+ if (v < 0) {
+ return 0;
+ } else if (v > scale) {
+ return scale;
+ } else {
+ return v;
+ }
+ },
+
+ _hslValue: function (n1, n2, hue) {
+ if (hue > 6.0) {
+ hue -= 6.0;
+ } else if (hue < 0.0) {
+ hue += 6.0;
+ }
+ var val;
+ if (hue < 1.0) {
+ val = n1 + (n2 - n1) * hue;
+ } else if (hue < 3.0) {
+ val = n2;
+ } else if (hue < 4.0) {
+ val = n1 + (n2 - n1) * (4.0 - hue);
+ } else {
+ val = n1;
+ }
+ return val;
+ },
+
+ /** @id MochiKit.Color.hsvToRGB */
+ hsvToRGB: function (hue, saturation, value, alpha) {
+ if (arguments.length == 1) {
+ var hsv = hue;
+ hue = hsv.h;
+ saturation = hsv.s;
+ value = hsv.v;
+ alpha = hsv.a;
+ }
+ var red;
+ var green;
+ var blue;
+ if (saturation === 0) {
+ red = value;
+ green = value;
+ blue = value;
+ } else {
+ var i = Math.floor(hue * 6);
+ var f = (hue * 6) - i;
+ var p = value * (1 - saturation);
+ var q = value * (1 - (saturation * f));
+ var t = value * (1 - (saturation * (1 - f)));
+ switch (i) {
+ case 1: red = q; green = value; blue = p; break;
+ case 2: red = p; green = value; blue = t; break;
+ case 3: red = p; green = q; blue = value; break;
+ case 4: red = t; green = p; blue = value; break;
+ case 5: red = value; green = p; blue = q; break;
+ case 6: // fall through
+ case 0: red = value; green = t; blue = p; break;
+ }
+ }
+ return {
+ r: red,
+ g: green,
+ b: blue,
+ a: alpha
+ };
+ },
+
+ /** @id MochiKit.Color.hslToRGB */
+ hslToRGB: function (hue, saturation, lightness, alpha) {
+ if (arguments.length == 1) {
+ var hsl = hue;
+ hue = hsl.h;
+ saturation = hsl.s;
+ lightness = hsl.l;
+ alpha = hsl.a;
+ }
+ var red;
+ var green;
+ var blue;
+ if (saturation === 0) {
+ red = lightness;
+ green = lightness;
+ blue = lightness;
+ } else {
+ var m2;
+ if (lightness <= 0.5) {
+ m2 = lightness * (1.0 + saturation);
+ } else {
+ m2 = lightness + saturation - (lightness * saturation);
+ }
+ var m1 = (2.0 * lightness) - m2;
+ var f = MochiKit.Color._hslValue;
+ var h6 = hue * 6.0;
+ red = f(m1, m2, h6 + 2);
+ green = f(m1, m2, h6);
+ blue = f(m1, m2, h6 - 2);
+ }
+ return {
+ r: red,
+ g: green,
+ b: blue,
+ a: alpha
+ };
+ },
+
+ /** @id MochiKit.Color.rgbToHSV */
+ rgbToHSV: function (red, green, blue, alpha) {
+ if (arguments.length == 1) {
+ var rgb = red;
+ red = rgb.r;
+ green = rgb.g;
+ blue = rgb.b;
+ alpha = rgb.a;
+ }
+ var max = Math.max(Math.max(red, green), blue);
+ var min = Math.min(Math.min(red, green), blue);
+ var hue;
+ var saturation;
+ var value = max;
+ if (min == max) {
+ hue = 0;
+ saturation = 0;
+ } else {
+ var delta = (max - min);
+ saturation = delta / max;
+
+ if (red == max) {
+ hue = (green - blue) / delta;
+ } else if (green == max) {
+ hue = 2 + ((blue - red) / delta);
+ } else {
+ hue = 4 + ((red - green) / delta);
+ }
+ hue /= 6;
+ if (hue < 0) {
+ hue += 1;
+ }
+ if (hue > 1) {
+ hue -= 1;
+ }
+ }
+ return {
+ h: hue,
+ s: saturation,
+ v: value,
+ a: alpha
+ };
+ },
+
+ /** @id MochiKit.Color.rgbToHSL */
+ rgbToHSL: function (red, green, blue, alpha) {
+ if (arguments.length == 1) {
+ var rgb = red;
+ red = rgb.r;
+ green = rgb.g;
+ blue = rgb.b;
+ alpha = rgb.a;
+ }
+ var max = Math.max(red, Math.max(green, blue));
+ var min = Math.min(red, Math.min(green, blue));
+ var hue;
+ var saturation;
+ var lightness = (max + min) / 2.0;
+ var delta = max - min;
+ if (delta === 0) {
+ hue = 0;
+ saturation = 0;
+ } else {
+ if (lightness <= 0.5) {
+ saturation = delta / (max + min);
+ } else {
+ saturation = delta / (2 - max - min);
+ }
+ if (red == max) {
+ hue = (green - blue) / delta;
+ } else if (green == max) {
+ hue = 2 + ((blue - red) / delta);
+ } else {
+ hue = 4 + ((red - green) / delta);
+ }
+ hue /= 6;
+ if (hue < 0) {
+ hue += 1;
+ }
+ if (hue > 1) {
+ hue -= 1;
+ }
+
+ }
+ return {
+ h: hue,
+ s: saturation,
+ l: lightness,
+ a: alpha
+ };
+ },
+
+ /** @id MochiKit.Color.toColorPart */
+ toColorPart: function (num) {
+ num = Math.round(num);
+ var digits = num.toString(16);
+ if (num < 16) {
+ return '0' + digits;
+ }
+ return digits;
+ },
+
+ __new__: function () {
+ var m = MochiKit.Base;
+ /** @id MochiKit.Color.Color.fromRGBString */
+ this.Color.fromRGBString = m.bind(
+ this.Color._fromColorString, this.Color, "rgb", "fromRGB",
+ [1.0/255.0, 1.0/255.0, 1.0/255.0, 1]
+ );
+ /** @id MochiKit.Color.Color.fromHSLString */
+ this.Color.fromHSLString = m.bind(
+ this.Color._fromColorString, this.Color, "hsl", "fromHSL",
+ [1.0/360.0, 0.01, 0.01, 1]
+ );
+
+ var third = 1.0 / 3.0;
+ /** @id MochiKit.Color.colors */
+ var colors = {
+ // NSColor colors plus transparent
+ /** @id MochiKit.Color.blackColor */
+ black: [0, 0, 0],
+ /** @id MochiKit.Color.blueColor */
+ blue: [0, 0, 1],
+ /** @id MochiKit.Color.brownColor */
+ brown: [0.6, 0.4, 0.2],
+ /** @id MochiKit.Color.cyanColor */
+ cyan: [0, 1, 1],
+ /** @id MochiKit.Color.darkGrayColor */
+ darkGray: [third, third, third],
+ /** @id MochiKit.Color.grayColor */
+ gray: [0.5, 0.5, 0.5],
+ /** @id MochiKit.Color.greenColor */
+ green: [0, 1, 0],
+ /** @id MochiKit.Color.lightGrayColor */
+ lightGray: [2 * third, 2 * third, 2 * third],
+ /** @id MochiKit.Color.magentaColor */
+ magenta: [1, 0, 1],
+ /** @id MochiKit.Color.orangeColor */
+ orange: [1, 0.5, 0],
+ /** @id MochiKit.Color.purpleColor */
+ purple: [0.5, 0, 0.5],
+ /** @id MochiKit.Color.redColor */
+ red: [1, 0, 0],
+ /** @id MochiKit.Color.transparentColor */
+ transparent: [0, 0, 0, 0],
+ /** @id MochiKit.Color.whiteColor */
+ white: [1, 1, 1],
+ /** @id MochiKit.Color.yellowColor */
+ yellow: [1, 1, 0]
+ };
+
+ var makeColor = function (name, r, g, b, a) {
+ var rval = this.fromRGB(r, g, b, a);
+ this[name] = function () { return rval; };
+ return rval;
+ };
+
+ for (var k in colors) {
+ var name = k + "Color";
+ var bindArgs = m.concat(
+ [makeColor, this.Color, name],
+ colors[k]
+ );
+ this.Color[name] = m.bind.apply(null, bindArgs);
+ }
+
+ var isColor = function () {
+ for (var i = 0; i < arguments.length; i++) {
+ if (!(arguments[i] instanceof MochiKit.Color.Color)) {
+ return false;
+ }
+ }
+ return true;
+ };
+
+ var compareColor = function (a, b) {
+ return a.compareRGB(b);
+ };
+
+ m.nameFunctions(this);
+
+ m.registerComparator(this.Color.NAME, isColor, compareColor);
+ }
+});
+
+MochiKit.Color.__new__();
+
+// Full table of css3 X11 colors <http://www.w3.org/TR/css3-color/#X11COLORS>
+
+MochiKit.Color.Color._namedColors = {
+ aliceblue: "#f0f8ff",
+ antiquewhite: "#faebd7",
+ aqua: "#00ffff",
+ aquamarine: "#7fffd4",
+ azure: "#f0ffff",
+ beige: "#f5f5dc",
+ bisque: "#ffe4c4",
+ black: "#000000",
+ blanchedalmond: "#ffebcd",
+ blue: "#0000ff",
+ blueviolet: "#8a2be2",
+ brown: "#a52a2a",
+ burlywood: "#deb887",
+ cadetblue: "#5f9ea0",
+ chartreuse: "#7fff00",
+ chocolate: "#d2691e",
+ coral: "#ff7f50",
+ cornflowerblue: "#6495ed",
+ cornsilk: "#fff8dc",
+ crimson: "#dc143c",
+ cyan: "#00ffff",
+ darkblue: "#00008b",
+ darkcyan: "#008b8b",
+ darkgoldenrod: "#b8860b",
+ darkgray: "#a9a9a9",
+ darkgreen: "#006400",
+ darkgrey: "#a9a9a9",
+ darkkhaki: "#bdb76b",
+ darkmagenta: "#8b008b",
+ darkolivegreen: "#556b2f",
+ darkorange: "#ff8c00",
+ darkorchid: "#9932cc",
+ darkred: "#8b0000",
+ darksalmon: "#e9967a",
+ darkseagreen: "#8fbc8f",
+ darkslateblue: "#483d8b",
+ darkslategray: "#2f4f4f",
+ darkslategrey: "#2f4f4f",
+ darkturquoise: "#00ced1",
+ darkviolet: "#9400d3",
+ deeppink: "#ff1493",
+ deepskyblue: "#00bfff",
+ dimgray: "#696969",
+ dimgrey: "#696969",
+ dodgerblue: "#1e90ff",
+ firebrick: "#b22222",
+ floralwhite: "#fffaf0",
+ forestgreen: "#228b22",
+ fuchsia: "#ff00ff",
+ gainsboro: "#dcdcdc",
+ ghostwhite: "#f8f8ff",
+ gold: "#ffd700",
+ goldenrod: "#daa520",
+ gray: "#808080",
+ green: "#008000",
+ greenyellow: "#adff2f",
+ grey: "#808080",
+ honeydew: "#f0fff0",
+ hotpink: "#ff69b4",
+ indianred: "#cd5c5c",
+ indigo: "#4b0082",
+ ivory: "#fffff0",
+ khaki: "#f0e68c",
+ lavender: "#e6e6fa",
+ lavenderblush: "#fff0f5",
+ lawngreen: "#7cfc00",
+ lemonchiffon: "#fffacd",
+ lightblue: "#add8e6",
+ lightcoral: "#f08080",
+ lightcyan: "#e0ffff",
+ lightgoldenrodyellow: "#fafad2",
+ lightgray: "#d3d3d3",
+ lightgreen: "#90ee90",
+ lightgrey: "#d3d3d3",
+ lightpink: "#ffb6c1",
+ lightsalmon: "#ffa07a",
+ lightseagreen: "#20b2aa",
+ lightskyblue: "#87cefa",
+ lightslategray: "#778899",
+ lightslategrey: "#778899",
+ lightsteelblue: "#b0c4de",
+ lightyellow: "#ffffe0",
+ lime: "#00ff00",
+ limegreen: "#32cd32",
+ linen: "#faf0e6",
+ magenta: "#ff00ff",
+ maroon: "#800000",
+ mediumaquamarine: "#66cdaa",
+ mediumblue: "#0000cd",
+ mediumorchid: "#ba55d3",
+ mediumpurple: "#9370db",
+ mediumseagreen: "#3cb371",
+ mediumslateblue: "#7b68ee",
+ mediumspringgreen: "#00fa9a",
+ mediumturquoise: "#48d1cc",
+ mediumvioletred: "#c71585",
+ midnightblue: "#191970",
+ mintcream: "#f5fffa",
+ mistyrose: "#ffe4e1",
+ moccasin: "#ffe4b5",
+ navajowhite: "#ffdead",
+ navy: "#000080",
+ oldlace: "#fdf5e6",
+ olive: "#808000",
+ olivedrab: "#6b8e23",
+ orange: "#ffa500",
+ orangered: "#ff4500",
+ orchid: "#da70d6",
+ palegoldenrod: "#eee8aa",
+ palegreen: "#98fb98",
+ paleturquoise: "#afeeee",
+ palevioletred: "#db7093",
+ papayawhip: "#ffefd5",
+ peachpuff: "#ffdab9",
+ peru: "#cd853f",
+ pink: "#ffc0cb",
+ plum: "#dda0dd",
+ powderblue: "#b0e0e6",
+ purple: "#800080",
+ red: "#ff0000",
+ rosybrown: "#bc8f8f",
+ royalblue: "#4169e1",
+ saddlebrown: "#8b4513",
+ salmon: "#fa8072",
+ sandybrown: "#f4a460",
+ seagreen: "#2e8b57",
+ seashell: "#fff5ee",
+ sienna: "#a0522d",
+ silver: "#c0c0c0",
+ skyblue: "#87ceeb",
+ slateblue: "#6a5acd",
+ slategray: "#708090",
+ slategrey: "#708090",
+ snow: "#fffafa",
+ springgreen: "#00ff7f",
+ steelblue: "#4682b4",
+ tan: "#d2b48c",
+ teal: "#008080",
+ thistle: "#d8bfd8",
+ tomato: "#ff6347",
+ turquoise: "#40e0d0",
+ violet: "#ee82ee",
+ wheat: "#f5deb3",
+ white: "#ffffff",
+ whitesmoke: "#f5f5f5",
+ yellow: "#ffff00",
+ yellowgreen: "#9acd32"
+};
+
+MochiKit.Base._exportSymbols(this, MochiKit.Color);
diff --git a/frontend/gamma/js/MochiKit/DOM.js b/frontend/gamma/js/MochiKit/DOM.js
new file mode 100644
index 0000000..af5d46f
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/DOM.js
@@ -0,0 +1,1144 @@
+/***
+
+MochiKit.DOM 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('DOM', '1.5', ['Base']);
+
+MochiKit.Base.update(MochiKit.DOM, {
+
+ /** @id MochiKit.DOM.currentWindow */
+ currentWindow: function () {
+ return MochiKit.DOM._window;
+ },
+
+ /** @id MochiKit.DOM.currentDocument */
+ currentDocument: function () {
+ return MochiKit.DOM._document;
+ },
+
+ /** @id MochiKit.DOM.withWindow */
+ withWindow: function (win, func) {
+ var self = MochiKit.DOM;
+ var oldDoc = self._document;
+ var oldWin = self._window;
+ var rval;
+ try {
+ self._window = win;
+ self._document = win.document;
+ rval = func();
+ } catch (e) {
+ self._window = oldWin;
+ self._document = oldDoc;
+ throw e;
+ }
+ self._window = oldWin;
+ self._document = oldDoc;
+ return rval;
+ },
+
+ /** @id MochiKit.DOM.formContents */
+ formContents: function (elem/* = document.body */) {
+ var names = [];
+ var values = [];
+ var m = MochiKit.Base;
+ var self = MochiKit.DOM;
+ if (typeof(elem) == "undefined" || elem === null) {
+ elem = self._document.body;
+ } else {
+ elem = self.getElement(elem);
+ }
+ m.nodeWalk(elem, function (elem) {
+ var name = elem.name;
+ if (m.isNotEmpty(name)) {
+ var tagName = elem.tagName.toUpperCase();
+ if (tagName === "INPUT"
+ && (elem.type == "radio" || elem.type == "checkbox")
+ && !elem.checked
+ ) {
+ return null;
+ }
+ if (tagName === "SELECT") {
+ if (elem.type == "select-one") {
+ if (elem.selectedIndex >= 0) {
+ var opt = elem.options[elem.selectedIndex];
+ var v = opt.value;
+ if (!v) {
+ var h = opt.outerHTML;
+ // internet explorer sure does suck.
+ if (h && !h.match(/^[^>]+\svalue\s*=/i)) {
+ v = opt.text;
+ }
+ }
+ names.push(name);
+ values.push(v);
+ return null;
+ }
+ // no form elements?
+ names.push(name);
+ values.push("");
+ return null;
+ } else {
+ var opts = elem.options;
+ if (!opts.length) {
+ names.push(name);
+ values.push("");
+ return null;
+ }
+ for (var i = 0; i < opts.length; i++) {
+ var opt = opts[i];
+ if (!opt.selected) {
+ continue;
+ }
+ var v = opt.value;
+ if (!v) {
+ var h = opt.outerHTML;
+ // internet explorer sure does suck.
+ if (h && !h.match(/^[^>]+\svalue\s*=/i)) {
+ v = opt.text;
+ }
+ }
+ names.push(name);
+ values.push(v);
+ }
+ return null;
+ }
+ }
+ if (tagName === "FORM" || tagName === "P" || tagName === "SPAN"
+ || tagName === "DIV"
+ ) {
+ return elem.childNodes;
+ }
+ names.push(name);
+ values.push(elem.value || '');
+ return null;
+ }
+ return elem.childNodes;
+ });
+ return [names, values];
+ },
+
+ /** @id MochiKit.DOM.withDocument */
+ withDocument: function (doc, func) {
+ var self = MochiKit.DOM;
+ var oldDoc = self._document;
+ var rval;
+ try {
+ self._document = doc;
+ rval = func();
+ } catch (e) {
+ self._document = oldDoc;
+ throw e;
+ }
+ self._document = oldDoc;
+ return rval;
+ },
+
+ /** @id MochiKit.DOM.registerDOMConverter */
+ registerDOMConverter: function (name, check, wrap, /* optional */override) {
+ MochiKit.DOM.domConverters.register(name, check, wrap, override);
+ },
+
+ /** @id MochiKit.DOM.coerceToDOM */
+ coerceToDOM: function (node, ctx) {
+ var m = MochiKit.Base;
+ var im = MochiKit.Iter;
+ var self = MochiKit.DOM;
+ if (im) {
+ var iter = im.iter;
+ var repeat = im.repeat;
+ }
+ var map = m.map;
+ var domConverters = self.domConverters;
+ var coerceToDOM = arguments.callee;
+ var NotFound = m.NotFound;
+ while (true) {
+ if (typeof(node) == 'undefined' || node === null) {
+ return null;
+ }
+ // this is a safari childNodes object, avoiding crashes w/ attr
+ // lookup
+ if (typeof(node) == "function" &&
+ typeof(node.length) == "number" &&
+ !(node instanceof Function)) {
+ node = im ? im.list(node) : m.extend(null, node);
+ }
+ if (typeof(node.nodeType) != 'undefined' && node.nodeType > 0) {
+ return node;
+ }
+ if (typeof(node) == 'number' || typeof(node) == 'boolean') {
+ node = node.toString();
+ // FALL THROUGH
+ }
+ if (typeof(node) == 'string') {
+ return self._document.createTextNode(node);
+ }
+ if (typeof(node.__dom__) == 'function') {
+ node = node.__dom__(ctx);
+ continue;
+ }
+ if (typeof(node.dom) == 'function') {
+ node = node.dom(ctx);
+ continue;
+ }
+ if (typeof(node) == 'function') {
+ node = node.apply(ctx, [ctx]);
+ continue;
+ }
+
+ if (im) {
+ // iterable
+ var iterNodes = null;
+ try {
+ iterNodes = iter(node);
+ } catch (e) {
+ // pass
+ }
+ if (iterNodes) {
+ return map(coerceToDOM, iterNodes, repeat(ctx));
+ }
+ } else if (m.isArrayLike(node)) {
+ var func = function (n) { return coerceToDOM(n, ctx); };
+ return map(func, node);
+ }
+
+ // adapter
+ try {
+ node = domConverters.match(node, ctx);
+ continue;
+ } catch (e) {
+ if (e != NotFound) {
+ throw e;
+ }
+ }
+
+ // fallback
+ return self._document.createTextNode(node.toString());
+ }
+ // mozilla warnings aren't too bright
+ return undefined;
+ },
+
+ /** @id MochiKit.DOM.isChildNode */
+ isChildNode: function (node, maybeparent) {
+ var self = MochiKit.DOM;
+ if (typeof(node) == "string") {
+ node = self.getElement(node);
+ }
+ if (typeof(maybeparent) == "string") {
+ maybeparent = self.getElement(maybeparent);
+ }
+ if (typeof(node) == 'undefined' || node === null) {
+ return false;
+ }
+ while (node != null && node !== self._document) {
+ if (node === maybeparent) {
+ return true;
+ }
+ node = node.parentNode;
+ }
+ return false;
+ },
+
+ /** @id MochiKit.DOM.setNodeAttribute */
+ setNodeAttribute: function (node, attr, value) {
+ var o = {};
+ o[attr] = value;
+ try {
+ return MochiKit.DOM.updateNodeAttributes(node, o);
+ } catch (e) {
+ // pass
+ }
+ return null;
+ },
+
+ /** @id MochiKit.DOM.getNodeAttribute */
+ getNodeAttribute: function (node, attr) {
+ var self = MochiKit.DOM;
+ var rename = self.attributeArray.renames[attr];
+ var ignoreValue = self.attributeArray.ignoreAttr[attr];
+ node = self.getElement(node);
+ try {
+ if (rename) {
+ return node[rename];
+ }
+ var value = node.getAttribute(attr);
+ if (value != ignoreValue) {
+ return value;
+ }
+ } catch (e) {
+ // pass
+ }
+ return null;
+ },
+
+ /** @id MochiKit.DOM.removeNodeAttribute */
+ removeNodeAttribute: function (node, attr) {
+ var self = MochiKit.DOM;
+ var rename = self.attributeArray.renames[attr];
+ node = self.getElement(node);
+ try {
+ if (rename) {
+ return node[rename];
+ }
+ return node.removeAttribute(attr);
+ } catch (e) {
+ // pass
+ }
+ return null;
+ },
+
+ /** @id MochiKit.DOM.updateNodeAttributes */
+ updateNodeAttributes: function (node, attrs) {
+ var elem = node;
+ var self = MochiKit.DOM;
+ if (typeof(node) == 'string') {
+ elem = self.getElement(node);
+ }
+ if (attrs) {
+ var updatetree = MochiKit.Base.updatetree;
+ if (self.attributeArray.compliant) {
+ // not IE, good.
+ for (var k in attrs) {
+ var v = attrs[k];
+ if (typeof(v) == 'object' && typeof(elem[k]) == 'object') {
+ if (k == "style" && MochiKit.Style) {
+ MochiKit.Style.setStyle(elem, v);
+ } else {
+ updatetree(elem[k], v);
+ }
+ } else if (k.substring(0, 2) == "on") {
+ if (typeof(v) == "string") {
+ v = new Function(v);
+ }
+ elem[k] = v;
+ } else {
+ elem.setAttribute(k, v);
+ }
+ if (typeof(elem[k]) == "string" && elem[k] != v) {
+ // Also set property for weird attributes (see #302)
+ elem[k] = v;
+ }
+ }
+ } else {
+ // IE is insane in the membrane
+ var renames = self.attributeArray.renames;
+ for (var k in attrs) {
+ v = attrs[k];
+ var renamed = renames[k];
+ if (k == "style" && typeof(v) == "string") {
+ elem.style.cssText = v;
+ } else if (typeof(renamed) == "string") {
+ elem[renamed] = v;
+ } else if (typeof(elem[k]) == 'object'
+ && typeof(v) == 'object') {
+ if (k == "style" && MochiKit.Style) {
+ MochiKit.Style.setStyle(elem, v);
+ } else {
+ updatetree(elem[k], v);
+ }
+ } else if (k.substring(0, 2) == "on") {
+ if (typeof(v) == "string") {
+ v = new Function(v);
+ }
+ elem[k] = v;
+ } else {
+ elem.setAttribute(k, v);
+ }
+ if (typeof(elem[k]) == "string" && elem[k] != v) {
+ // Also set property for weird attributes (see #302)
+ elem[k] = v;
+ }
+ }
+ }
+ }
+ return elem;
+ },
+
+ /** @id MochiKit.DOM.appendChildNodes */
+ appendChildNodes: function (node/*, nodes...*/) {
+ var elem = node;
+ var self = MochiKit.DOM;
+ if (typeof(node) == 'string') {
+ elem = self.getElement(node);
+ }
+ var nodeStack = [
+ self.coerceToDOM(
+ MochiKit.Base.extend(null, arguments, 1),
+ elem
+ )
+ ];
+ var concat = MochiKit.Base.concat;
+ while (nodeStack.length) {
+ var n = nodeStack.shift();
+ if (typeof(n) == 'undefined' || n === null) {
+ // pass
+ } else if (typeof(n.nodeType) == 'number') {
+ elem.appendChild(n);
+ } else {
+ nodeStack = concat(n, nodeStack);
+ }
+ }
+ return elem;
+ },
+
+
+ /** @id MochiKit.DOM.insertSiblingNodesBefore */
+ insertSiblingNodesBefore: function (node/*, nodes...*/) {
+ var elem = node;
+ var self = MochiKit.DOM;
+ if (typeof(node) == 'string') {
+ elem = self.getElement(node);
+ }
+ var nodeStack = [
+ self.coerceToDOM(
+ MochiKit.Base.extend(null, arguments, 1),
+ elem
+ )
+ ];
+ var parentnode = elem.parentNode;
+ var concat = MochiKit.Base.concat;
+ while (nodeStack.length) {
+ var n = nodeStack.shift();
+ if (typeof(n) == 'undefined' || n === null) {
+ // pass
+ } else if (typeof(n.nodeType) == 'number') {
+ parentnode.insertBefore(n, elem);
+ } else {
+ nodeStack = concat(n, nodeStack);
+ }
+ }
+ return parentnode;
+ },
+
+ /** @id MochiKit.DOM.insertSiblingNodesAfter */
+ insertSiblingNodesAfter: function (node/*, nodes...*/) {
+ var elem = node;
+ var self = MochiKit.DOM;
+
+ if (typeof(node) == 'string') {
+ elem = self.getElement(node);
+ }
+ var nodeStack = [
+ self.coerceToDOM(
+ MochiKit.Base.extend(null, arguments, 1),
+ elem
+ )
+ ];
+
+ if (elem.nextSibling) {
+ return self.insertSiblingNodesBefore(elem.nextSibling, nodeStack);
+ }
+ else {
+ return self.appendChildNodes(elem.parentNode, nodeStack);
+ }
+ },
+
+ /** @id MochiKit.DOM.replaceChildNodes */
+ replaceChildNodes: function (node/*, nodes...*/) {
+ var elem = node;
+ var self = MochiKit.DOM;
+ if (typeof(node) == 'string') {
+ elem = self.getElement(node);
+ arguments[0] = elem;
+ }
+ var child;
+ while ((child = elem.firstChild)) {
+ elem.removeChild(child);
+ }
+ if (arguments.length < 2) {
+ return elem;
+ } else {
+ return self.appendChildNodes.apply(this, arguments);
+ }
+ },
+
+ /** @id MochiKit.DOM.createDOM */
+ createDOM: function (name, attrs/*, nodes... */) {
+ var elem;
+ var self = MochiKit.DOM;
+ var m = MochiKit.Base;
+ if (typeof(attrs) == "string" || typeof(attrs) == "number") {
+ var args = m.extend([name, null], arguments, 1);
+ return arguments.callee.apply(this, args);
+ }
+ if (typeof(name) == 'string') {
+ // Internet Explorer is dumb
+ var xhtml = self._xhtml;
+ if (attrs && !self.attributeArray.compliant) {
+ // http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/name_2.asp
+ var contents = "";
+ if ('name' in attrs) {
+ contents += ' name="' + self.escapeHTML(attrs.name) + '"';
+ }
+ if (name == 'input' && 'type' in attrs) {
+ contents += ' type="' + self.escapeHTML(attrs.type) + '"';
+ }
+ if (contents) {
+ name = "<" + name + contents + ">";
+ xhtml = false;
+ }
+ }
+ var d = self._document;
+ if (xhtml && d === document) {
+ elem = d.createElementNS("http://www.w3.org/1999/xhtml", name);
+ } else {
+ elem = d.createElement(name);
+ }
+ } else {
+ elem = name;
+ }
+ if (attrs) {
+ self.updateNodeAttributes(elem, attrs);
+ }
+ if (arguments.length <= 2) {
+ return elem;
+ } else {
+ var args = m.extend([elem], arguments, 2);
+ return self.appendChildNodes.apply(this, args);
+ }
+ },
+
+ /** @id MochiKit.DOM.createDOMFunc */
+ createDOMFunc: function (/* tag, attrs, *nodes */) {
+ var m = MochiKit.Base;
+ return m.partial.apply(
+ this,
+ m.extend([MochiKit.DOM.createDOM], arguments)
+ );
+ },
+
+ /** @id MochiKit.DOM.removeElement */
+ removeElement: function (elem) {
+ var self = MochiKit.DOM;
+ if (typeof(elem) == "string") {
+ elem = self.getElement(elem);
+ }
+ var e = self.coerceToDOM(elem);
+ e.parentNode.removeChild(e);
+ return e;
+ },
+
+ /** @id MochiKit.DOM.swapDOM */
+ swapDOM: function (dest, src) {
+ var self = MochiKit.DOM;
+ dest = self.getElement(dest);
+ var parent = dest.parentNode;
+ if (src) {
+ if (typeof(src) == "string") {
+ src = self.getElement(src);
+ }
+ src = self.coerceToDOM(src, parent);
+ parent.replaceChild(src, dest);
+ } else {
+ parent.removeChild(dest);
+ }
+ return src;
+ },
+
+ /** @id MochiKit.DOM.getElement */
+ getElement: function (id) {
+ var self = MochiKit.DOM;
+ if (arguments.length == 1) {
+ return ((typeof(id) == "string") ?
+ self._document.getElementById(id) : id);
+ } else {
+ return MochiKit.Base.map(self.getElement, arguments);
+ }
+ },
+
+ /** @id MochiKit.DOM.getElementsByTagAndClassName */
+ getElementsByTagAndClassName: function (tagName, className,
+ /* optional */parent) {
+ var self = MochiKit.DOM;
+ if (typeof(tagName) == 'undefined' || tagName === null) {
+ tagName = '*';
+ }
+ if (typeof(parent) == 'undefined' || parent === null) {
+ parent = self._document;
+ }
+ parent = self.getElement(parent);
+ if (parent == null) {
+ return [];
+ }
+ var children = (parent.getElementsByTagName(tagName)
+ || self._document.all);
+ if (typeof(className) == 'undefined' || className === null) {
+ return MochiKit.Base.extend(null, children);
+ }
+
+ var elements = [];
+ for (var i = 0; i < children.length; i++) {
+ var child = children[i];
+ var cls = child.className;
+ if (typeof(cls) != "string") {
+ cls = child.getAttribute("class");
+ }
+ if (typeof(cls) == "string") {
+ var classNames = cls.split(' ');
+ for (var j = 0; j < classNames.length; j++) {
+ if (classNames[j] == className) {
+ elements.push(child);
+ break;
+ }
+ }
+ }
+ }
+
+ return elements;
+ },
+
+ _newCallStack: function (path, once) {
+ var rval = function () {
+ var callStack = arguments.callee.callStack;
+ for (var i = 0; i < callStack.length; i++) {
+ if (callStack[i].apply(this, arguments) === false) {
+ break;
+ }
+ }
+ if (once) {
+ try {
+ this[path] = null;
+ } catch (e) {
+ // pass
+ }
+ }
+ };
+ rval.callStack = [];
+ return rval;
+ },
+
+ /** @id MochiKit.DOM.addToCallStack */
+ addToCallStack: function (target, path, func, once) {
+ var self = MochiKit.DOM;
+ var existing = target[path];
+ var regfunc = existing;
+ if (!(typeof(existing) == 'function'
+ && typeof(existing.callStack) == "object"
+ && existing.callStack !== null)) {
+ regfunc = self._newCallStack(path, once);
+ if (typeof(existing) == 'function') {
+ regfunc.callStack.push(existing);
+ }
+ target[path] = regfunc;
+ }
+ regfunc.callStack.push(func);
+ },
+
+ /** @id MochiKit.DOM.addLoadEvent */
+ addLoadEvent: function (func) {
+ var self = MochiKit.DOM;
+ self.addToCallStack(self._window, "onload", func, true);
+
+ },
+
+ /** @id MochiKit.DOM.focusOnLoad */
+ focusOnLoad: function (element) {
+ var self = MochiKit.DOM;
+ self.addLoadEvent(function () {
+ element = self.getElement(element);
+ if (element) {
+ element.focus();
+ }
+ });
+ },
+
+ /** @id MochiKit.DOM.setElementClass */
+ setElementClass: function (element, className) {
+ var self = MochiKit.DOM;
+ var obj = self.getElement(element);
+ if (self.attributeArray.compliant) {
+ obj.setAttribute("class", className);
+ } else {
+ obj.setAttribute("className", className);
+ }
+ },
+
+ /** @id MochiKit.DOM.toggleElementClass */
+ toggleElementClass: function (className/*, element... */) {
+ var self = MochiKit.DOM;
+ for (var i = 1; i < arguments.length; i++) {
+ var obj = self.getElement(arguments[i]);
+ if (!self.addElementClass(obj, className)) {
+ self.removeElementClass(obj, className);
+ }
+ }
+ },
+
+ /** @id MochiKit.DOM.addElementClass */
+ addElementClass: function (element, className) {
+ var self = MochiKit.DOM;
+ var obj = self.getElement(element);
+ var cls = obj.className;
+ if (typeof(cls) != "string") {
+ cls = obj.getAttribute("class");
+ }
+ // trivial case, no className yet
+ if (typeof(cls) != "string" || cls.length === 0) {
+ self.setElementClass(obj, className);
+ return true;
+ }
+ // the other trivial case, already set as the only class
+ if (cls == className) {
+ return false;
+ }
+ var classes = cls.split(" ");
+ for (var i = 0; i < classes.length; i++) {
+ // already present
+ if (classes[i] == className) {
+ return false;
+ }
+ }
+ // append class
+ self.setElementClass(obj, cls + " " + className);
+ return true;
+ },
+
+ /** @id MochiKit.DOM.removeElementClass */
+ removeElementClass: function (element, className) {
+ var self = MochiKit.DOM;
+ var obj = self.getElement(element);
+ var cls = obj.className;
+ if (typeof(cls) != "string") {
+ cls = obj.getAttribute("class");
+ }
+ // trivial case, no className yet
+ if (typeof(cls) != "string" || cls.length === 0) {
+ return false;
+ }
+ // other trivial case, set only to className
+ if (cls == className) {
+ self.setElementClass(obj, "");
+ return true;
+ }
+ var classes = cls.split(" ");
+ for (var i = 0; i < classes.length; i++) {
+ // already present
+ if (classes[i] == className) {
+ // only check sane case where the class is used once
+ classes.splice(i, 1);
+ self.setElementClass(obj, classes.join(" "));
+ return true;
+ }
+ }
+ // not found
+ return false;
+ },
+
+ /** @id MochiKit.DOM.swapElementClass */
+ swapElementClass: function (element, fromClass, toClass) {
+ var obj = MochiKit.DOM.getElement(element);
+ var res = MochiKit.DOM.removeElementClass(obj, fromClass);
+ if (res) {
+ MochiKit.DOM.addElementClass(obj, toClass);
+ }
+ return res;
+ },
+
+ /** @id MochiKit.DOM.hasElementClass */
+ hasElementClass: function (element, className/*...*/) {
+ var obj = MochiKit.DOM.getElement(element);
+ if (obj == null) {
+ return false;
+ }
+ var cls = obj.className;
+ if (typeof(cls) != "string" && typeof(obj.getAttribute) == "function") {
+ cls = obj.getAttribute("class");
+ }
+ if (typeof(cls) != "string") {
+ return false;
+ }
+ var classes = cls.split(" ");
+ for (var i = 1; i < arguments.length; i++) {
+ var good = false;
+ for (var j = 0; j < classes.length; j++) {
+ if (classes[j] == arguments[i]) {
+ good = true;
+ break;
+ }
+ }
+ if (!good) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /** @id MochiKit.DOM.escapeHTML */
+ escapeHTML: function (s) {
+ return s.replace(/&/g, "&amp;"
+ ).replace(/"/g, "&quot;"
+ ).replace(/</g, "&lt;"
+ ).replace(/>/g, "&gt;");
+ },
+
+ /** @id MochiKit.DOM.toHTML */
+ toHTML: function (dom) {
+ return MochiKit.DOM.emitHTML(dom).join("");
+ },
+
+ /** @id MochiKit.DOM.emitHTML */
+ emitHTML: function (dom, /* optional */lst) {
+ if (typeof(lst) == 'undefined' || lst === null) {
+ lst = [];
+ }
+ // queue is the call stack, we're doing this non-recursively
+ var queue = [dom];
+ var self = MochiKit.DOM;
+ var escapeHTML = self.escapeHTML;
+ var attributeArray = self.attributeArray;
+ while (queue.length) {
+ dom = queue.pop();
+ if (typeof(dom) == 'string') {
+ lst.push(dom);
+ } else if (dom.nodeType == 1) {
+ // we're not using higher order stuff here
+ // because safari has heisenbugs.. argh.
+ //
+ // I think it might have something to do with
+ // garbage collection and function calls.
+ lst.push('<' + dom.tagName.toLowerCase());
+ var attributes = [];
+ var domAttr = attributeArray(dom);
+ for (var i = 0; i < domAttr.length; i++) {
+ var a = domAttr[i];
+ attributes.push([
+ " ",
+ a.name,
+ '="',
+ escapeHTML(a.value),
+ '"'
+ ]);
+ }
+ attributes.sort();
+ for (i = 0; i < attributes.length; i++) {
+ var attrs = attributes[i];
+ for (var j = 0; j < attrs.length; j++) {
+ lst.push(attrs[j]);
+ }
+ }
+ if (dom.hasChildNodes()) {
+ lst.push(">");
+ // queue is the FILO call stack, so we put the close tag
+ // on first
+ queue.push("</" + dom.tagName.toLowerCase() + ">");
+ var cnodes = dom.childNodes;
+ for (i = cnodes.length - 1; i >= 0; i--) {
+ queue.push(cnodes[i]);
+ }
+ } else {
+ lst.push('/>');
+ }
+ } else if (dom.nodeType == 3) {
+ lst.push(escapeHTML(dom.nodeValue));
+ }
+ }
+ return lst;
+ },
+
+ /** @id MochiKit.DOM.scrapeText */
+ scrapeText: function (node, /* optional */asArray) {
+ var rval = [];
+ (function (node) {
+ var cn = node.childNodes;
+ if (cn) {
+ for (var i = 0; i < cn.length; i++) {
+ arguments.callee.call(this, cn[i]);
+ }
+ }
+ var nodeValue = node.nodeValue;
+ if (typeof(nodeValue) == 'string') {
+ rval.push(nodeValue);
+ }
+ })(MochiKit.DOM.getElement(node));
+ if (asArray) {
+ return rval;
+ } else {
+ return rval.join("");
+ }
+ },
+
+ /** @id MochiKit.DOM.removeEmptyTextNodes */
+ removeEmptyTextNodes: function (element) {
+ element = MochiKit.DOM.getElement(element);
+ for (var i = 0; i < element.childNodes.length; i++) {
+ var node = element.childNodes[i];
+ if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) {
+ node.parentNode.removeChild(node);
+ }
+ }
+ },
+
+ /** @id MochiKit.DOM.getFirstElementByTagAndClassName */
+ getFirstElementByTagAndClassName: function (tagName, className,
+ /* optional */parent) {
+ var self = MochiKit.DOM;
+ if (typeof(tagName) == 'undefined' || tagName === null) {
+ tagName = '*';
+ }
+ if (typeof(parent) == 'undefined' || parent === null) {
+ parent = self._document;
+ }
+ parent = self.getElement(parent);
+ if (parent == null) {
+ return null;
+ }
+ var children = (parent.getElementsByTagName(tagName)
+ || self._document.all);
+ if (children.length <= 0) {
+ return null;
+ } else if (typeof(className) == 'undefined' || className === null) {
+ return children[0];
+ }
+
+ for (var i = 0; i < children.length; i++) {
+ var child = children[i];
+ var cls = child.className;
+ if (typeof(cls) != "string") {
+ cls = child.getAttribute("class");
+ }
+ if (typeof(cls) == "string") {
+ var classNames = cls.split(' ');
+ for (var j = 0; j < classNames.length; j++) {
+ if (classNames[j] == className) {
+ return child;
+ }
+ }
+ }
+ }
+ return null;
+ },
+
+ /** @id MochiKit.DOM.getFirstParentByTagAndClassName */
+ getFirstParentByTagAndClassName: function (elem, tagName, className) {
+ var self = MochiKit.DOM;
+ elem = self.getElement(elem);
+ if (typeof(tagName) == 'undefined' || tagName === null) {
+ tagName = '*';
+ } else {
+ tagName = tagName.toUpperCase();
+ }
+ if (typeof(className) == 'undefined' || className === null) {
+ className = null;
+ }
+ if (elem) {
+ elem = elem.parentNode;
+ }
+ while (elem && elem.tagName) {
+ var curTagName = elem.tagName.toUpperCase();
+ if ((tagName === '*' || tagName == curTagName) &&
+ (className === null || self.hasElementClass(elem, className))) {
+ return elem;
+ }
+ elem = elem.parentNode;
+ }
+ return null;
+ },
+
+ __new__: function (win) {
+
+ var m = MochiKit.Base;
+ if (typeof(document) != "undefined") {
+ this._document = document;
+ var kXULNSURI = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ this._xhtml = (document.documentElement &&
+ document.createElementNS &&
+ document.documentElement.namespaceURI === kXULNSURI);
+ } else if (MochiKit.MockDOM) {
+ this._document = MochiKit.MockDOM.document;
+ }
+ this._window = win;
+
+ this.domConverters = new m.AdapterRegistry();
+
+ var __tmpElement = this._document.createElement("span");
+ var attributeArray;
+ if (__tmpElement && __tmpElement.attributes &&
+ __tmpElement.attributes.length > 0) {
+ // for braindead browsers (IE) that insert extra junk
+ var filter = m.filter;
+ attributeArray = function (node) {
+ /***
+
+ Return an array of attributes for a given node,
+ filtering out attributes that don't belong for
+ that are inserted by "Certain Browsers".
+
+ ***/
+ return filter(attributeArray.ignoreAttrFilter, node.attributes);
+ };
+ attributeArray.ignoreAttr = {};
+ var attrs = __tmpElement.attributes;
+ var ignoreAttr = attributeArray.ignoreAttr;
+ for (var i = 0; i < attrs.length; i++) {
+ var a = attrs[i];
+ ignoreAttr[a.name] = a.value;
+ }
+ attributeArray.ignoreAttrFilter = function (a) {
+ return (attributeArray.ignoreAttr[a.name] != a.value);
+ };
+ attributeArray.compliant = false;
+ attributeArray.renames = {
+ "class": "className",
+ "checked": "defaultChecked",
+ "usemap": "useMap",
+ "for": "htmlFor",
+ "readonly": "readOnly",
+ "colspan": "colSpan",
+ "bgcolor": "bgColor",
+ "cellspacing": "cellSpacing",
+ "cellpadding": "cellPadding"
+ };
+ } else {
+ attributeArray = function (node) {
+ return node.attributes;
+ };
+ attributeArray.compliant = true;
+ attributeArray.ignoreAttr = {};
+ attributeArray.renames = {};
+ }
+ attributeArray.__export__ = false;
+ this.attributeArray = attributeArray;
+
+ // Backwards compatibility aliases
+ /** @id MochiKit.DOM.computedStyle */
+ m._deprecated(this, 'computedStyle', 'MochiKit.Style.getStyle', '1.4');
+ /** @id MochiKit.DOM.elementDimensions */
+ m._deprecated(this, 'elementDimensions', 'MochiKit.Style.getElementDimensions', '1.4');
+ /** @id MochiKit.DOM.elementPosition */
+ m._deprecated(this, 'elementPosition', 'MochiKit.Style.getElementPosition', '1.4');
+ /** @id MochiKit.DOM.getViewportDimensions */
+ m._deprecated(this, 'getViewportDimensions', 'MochiKit.Style.getViewportDimensions', '1.4');
+ /** @id MochiKit.DOM.hideElement */
+ m._deprecated(this, 'hideElement', 'MochiKit.Style.hideElement', '1.4');
+ /** @id MochiKit.DOM.makeClipping */
+ m._deprecated(this, 'makeClipping', 'MochiKit.Style.makeClipping', '1.4.1');
+ /** @id MochiKit.DOM.makePositioned */
+ m._deprecated(this, 'makePositioned', 'MochiKit.Style.makePositioned', '1.4.1');
+ /** @id MochiKit.DOM.setElementDimensions */
+ m._deprecated(this, 'setElementDimensions', 'MochiKit.Style.setElementDimensions', '1.4');
+ /** @id MochiKit.DOM.setElementPosition */
+ m._deprecated(this, 'setElementPosition', 'MochiKit.Style.setElementPosition', '1.4');
+ /** @id MochiKit.DOM.setDisplayForElement */
+ m._deprecated(this, 'setDisplayForElement', 'MochiKit.Style.setDisplayForElement', '1.4');
+ /** @id MochiKit.DOM.setOpacity */
+ m._deprecated(this, 'setOpacity', 'MochiKit.Style.setOpacity', '1.4');
+ /** @id MochiKit.DOM.showElement */
+ m._deprecated(this, 'showElement', 'MochiKit.Style.showElement', '1.4');
+ /** @id MochiKit.DOM.undoClipping */
+ m._deprecated(this, 'undoClipping', 'MochiKit.Style.undoClipping', '1.4.1');
+ /** @id MochiKit.DOM.undoPositioned */
+ m._deprecated(this, 'undoPositioned', 'MochiKit.Style.undoPositioned', '1.4.1');
+ /** @id MochiKit.DOM.Coordinates */
+ m._deprecated(this, 'Coordinates', 'MochiKit.Style.Coordinates', '1.4');
+ /** @id MochiKit.DOM.Dimensions */
+ m._deprecated(this, 'Dimensions', 'MochiKit.Style.Dimensions', '1.4');
+
+ // shorthand for createDOM syntax
+ var createDOMFunc = this.createDOMFunc;
+ /** @id MochiKit.DOM.UL */
+ this.UL = createDOMFunc("ul");
+ /** @id MochiKit.DOM.OL */
+ this.OL = createDOMFunc("ol");
+ /** @id MochiKit.DOM.LI */
+ this.LI = createDOMFunc("li");
+ /** @id MochiKit.DOM.DL */
+ this.DL = createDOMFunc("dl");
+ /** @id MochiKit.DOM.DT */
+ this.DT = createDOMFunc("dt");
+ /** @id MochiKit.DOM.DD */
+ this.DD = createDOMFunc("dd");
+ /** @id MochiKit.DOM.TD */
+ this.TD = createDOMFunc("td");
+ /** @id MochiKit.DOM.TR */
+ this.TR = createDOMFunc("tr");
+ /** @id MochiKit.DOM.TBODY */
+ this.TBODY = createDOMFunc("tbody");
+ /** @id MochiKit.DOM.THEAD */
+ this.THEAD = createDOMFunc("thead");
+ /** @id MochiKit.DOM.TFOOT */
+ this.TFOOT = createDOMFunc("tfoot");
+ /** @id MochiKit.DOM.TABLE */
+ this.TABLE = createDOMFunc("table");
+ /** @id MochiKit.DOM.TH */
+ this.TH = createDOMFunc("th");
+ /** @id MochiKit.DOM.INPUT */
+ this.INPUT = createDOMFunc("input");
+ /** @id MochiKit.DOM.SPAN */
+ this.SPAN = createDOMFunc("span");
+ /** @id MochiKit.DOM.A */
+ this.A = createDOMFunc("a");
+ /** @id MochiKit.DOM.DIV */
+ this.DIV = createDOMFunc("div");
+ /** @id MochiKit.DOM.IMG */
+ this.IMG = createDOMFunc("img");
+ /** @id MochiKit.DOM.BUTTON */
+ this.BUTTON = createDOMFunc("button");
+ /** @id MochiKit.DOM.TT */
+ this.TT = createDOMFunc("tt");
+ /** @id MochiKit.DOM.PRE */
+ this.PRE = createDOMFunc("pre");
+ /** @id MochiKit.DOM.H1 */
+ this.H1 = createDOMFunc("h1");
+ /** @id MochiKit.DOM.H2 */
+ this.H2 = createDOMFunc("h2");
+ /** @id MochiKit.DOM.H3 */
+ this.H3 = createDOMFunc("h3");
+ /** @id MochiKit.DOM.H4 */
+ this.H4 = createDOMFunc("h4");
+ /** @id MochiKit.DOM.H5 */
+ this.H5 = createDOMFunc("h5");
+ /** @id MochiKit.DOM.H6 */
+ this.H6 = createDOMFunc("h6");
+ /** @id MochiKit.DOM.BR */
+ this.BR = createDOMFunc("br");
+ /** @id MochiKit.DOM.HR */
+ this.HR = createDOMFunc("hr");
+ /** @id MochiKit.DOM.LABEL */
+ this.LABEL = createDOMFunc("label");
+ /** @id MochiKit.DOM.TEXTAREA */
+ this.TEXTAREA = createDOMFunc("textarea");
+ /** @id MochiKit.DOM.FORM */
+ this.FORM = createDOMFunc("form");
+ /** @id MochiKit.DOM.P */
+ this.P = createDOMFunc("p");
+ /** @id MochiKit.DOM.SELECT */
+ this.SELECT = createDOMFunc("select");
+ /** @id MochiKit.DOM.OPTION */
+ this.OPTION = createDOMFunc("option");
+ /** @id MochiKit.DOM.OPTGROUP */
+ this.OPTGROUP = createDOMFunc("optgroup");
+ /** @id MochiKit.DOM.LEGEND */
+ this.LEGEND = createDOMFunc("legend");
+ /** @id MochiKit.DOM.FIELDSET */
+ this.FIELDSET = createDOMFunc("fieldset");
+ /** @id MochiKit.DOM.STRONG */
+ this.STRONG = createDOMFunc("strong");
+ /** @id MochiKit.DOM.CANVAS */
+ this.CANVAS = createDOMFunc("canvas");
+
+ /** @id MochiKit.DOM.$ */
+ this.$ = this.getElement;
+
+ m.nameFunctions(this);
+
+ }
+});
+
+
+MochiKit.DOM.__new__(((typeof(window) == "undefined") ? this : window));
+
+//
+// XXX: Internet Explorer blows
+//
+if (MochiKit.__export__) {
+ withWindow = MochiKit.DOM.withWindow;
+ withDocument = MochiKit.DOM.withDocument;
+}
+
+MochiKit.Base._exportSymbols(this, MochiKit.DOM);
diff --git a/frontend/gamma/js/MochiKit/DateTime.js b/frontend/gamma/js/MochiKit/DateTime.js
new file mode 100644
index 0000000..c7b2d25
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/DateTime.js
@@ -0,0 +1,173 @@
+/***
+
+MochiKit.DateTime 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('DateTime', '1.5', ['Base']);
+
+/** @id MochiKit.DateTime.isoDate */
+MochiKit.DateTime.isoDate = function (str) {
+ str = str + "";
+ if (typeof(str) != "string" || str.length === 0) {
+ return null;
+ }
+ var iso = str.split('-');
+ if (iso.length === 0) {
+ return null;
+ }
+ var date = new Date(iso[0], iso[1] - 1, iso[2]);
+ date.setFullYear(iso[0]);
+ date.setMonth(iso[1] - 1);
+ date.setDate(iso[2]);
+ return date;
+};
+
+MochiKit.DateTime._isoRegexp = /(\d{4,})(?:-(\d{1,2})(?:-(\d{1,2})(?:[T ](\d{1,2}):(\d{1,2})(?::(\d{1,2})(?:\.(\d+))?)?(?:(Z)|([+-])(\d{1,2})(?::(\d{1,2}))?)?)?)?)?/;
+
+/** @id MochiKit.DateTime.isoTimestamp */
+MochiKit.DateTime.isoTimestamp = function (str) {
+ str = str + "";
+ if (typeof(str) != "string" || str.length === 0) {
+ return null;
+ }
+ var res = str.match(MochiKit.DateTime._isoRegexp);
+ if (typeof(res) == "undefined" || res === null) {
+ return null;
+ }
+ var year, month, day, hour, min, sec, msec;
+ year = parseInt(res[1], 10);
+ if (typeof(res[2]) == "undefined" || res[2] === '') {
+ return new Date(year);
+ }
+ month = parseInt(res[2], 10) - 1;
+ day = parseInt(res[3], 10);
+ if (typeof(res[4]) == "undefined" || res[4] === '') {
+ return new Date(year, month, day);
+ }
+ hour = parseInt(res[4], 10);
+ min = parseInt(res[5], 10);
+ sec = (typeof(res[6]) != "undefined" && res[6] !== '') ? parseInt(res[6], 10) : 0;
+ if (typeof(res[7]) != "undefined" && res[7] !== '') {
+ msec = Math.round(1000.0 * parseFloat("0." + res[7]));
+ } else {
+ msec = 0;
+ }
+ if ((typeof(res[8]) == "undefined" || res[8] === '') && (typeof(res[9]) == "undefined" || res[9] === '')) {
+ return new Date(year, month, day, hour, min, sec, msec);
+ }
+ var ofs;
+ if (typeof(res[9]) != "undefined" && res[9] !== '') {
+ ofs = parseInt(res[10], 10) * 3600000;
+ if (typeof(res[11]) != "undefined" && res[11] !== '') {
+ ofs += parseInt(res[11], 10) * 60000;
+ }
+ if (res[9] == "-") {
+ ofs = -ofs;
+ }
+ } else {
+ ofs = 0;
+ }
+ return new Date(Date.UTC(year, month, day, hour, min, sec, msec) - ofs);
+};
+
+/** @id MochiKit.DateTime.toISOTime */
+MochiKit.DateTime.toISOTime = function (date, realISO/* = false */) {
+ if (typeof(date) == "undefined" || date === null) {
+ return null;
+ }
+ var hh = date.getHours();
+ var mm = date.getMinutes();
+ var ss = date.getSeconds();
+ var lst = [
+ ((realISO && (hh < 10)) ? "0" + hh : hh),
+ ((mm < 10) ? "0" + mm : mm),
+ ((ss < 10) ? "0" + ss : ss)
+ ];
+ return lst.join(":");
+};
+
+/** @id MochiKit.DateTime.toISOTimeStamp */
+MochiKit.DateTime.toISOTimestamp = function (date, realISO/* = false*/) {
+ if (typeof(date) == "undefined" || date === null) {
+ return null;
+ }
+ var sep = realISO ? "T" : " ";
+ var foot = realISO ? "Z" : "";
+ if (realISO) {
+ date = new Date(date.getTime() + (date.getTimezoneOffset() * 60000));
+ }
+ return MochiKit.DateTime.toISODate(date) + sep + MochiKit.DateTime.toISOTime(date, realISO) + foot;
+};
+
+/** @id MochiKit.DateTime.toISODate */
+MochiKit.DateTime.toISODate = function (date) {
+ if (typeof(date) == "undefined" || date === null) {
+ return null;
+ }
+ var _padTwo = MochiKit.DateTime._padTwo;
+ var _padFour = MochiKit.DateTime._padFour;
+ return [
+ _padFour(date.getFullYear()),
+ _padTwo(date.getMonth() + 1),
+ _padTwo(date.getDate())
+ ].join("-");
+};
+
+/** @id MochiKit.DateTime.americanDate */
+MochiKit.DateTime.americanDate = function (d) {
+ d = d + "";
+ if (typeof(d) != "string" || d.length === 0) {
+ return null;
+ }
+ var a = d.split('/');
+ return new Date(a[2], a[0] - 1, a[1]);
+};
+
+MochiKit.DateTime._padTwo = function (n) {
+ return (n > 9) ? n : "0" + n;
+};
+
+MochiKit.DateTime._padFour = function(n) {
+ switch(n.toString().length) {
+ case 1: return "000" + n; break;
+ case 2: return "00" + n; break;
+ case 3: return "0" + n; break;
+ case 4:
+ default:
+ return n;
+ }
+};
+
+/** @id MochiKit.DateTime.toPaddedAmericanDate */
+MochiKit.DateTime.toPaddedAmericanDate = function (d) {
+ if (typeof(d) == "undefined" || d === null) {
+ return null;
+ }
+ var _padTwo = MochiKit.DateTime._padTwo;
+ return [
+ _padTwo(d.getMonth() + 1),
+ _padTwo(d.getDate()),
+ d.getFullYear()
+ ].join('/');
+};
+
+/** @id MochiKit.DateTime.toAmericanDate */
+MochiKit.DateTime.toAmericanDate = function (d) {
+ if (typeof(d) == "undefined" || d === null) {
+ return null;
+ }
+ return [d.getMonth() + 1, d.getDate(), d.getFullYear()].join('/');
+};
+
+MochiKit.DateTime.__new__ = function () {
+ MochiKit.Base.nameFunctions(this);
+};
+
+MochiKit.DateTime.__new__();
+
+MochiKit.Base._exportSymbols(this, MochiKit.DateTime);
diff --git a/frontend/gamma/js/MochiKit/DragAndDrop.js b/frontend/gamma/js/MochiKit/DragAndDrop.js
new file mode 100644
index 0000000..62777c5
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/DragAndDrop.js
@@ -0,0 +1,766 @@
+/***
+MochiKit.DragAndDrop 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+ Mochi-ized By Thomas Herve (_firstname_@nimail.org)
+
+***/
+
+MochiKit.Base._module('DragAndDrop', '1.5', ['Base', 'Iter', 'DOM', 'Signal', 'Visual', 'Position']);
+
+MochiKit.DragAndDrop.Droppables = {
+ /***
+
+ Manage all droppables. Shouldn't be used, use the Droppable object instead.
+
+ ***/
+ drops: [],
+
+ remove: function (element) {
+ this.drops = MochiKit.Base.filter(function (d) {
+ return d.element != MochiKit.DOM.getElement(element);
+ }, this.drops);
+ },
+
+ register: function (drop) {
+ this.drops.push(drop);
+ },
+
+ unregister: function (drop) {
+ this.drops = MochiKit.Base.filter(function (d) {
+ return d != drop;
+ }, this.drops);
+ },
+
+ prepare: function (element) {
+ MochiKit.Base.map(function (drop) {
+ if (drop.isAccepted(element)) {
+ if (drop.options.activeclass) {
+ MochiKit.DOM.addElementClass(drop.element,
+ drop.options.activeclass);
+ }
+ drop.options.onactive(drop.element, element);
+ }
+ }, this.drops);
+ },
+
+ findDeepestChild: function (drops) {
+ var deepest = drops[0];
+
+ for (var i = 1; i < drops.length; ++i) {
+ if (MochiKit.DOM.isChildNode(drops[i].element, deepest.element)) {
+ deepest = drops[i];
+ }
+ }
+ return deepest;
+ },
+
+ show: function (point, element) {
+ if (!this.drops.length) {
+ return;
+ }
+ var affected = [];
+
+ if (this.last_active) {
+ this.last_active.deactivate();
+ }
+ MochiKit.Iter.forEach(this.drops, function (drop) {
+ if (drop.isAffected(point, element)) {
+ affected.push(drop);
+ }
+ });
+ if (affected.length > 0) {
+ var drop = this.findDeepestChild(affected);
+ MochiKit.Position.within(drop.element, point.page.x, point.page.y);
+ drop.options.onhover(element, drop.element,
+ MochiKit.Position.overlap(drop.options.overlap, drop.element));
+ drop.activate();
+ }
+ },
+
+ fire: function (event, element) {
+ if (!this.last_active) {
+ return;
+ }
+ MochiKit.Position.prepare();
+
+ if (this.last_active.isAffected(event.mouse(), element)) {
+ this.last_active.options.ondrop(element,
+ this.last_active.element, event);
+ }
+ },
+
+ reset: function (element) {
+ MochiKit.Base.map(function (drop) {
+ if (drop.options.activeclass) {
+ MochiKit.DOM.removeElementClass(drop.element,
+ drop.options.activeclass);
+ }
+ drop.options.ondesactive(drop.element, element);
+ }, this.drops);
+ if (this.last_active) {
+ this.last_active.deactivate();
+ }
+ }
+};
+
+/** @id MochiKit.DragAndDrop.Droppable */
+MochiKit.DragAndDrop.Droppable = function (element, options) {
+ var cls = arguments.callee;
+ if (!(this instanceof cls)) {
+ return new cls(element, options);
+ }
+ this.__init__(element, options);
+};
+
+MochiKit.DragAndDrop.Droppable.prototype = {
+ /***
+
+ A droppable object. Simple use is to create giving an element:
+
+ new MochiKit.DragAndDrop.Droppable('myelement');
+
+ Generally you'll want to define the 'ondrop' function and maybe the
+ 'accept' option to filter draggables.
+
+ ***/
+ __class__: MochiKit.DragAndDrop.Droppable,
+
+ __init__: function (element, /* optional */options) {
+ var d = MochiKit.DOM;
+ var b = MochiKit.Base;
+ this.element = d.getElement(element);
+ this.options = b.update({
+
+ /** @id MochiKit.DragAndDrop.greedy */
+ greedy: true,
+
+ /** @id MochiKit.DragAndDrop.hoverclass */
+ hoverclass: null,
+
+ /** @id MochiKit.DragAndDrop.activeclass */
+ activeclass: null,
+
+ /** @id MochiKit.DragAndDrop.hoverfunc */
+ hoverfunc: b.noop,
+
+ /** @id MochiKit.DragAndDrop.accept */
+ accept: null,
+
+ /** @id MochiKit.DragAndDrop.onactive */
+ onactive: b.noop,
+
+ /** @id MochiKit.DragAndDrop.ondesactive */
+ ondesactive: b.noop,
+
+ /** @id MochiKit.DragAndDrop.onhover */
+ onhover: b.noop,
+
+ /** @id MochiKit.DragAndDrop.ondrop */
+ ondrop: b.noop,
+
+ /** @id MochiKit.DragAndDrop.containment */
+ containment: [],
+ tree: false
+ }, options);
+
+ // cache containers
+ this.options._containers = [];
+ b.map(MochiKit.Base.bind(function (c) {
+ this.options._containers.push(d.getElement(c));
+ }, this), this.options.containment);
+
+ MochiKit.Style.makePositioned(this.element); // fix IE
+
+ MochiKit.DragAndDrop.Droppables.register(this);
+ },
+
+ /** @id MochiKit.DragAndDrop.isContained */
+ isContained: function (element) {
+ if (this.options._containers.length) {
+ var containmentNode;
+ if (this.options.tree) {
+ containmentNode = element.treeNode;
+ } else {
+ containmentNode = element.parentNode;
+ }
+ return MochiKit.Iter.some(this.options._containers, function (c) {
+ return containmentNode == c;
+ });
+ } else {
+ return true;
+ }
+ },
+
+ /** @id MochiKit.DragAndDrop.isAccepted */
+ isAccepted: function (element) {
+ return ((!this.options.accept) || MochiKit.Iter.some(
+ this.options.accept, function (c) {
+ return MochiKit.DOM.hasElementClass(element, c);
+ }));
+ },
+
+ /** @id MochiKit.DragAndDrop.isAffected */
+ isAffected: function (point, element) {
+ return ((this.element != element) &&
+ this.isContained(element) &&
+ this.isAccepted(element) &&
+ MochiKit.Position.within(this.element, point.page.x,
+ point.page.y));
+ },
+
+ /** @id MochiKit.DragAndDrop.deactivate */
+ deactivate: function () {
+ /***
+
+ A droppable is deactivate when a draggable has been over it and left.
+
+ ***/
+ if (this.options.hoverclass) {
+ MochiKit.DOM.removeElementClass(this.element,
+ this.options.hoverclass);
+ }
+ this.options.hoverfunc(this.element, false);
+ MochiKit.DragAndDrop.Droppables.last_active = null;
+ },
+
+ /** @id MochiKit.DragAndDrop.activate */
+ activate: function () {
+ /***
+
+ A droppable is active when a draggable is over it.
+
+ ***/
+ if (this.options.hoverclass) {
+ MochiKit.DOM.addElementClass(this.element, this.options.hoverclass);
+ }
+ this.options.hoverfunc(this.element, true);
+ MochiKit.DragAndDrop.Droppables.last_active = this;
+ },
+
+ /** @id MochiKit.DragAndDrop.destroy */
+ destroy: function () {
+ /***
+
+ Delete this droppable.
+
+ ***/
+ MochiKit.DragAndDrop.Droppables.unregister(this);
+ },
+
+ /** @id MochiKit.DragAndDrop.repr */
+ repr: function () {
+ return '[' + this.__class__.NAME + ", options:" + MochiKit.Base.repr(this.options) + "]";
+ }
+};
+
+MochiKit.DragAndDrop.Draggables = {
+ /***
+
+ Manage draggables elements. Not intended to direct use.
+
+ ***/
+ drags: [],
+
+ register: function (draggable) {
+ if (this.drags.length === 0) {
+ var conn = MochiKit.Signal.connect;
+ this.eventMouseUp = conn(document, 'onmouseup', this, this.endDrag);
+ this.eventMouseMove = conn(document, 'onmousemove', this,
+ this.updateDrag);
+ this.eventKeypress = conn(document, 'onkeypress', this,
+ this.keyPress);
+ }
+ this.drags.push(draggable);
+ },
+
+ unregister: function (draggable) {
+ this.drags = MochiKit.Base.filter(function (d) {
+ return d != draggable;
+ }, this.drags);
+ if (this.drags.length === 0) {
+ var disc = MochiKit.Signal.disconnect;
+ disc(this.eventMouseUp);
+ disc(this.eventMouseMove);
+ disc(this.eventKeypress);
+ }
+ },
+
+ activate: function (draggable) {
+ // allows keypress events if window is not currently focused
+ // fails for Safari
+ window.focus();
+ this.activeDraggable = draggable;
+ },
+
+ deactivate: function () {
+ this.activeDraggable = null;
+ },
+
+ updateDrag: function (event) {
+ if (!this.activeDraggable) {
+ return;
+ }
+ var pointer = event.mouse();
+ // Mozilla-based browsers fire successive mousemove events with
+ // the same coordinates, prevent needless redrawing (moz bug?)
+ if (this._lastPointer && (MochiKit.Base.repr(this._lastPointer.page) ==
+ MochiKit.Base.repr(pointer.page))) {
+ return;
+ }
+ this._lastPointer = pointer;
+ this.activeDraggable.updateDrag(event, pointer);
+ },
+
+ endDrag: function (event) {
+ if (!this.activeDraggable) {
+ return;
+ }
+ this._lastPointer = null;
+ this.activeDraggable.endDrag(event);
+ this.activeDraggable = null;
+ },
+
+ keyPress: function (event) {
+ if (this.activeDraggable) {
+ this.activeDraggable.keyPress(event);
+ }
+ },
+
+ notify: function (eventName, draggable, event) {
+ MochiKit.Signal.signal(this, eventName, draggable, event);
+ }
+};
+
+/** @id MochiKit.DragAndDrop.Draggable */
+MochiKit.DragAndDrop.Draggable = function (element, options) {
+ var cls = arguments.callee;
+ if (!(this instanceof cls)) {
+ return new cls(element, options);
+ }
+ this.__init__(element, options);
+};
+
+MochiKit.DragAndDrop.Draggable.prototype = {
+ /***
+
+ A draggable object. Simple instantiate :
+
+ new MochiKit.DragAndDrop.Draggable('myelement');
+
+ ***/
+ __class__ : MochiKit.DragAndDrop.Draggable,
+
+ __init__: function (element, /* optional */options) {
+ var v = MochiKit.Visual;
+ var b = MochiKit.Base;
+ options = b.update({
+
+ /** @id MochiKit.DragAndDrop.handle */
+ handle: false,
+
+ /** @id MochiKit.DragAndDrop.starteffect */
+ starteffect: function (innerelement) {
+ this._savedOpacity = MochiKit.Style.getStyle(innerelement, 'opacity') || 1.0;
+ new v.Opacity(innerelement, {duration:0.2, from:this._savedOpacity, to:0.7});
+ },
+ /** @id MochiKit.DragAndDrop.reverteffect */
+ reverteffect: function (innerelement, top_offset, left_offset) {
+ var dur = Math.sqrt(Math.abs(top_offset^2) +
+ Math.abs(left_offset^2))*0.02;
+ return new v.Move(innerelement,
+ {x: -left_offset, y: -top_offset, duration: dur});
+ },
+
+ /** @id MochiKit.DragAndDrop.endeffect */
+ endeffect: function (innerelement) {
+ new v.Opacity(innerelement, {duration:0.2, from:0.7, to:this._savedOpacity});
+ },
+
+ /** @id MochiKit.DragAndDrop.onchange */
+ onchange: b.noop,
+
+ /** @id MochiKit.DragAndDrop.zindex */
+ zindex: 1000,
+
+ /** @id MochiKit.DragAndDrop.revert */
+ revert: false,
+
+ /** @id MochiKit.DragAndDrop.scroll */
+ scroll: false,
+
+ /** @id MochiKit.DragAndDrop.scrollSensitivity */
+ scrollSensitivity: 20,
+
+ /** @id MochiKit.DragAndDrop.scrollSpeed */
+ scrollSpeed: 15,
+ // false, or xy or [x, y] or function (x, y){return [x, y];}
+
+ /** @id MochiKit.DragAndDrop.snap */
+ snap: false
+ }, options);
+
+ var d = MochiKit.DOM;
+ this.element = d.getElement(element);
+
+ if (options.handle && (typeof(options.handle) == 'string')) {
+ this.handle = d.getFirstElementByTagAndClassName(null,
+ options.handle, this.element);
+ }
+ if (!this.handle) {
+ this.handle = d.getElement(options.handle);
+ }
+ if (!this.handle) {
+ this.handle = this.element;
+ }
+
+ if (options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
+ options.scroll = d.getElement(options.scroll);
+ this._isScrollChild = MochiKit.DOM.isChildNode(this.element, options.scroll);
+ }
+
+ MochiKit.Style.makePositioned(this.element); // fix IE
+
+ this.delta = this.currentDelta();
+ this.options = options;
+ this.dragging = false;
+
+ this.eventMouseDown = MochiKit.Signal.connect(this.handle,
+ 'onmousedown', this, this.initDrag);
+ MochiKit.DragAndDrop.Draggables.register(this);
+ },
+
+ /** @id MochiKit.DragAndDrop.destroy */
+ destroy: function () {
+ MochiKit.Signal.disconnect(this.eventMouseDown);
+ MochiKit.DragAndDrop.Draggables.unregister(this);
+ },
+
+ /** @id MochiKit.DragAndDrop.currentDelta */
+ currentDelta: function () {
+ var s = MochiKit.Style.getStyle;
+ return [
+ parseInt(s(this.element, 'left') || '0'),
+ parseInt(s(this.element, 'top') || '0')];
+ },
+
+ /** @id MochiKit.DragAndDrop.initDrag */
+ initDrag: function (event) {
+ if (!event.mouse().button.left) {
+ return;
+ }
+ // abort on form elements, fixes a Firefox issue
+ var src = event.target();
+ var tagName = (src.tagName || '').toUpperCase();
+ if (tagName === 'INPUT' || tagName === 'SELECT' ||
+ tagName === 'OPTION' || tagName === 'BUTTON' ||
+ tagName === 'TEXTAREA') {
+ return;
+ }
+
+ if (this._revert) {
+ this._revert.cancel();
+ this._revert = null;
+ }
+
+ var pointer = event.mouse();
+ var pos = MochiKit.Position.cumulativeOffset(this.element);
+ this.offset = [pointer.page.x - pos.x, pointer.page.y - pos.y];
+
+ MochiKit.DragAndDrop.Draggables.activate(this);
+ event.stop();
+ },
+
+ /** @id MochiKit.DragAndDrop.startDrag */
+ startDrag: function (event) {
+ this.dragging = true;
+ if (this.options.selectclass) {
+ MochiKit.DOM.addElementClass(this.element,
+ this.options.selectclass);
+ }
+ if (this.options.zindex) {
+ this.originalZ = parseInt(MochiKit.Style.getStyle(this.element,
+ 'z-index') || '0');
+ this.element.style.zIndex = this.options.zindex;
+ }
+
+ if (this.options.ghosting) {
+ this._clone = this.element.cloneNode(true);
+ this.ghostPosition = MochiKit.Position.absolutize(this.element);
+ this.element.parentNode.insertBefore(this._clone, this.element);
+ }
+
+ if (this.options.scroll) {
+ if (this.options.scroll == window) {
+ var where = this._getWindowScroll(this.options.scroll);
+ this.originalScrollLeft = where.left;
+ this.originalScrollTop = where.top;
+ } else {
+ this.originalScrollLeft = this.options.scroll.scrollLeft;
+ this.originalScrollTop = this.options.scroll.scrollTop;
+ }
+ }
+
+ MochiKit.DragAndDrop.Droppables.prepare(this.element);
+ MochiKit.DragAndDrop.Draggables.notify('start', this, event);
+ if (this.options.starteffect) {
+ this.options.starteffect(this.element);
+ }
+ },
+
+ /** @id MochiKit.DragAndDrop.updateDrag */
+ updateDrag: function (event, pointer) {
+ if (!this.dragging) {
+ this.startDrag(event);
+ }
+ MochiKit.Position.prepare();
+ MochiKit.DragAndDrop.Droppables.show(pointer, this.element);
+ MochiKit.DragAndDrop.Draggables.notify('drag', this, event);
+ this.draw(pointer);
+ this.options.onchange(this);
+
+ if (this.options.scroll) {
+ this.stopScrolling();
+ var p, q;
+ if (this.options.scroll == window) {
+ var s = this._getWindowScroll(this.options.scroll);
+ p = new MochiKit.Style.Coordinates(s.left, s.top);
+ q = new MochiKit.Style.Coordinates(s.left + s.width,
+ s.top + s.height);
+ } else {
+ p = MochiKit.Position.page(this.options.scroll);
+ p.x += this.options.scroll.scrollLeft;
+ p.y += this.options.scroll.scrollTop;
+ p.x += (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0);
+ p.y += (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0);
+ q = new MochiKit.Style.Coordinates(p.x + this.options.scroll.offsetWidth,
+ p.y + this.options.scroll.offsetHeight);
+ }
+ var speed = [0, 0];
+ if (pointer.page.x > (q.x - this.options.scrollSensitivity)) {
+ speed[0] = pointer.page.x - (q.x - this.options.scrollSensitivity);
+ } else if (pointer.page.x < (p.x + this.options.scrollSensitivity)) {
+ speed[0] = pointer.page.x - (p.x + this.options.scrollSensitivity);
+ }
+ if (pointer.page.y > (q.y - this.options.scrollSensitivity)) {
+ speed[1] = pointer.page.y - (q.y - this.options.scrollSensitivity);
+ } else if (pointer.page.y < (p.y + this.options.scrollSensitivity)) {
+ speed[1] = pointer.page.y - (p.y + this.options.scrollSensitivity);
+ }
+ this.startScrolling(speed);
+ }
+
+ // fix AppleWebKit rendering
+ if (/AppleWebKit/.test(navigator.appVersion)) {
+ window.scrollBy(0, 0);
+ }
+ event.stop();
+ },
+
+ /** @id MochiKit.DragAndDrop.finishDrag */
+ finishDrag: function (event, success) {
+ var dr = MochiKit.DragAndDrop;
+ this.dragging = false;
+ if (this.options.selectclass) {
+ MochiKit.DOM.removeElementClass(this.element,
+ this.options.selectclass);
+ }
+
+ if (this.options.ghosting) {
+ // XXX: from a user point of view, it would be better to remove
+ // the node only *after* the MochiKit.Visual.Move end when used
+ // with revert.
+ MochiKit.Position.relativize(this.element, this.ghostPosition);
+ MochiKit.DOM.removeElement(this._clone);
+ this._clone = null;
+ }
+
+ if (success) {
+ dr.Droppables.fire(event, this.element);
+ }
+ dr.Draggables.notify('end', this, event);
+
+ var revert = this.options.revert;
+ if (revert && typeof(revert) == 'function') {
+ revert = revert(this.element);
+ }
+
+ var d = this.currentDelta();
+ if (revert && this.options.reverteffect) {
+ this._revert = this.options.reverteffect(this.element,
+ d[1] - this.delta[1], d[0] - this.delta[0]);
+ } else {
+ this.delta = d;
+ }
+
+ if (this.options.zindex) {
+ this.element.style.zIndex = this.originalZ;
+ }
+
+ if (this.options.endeffect) {
+ this.options.endeffect(this.element);
+ }
+
+ dr.Draggables.deactivate();
+ dr.Droppables.reset(this.element);
+ },
+
+ /** @id MochiKit.DragAndDrop.keyPress */
+ keyPress: function (event) {
+ if (event.key().string != "KEY_ESCAPE") {
+ return;
+ }
+ this.finishDrag(event, false);
+ event.stop();
+ },
+
+ /** @id MochiKit.DragAndDrop.endDrag */
+ endDrag: function (event) {
+ if (!this.dragging) {
+ return;
+ }
+ this.stopScrolling();
+ this.finishDrag(event, true);
+ event.stop();
+ },
+
+ /** @id MochiKit.DragAndDrop.draw */
+ draw: function (point) {
+ var pos = MochiKit.Position.cumulativeOffset(this.element);
+ var d = this.currentDelta();
+ pos.x -= d[0];
+ pos.y -= d[1];
+
+ if (this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
+ pos.x -= this.options.scroll.scrollLeft - this.originalScrollLeft;
+ pos.y -= this.options.scroll.scrollTop - this.originalScrollTop;
+ }
+
+ var p = [point.page.x - pos.x - this.offset[0],
+ point.page.y - pos.y - this.offset[1]];
+
+ if (this.options.snap) {
+ if (typeof(this.options.snap) == 'function') {
+ p = this.options.snap(p[0], p[1]);
+ } else {
+ if (this.options.snap instanceof Array) {
+ var i = -1;
+ p = MochiKit.Base.map(MochiKit.Base.bind(function (v) {
+ i += 1;
+ return Math.round(v/this.options.snap[i]) *
+ this.options.snap[i];
+ }, this), p);
+ } else {
+ p = MochiKit.Base.map(MochiKit.Base.bind(function (v) {
+ return Math.round(v/this.options.snap) *
+ this.options.snap;
+ }, this), p);
+ }
+ }
+ }
+ var style = this.element.style;
+ if ((!this.options.constraint) ||
+ (this.options.constraint == 'horizontal')) {
+ style.left = p[0] + 'px';
+ }
+ if ((!this.options.constraint) ||
+ (this.options.constraint == 'vertical')) {
+ style.top = p[1] + 'px';
+ }
+ if (style.visibility == 'hidden') {
+ style.visibility = ''; // fix gecko rendering
+ }
+ },
+
+ /** @id MochiKit.DragAndDrop.stopScrolling */
+ stopScrolling: function () {
+ if (this.scrollInterval) {
+ clearInterval(this.scrollInterval);
+ this.scrollInterval = null;
+ MochiKit.DragAndDrop.Draggables._lastScrollPointer = null;
+ }
+ },
+
+ /** @id MochiKit.DragAndDrop.startScrolling */
+ startScrolling: function (speed) {
+ if (!speed[0] && !speed[1]) {
+ return;
+ }
+ this.scrollSpeed = [speed[0] * this.options.scrollSpeed,
+ speed[1] * this.options.scrollSpeed];
+ this.lastScrolled = new Date();
+ this.scrollInterval = setInterval(MochiKit.Base.bind(this.scroll, this), 10);
+ },
+
+ /** @id MochiKit.DragAndDrop.scroll */
+ scroll: function () {
+ var current = new Date();
+ var delta = current - this.lastScrolled;
+ this.lastScrolled = current;
+
+ if (this.options.scroll == window) {
+ var s = this._getWindowScroll(this.options.scroll);
+ if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
+ var dm = delta / 1000;
+ this.options.scroll.scrollTo(s.left + dm * this.scrollSpeed[0],
+ s.top + dm * this.scrollSpeed[1]);
+ }
+ } else {
+ this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
+ this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
+ }
+
+ var d = MochiKit.DragAndDrop;
+
+ MochiKit.Position.prepare();
+ d.Droppables.show(d.Draggables._lastPointer, this.element);
+ d.Draggables.notify('drag', this);
+ if (this._isScrollChild) {
+ d.Draggables._lastScrollPointer = d.Draggables._lastScrollPointer || d.Draggables._lastPointer;
+ d.Draggables._lastScrollPointer.x += this.scrollSpeed[0] * delta / 1000;
+ d.Draggables._lastScrollPointer.y += this.scrollSpeed[1] * delta / 1000;
+ if (d.Draggables._lastScrollPointer.x < 0) {
+ d.Draggables._lastScrollPointer.x = 0;
+ }
+ if (d.Draggables._lastScrollPointer.y < 0) {
+ d.Draggables._lastScrollPointer.y = 0;
+ }
+ this.draw(d.Draggables._lastScrollPointer);
+ }
+
+ this.options.onchange(this);
+ },
+
+ _getWindowScroll: function (win) {
+ var vp, w, h;
+ MochiKit.DOM.withWindow(win, function () {
+ vp = MochiKit.Style.getViewportPosition(win.document);
+ });
+ if (win.innerWidth) {
+ w = win.innerWidth;
+ h = win.innerHeight;
+ } else if (win.document.documentElement && win.document.documentElement.clientWidth) {
+ w = win.document.documentElement.clientWidth;
+ h = win.document.documentElement.clientHeight;
+ } else {
+ w = win.document.body.offsetWidth;
+ h = win.document.body.offsetHeight;
+ }
+ return {top: vp.y, left: vp.x, width: w, height: h};
+ },
+
+ /** @id MochiKit.DragAndDrop.repr */
+ repr: function () {
+ return '[' + this.__class__.NAME + ", options:" + MochiKit.Base.repr(this.options) + "]";
+ }
+};
+
+MochiKit.DragAndDrop.__new__ = function () {
+ MochiKit.Base.nameFunctions(this);
+};
+
+MochiKit.DragAndDrop.__new__();
+
+MochiKit.Base._exportSymbols(this, MochiKit.DragAndDrop);
diff --git a/frontend/gamma/js/MochiKit/Format.js b/frontend/gamma/js/MochiKit/Format.js
new file mode 100644
index 0000000..122845e
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Format.js
@@ -0,0 +1,309 @@
+/***
+
+MochiKit.Format 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('Format', '1.5', ['Base']);
+
+MochiKit.Format._numberFormatter = function (placeholder, header, footer, locale, isPercent, precision, leadingZeros, separatorAt, trailingZeros) {
+ return function (num) {
+ num = parseFloat(num);
+ if (typeof(num) == "undefined" || num === null || isNaN(num)) {
+ return placeholder;
+ }
+ var curheader = header;
+ var curfooter = footer;
+ if (num < 0) {
+ num = -num;
+ } else {
+ curheader = curheader.replace(/-/, "");
+ }
+ var me = arguments.callee;
+ var fmt = MochiKit.Format.formatLocale(locale);
+ if (isPercent) {
+ num = num * 100.0;
+ curfooter = fmt.percent + curfooter;
+ }
+ num = MochiKit.Format.roundToFixed(num, precision);
+ var parts = num.split(/\./);
+ var whole = parts[0];
+ var frac = (parts.length == 1) ? "" : parts[1];
+ var res = "";
+ while (whole.length < leadingZeros) {
+ whole = "0" + whole;
+ }
+ if (separatorAt) {
+ while (whole.length > separatorAt) {
+ var i = whole.length - separatorAt;
+ //res = res + fmt.separator + whole.substring(i, whole.length);
+ res = fmt.separator + whole.substring(i, whole.length) + res;
+ whole = whole.substring(0, i);
+ }
+ }
+ res = whole + res;
+ if (precision > 0) {
+ while (frac.length < trailingZeros) {
+ frac = frac + "0";
+ }
+ res = res + fmt.decimal + frac;
+ }
+ return curheader + res + curfooter;
+ };
+};
+
+/** @id MochiKit.Format.numberFormatter */
+MochiKit.Format.numberFormatter = function (pattern, placeholder/* = "" */, locale/* = "default" */) {
+ // http://java.sun.com/docs/books/tutorial/i18n/format/numberpattern.html
+ // | 0 | leading or trailing zeros
+ // | # | just the number
+ // | , | separator
+ // | . | decimal separator
+ // | % | Multiply by 100 and format as percent
+ if (typeof(placeholder) == "undefined") {
+ placeholder = "";
+ }
+ var match = pattern.match(/((?:[0#]+,)?[0#]+)(?:\.([0#]+))?(%)?/);
+ if (!match) {
+ throw TypeError("Invalid pattern");
+ }
+ var header = pattern.substr(0, match.index);
+ var footer = pattern.substr(match.index + match[0].length);
+ if (header.search(/-/) == -1) {
+ header = header + "-";
+ }
+ var whole = match[1];
+ var frac = (typeof(match[2]) == "string" && match[2] != "") ? match[2] : "";
+ var isPercent = (typeof(match[3]) == "string" && match[3] != "");
+ var tmp = whole.split(/,/);
+ var separatorAt;
+ if (typeof(locale) == "undefined") {
+ locale = "default";
+ }
+ if (tmp.length == 1) {
+ separatorAt = null;
+ } else {
+ separatorAt = tmp[1].length;
+ }
+ var leadingZeros = whole.length - whole.replace(/0/g, "").length;
+ var trailingZeros = frac.length - frac.replace(/0/g, "").length;
+ var precision = frac.length;
+ var rval = MochiKit.Format._numberFormatter(
+ placeholder, header, footer, locale, isPercent, precision,
+ leadingZeros, separatorAt, trailingZeros
+ );
+ var m = MochiKit.Base;
+ if (m) {
+ var fn = arguments.callee;
+ var args = m.concat(arguments);
+ rval.repr = function () {
+ return [
+ self.NAME,
+ "(",
+ map(m.repr, args).join(", "),
+ ")"
+ ].join("");
+ };
+ }
+ return rval;
+};
+
+/** @id MochiKit.Format.formatLocale */
+MochiKit.Format.formatLocale = function (locale) {
+ if (typeof(locale) == "undefined" || locale === null) {
+ locale = "default";
+ }
+ if (typeof(locale) == "string") {
+ var rval = MochiKit.Format.LOCALE[locale];
+ if (typeof(rval) == "string") {
+ rval = arguments.callee(rval);
+ MochiKit.Format.LOCALE[locale] = rval;
+ }
+ return rval;
+ } else {
+ return locale;
+ }
+};
+
+/** @id MochiKit.Format.twoDigitAverage */
+MochiKit.Format.twoDigitAverage = function (numerator, denominator) {
+ if (denominator) {
+ var res = numerator / denominator;
+ if (!isNaN(res)) {
+ return MochiKit.Format.twoDigitFloat(res);
+ }
+ }
+ return "0";
+};
+
+/** @id MochiKit.Format.twoDigitFloat */
+MochiKit.Format.twoDigitFloat = function (aNumber) {
+ var res = roundToFixed(aNumber, 2);
+ if (res.indexOf(".00") > 0) {
+ return res.substring(0, res.length - 3);
+ } else if (res.charAt(res.length - 1) == "0") {
+ return res.substring(0, res.length - 1);
+ } else {
+ return res;
+ }
+};
+
+/** @id MochiKit.Format.lstrip */
+MochiKit.Format.lstrip = function (str, /* optional */chars) {
+ str = str + "";
+ if (typeof(str) != "string") {
+ return null;
+ }
+ if (!chars) {
+ return str.replace(/^\s+/, "");
+ } else {
+ return str.replace(new RegExp("^[" + chars + "]+"), "");
+ }
+};
+
+/** @id MochiKit.Format.rstrip */
+MochiKit.Format.rstrip = function (str, /* optional */chars) {
+ str = str + "";
+ if (typeof(str) != "string") {
+ return null;
+ }
+ if (!chars) {
+ return str.replace(/\s+$/, "");
+ } else {
+ return str.replace(new RegExp("[" + chars + "]+$"), "");
+ }
+};
+
+/** @id MochiKit.Format.strip */
+MochiKit.Format.strip = function (str, /* optional */chars) {
+ var self = MochiKit.Format;
+ return self.rstrip(self.lstrip(str, chars), chars);
+};
+
+/** @id MochiKit.Format.truncToFixed */
+MochiKit.Format.truncToFixed = function (aNumber, precision) {
+ var fixed = MochiKit.Format._numberToFixed(aNumber, precision);
+ var fracPos = fixed.indexOf(".");
+ if (fracPos > 0 && fracPos + precision + 1 < fixed.length) {
+ fixed = fixed.substring(0, fracPos + precision + 1);
+ fixed = MochiKit.Format._shiftNumber(fixed, 0);
+ }
+ return fixed;
+}
+
+/** @id MochiKit.Format.roundToFixed */
+MochiKit.Format.roundToFixed = function (aNumber, precision) {
+ var fixed = MochiKit.Format._numberToFixed(aNumber, precision);
+ var fracPos = fixed.indexOf(".");
+ if (fracPos > 0 && fracPos + precision + 1 < fixed.length) {
+ var str = MochiKit.Format._shiftNumber(fixed, precision);
+ str = MochiKit.Format._numberToFixed(Math.round(parseFloat(str)), 0);
+ fixed = MochiKit.Format._shiftNumber(str, -precision);
+ }
+ return fixed;
+}
+
+/**
+ * Converts a number to a fixed format string. This function handles
+ * conversion of exponents by shifting the decimal point to the left
+ * or the right. It also guarantees a specified minimum number of
+ * fractional digits (but no maximum).
+ *
+ * @param {Number} aNumber the number to convert
+ * @param {Number} precision the minimum number of decimal digits
+ *
+ * @return {String} the fixed format number string
+ */
+MochiKit.Format._numberToFixed = function (aNumber, precision) {
+ var str = aNumber.toString();
+ var parts = str.split(/[eE]/);
+ var exp = (parts.length === 1) ? 0 : parseInt(parts[1]) || 0;
+ var fixed = MochiKit.Format._shiftNumber(parts[0], exp);
+ parts = fixed.split(/\./);
+ var whole = parts[0];
+ var frac = (parts.length === 1) ? "" : parts[1];
+ while (frac.length < precision) {
+ frac += "0";
+ }
+ if (frac.length > 0) {
+ return whole + "." + frac;
+ } else {
+ return whole;
+ }
+}
+
+/**
+ * Shifts the decimal dot location in a fixed format number string.
+ * This function handles negative values and will add and remove
+ * leading and trailing zeros as needed.
+ *
+ * @param {String} num the fixed format number string
+ * @param {Number} exp the base-10 exponent to apply
+ *
+ * @return {String} the new fixed format number string
+ */
+MochiKit.Format._shiftNumber = function (num, exp) {
+ var pos = num.indexOf(".");
+ if (pos < 0) {
+ pos = num.length;
+ } else {
+ num = num.substring(0, pos) + num.substring(pos + 1);
+ }
+ pos += exp;
+ while (pos <= 0 || (pos <= 1 && num.charAt(0) === "-")) {
+ if (num.charAt(0) === "-") {
+ num = "-0" + num.substring(1);
+ } else {
+ num = "0" + num;
+ }
+ pos++;
+ }
+ while (pos > num.length) {
+ num += "0";
+ }
+ if (pos < num.length) {
+ num = num.substring(0, pos) + "." + num.substring(pos);
+ }
+ while (/^0[^.]/.test(num)) {
+ num = num.substring(1);
+ }
+ while (/^-0[^.]/.test(num)) {
+ num = "-" + num.substring(2);
+ }
+ return num;
+}
+
+/** @id MochiKit.Format.percentFormat */
+MochiKit.Format.percentFormat = function (aNumber) {
+ return MochiKit.Format.twoDigitFloat(100 * aNumber) + '%';
+};
+
+MochiKit.Format.LOCALE = {
+ en_US: {separator: ",", decimal: ".", percent: "%"},
+ de_DE: {separator: ".", decimal: ",", percent: "%"},
+ pt_BR: {separator: ".", decimal: ",", percent: "%"},
+ fr_FR: {separator: " ", decimal: ",", percent: "%"},
+ "default": "en_US",
+ __export__: false
+};
+
+MochiKit.Format.__new__ = function () {
+ MochiKit.Base.nameFunctions(this);
+ var base = this.NAME + ".";
+ var k, v, o;
+ for (k in this.LOCALE) {
+ o = this.LOCALE[k];
+ if (typeof(o) == "object") {
+ o.repr = function () { return this.NAME; };
+ o.NAME = base + "LOCALE." + k;
+ }
+ }
+};
+
+MochiKit.Format.__new__();
+
+MochiKit.Base._exportSymbols(this, MochiKit.Format);
diff --git a/frontend/gamma/js/MochiKit/Iter.js b/frontend/gamma/js/MochiKit/Iter.js
new file mode 100644
index 0000000..524b2bc
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Iter.js
@@ -0,0 +1,790 @@
+/***
+
+MochiKit.Iter 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('Iter', '1.5', ['Base']);
+
+MochiKit.Base.update(MochiKit.Iter, {
+ /** @id MochiKit.Iter.registerIteratorFactory */
+ registerIteratorFactory: function (name, check, iterfactory, /* optional */ override) {
+ MochiKit.Iter.iteratorRegistry.register(name, check, iterfactory, override);
+ },
+
+ /** @id MochiKit.Iter.isIterable */
+ isIterable: function(o) {
+ return o != null &&
+ (typeof(o.next) == "function" || typeof(o.iter) == "function");
+ },
+
+ /** @id MochiKit.Iter.iter */
+ iter: function (iterable, /* optional */ sentinel) {
+ var self = MochiKit.Iter;
+ if (arguments.length == 2) {
+ return self.takewhile(
+ function (a) { return a != sentinel; },
+ iterable
+ );
+ }
+ if (typeof(iterable.next) == 'function') {
+ return iterable;
+ } else if (typeof(iterable.iter) == 'function') {
+ return iterable.iter();
+ /*
+ } else if (typeof(iterable.__iterator__) == 'function') {
+ //
+ // XXX: We can't support JavaScript 1.7 __iterator__ directly
+ // because of Object.prototype.__iterator__
+ //
+ return iterable.__iterator__();
+ */
+ }
+
+ try {
+ return self.iteratorRegistry.match(iterable);
+ } catch (e) {
+ var m = MochiKit.Base;
+ if (e == m.NotFound) {
+ e = new TypeError(typeof(iterable) + ": " + m.repr(iterable) + " is not iterable");
+ }
+ throw e;
+ }
+ },
+
+ /** @id MochiKit.Iter.count */
+ count: function (n) {
+ if (!n) {
+ n = 0;
+ }
+ var m = MochiKit.Base;
+ return {
+ repr: function () { return "count(" + n + ")"; },
+ toString: m.forwardCall("repr"),
+ next: m.counter(n)
+ };
+ },
+
+ /** @id MochiKit.Iter.cycle */
+ cycle: function (p) {
+ var self = MochiKit.Iter;
+ var m = MochiKit.Base;
+ var lst = [];
+ var iterator = self.iter(p);
+ return {
+ repr: function () { return "cycle(...)"; },
+ toString: m.forwardCall("repr"),
+ next: function () {
+ try {
+ var rval = iterator.next();
+ lst.push(rval);
+ return rval;
+ } catch (e) {
+ if (e != self.StopIteration) {
+ throw e;
+ }
+ if (lst.length === 0) {
+ this.next = function () {
+ throw self.StopIteration;
+ };
+ } else {
+ var i = -1;
+ this.next = function () {
+ i = (i + 1) % lst.length;
+ return lst[i];
+ };
+ }
+ return this.next();
+ }
+ }
+ };
+ },
+
+ /** @id MochiKit.Iter.repeat */
+ repeat: function (elem, /* optional */n) {
+ var m = MochiKit.Base;
+ if (typeof(n) == 'undefined') {
+ return {
+ repr: function () {
+ return "repeat(" + m.repr(elem) + ")";
+ },
+ toString: m.forwardCall("repr"),
+ next: function () {
+ return elem;
+ }
+ };
+ }
+ return {
+ repr: function () {
+ return "repeat(" + m.repr(elem) + ", " + n + ")";
+ },
+ toString: m.forwardCall("repr"),
+ next: function () {
+ if (n <= 0) {
+ throw MochiKit.Iter.StopIteration;
+ }
+ n -= 1;
+ return elem;
+ }
+ };
+ },
+
+ /** @id MochiKit.Iter.next */
+ next: function (iterator) {
+ return iterator.next();
+ },
+
+ /** @id MochiKit.Iter.izip */
+ izip: function (p, q/*, ...*/) {
+ var m = MochiKit.Base;
+ var self = MochiKit.Iter;
+ var next = self.next;
+ var iterables = m.map(self.iter, arguments);
+ return {
+ repr: function () { return "izip(...)"; },
+ toString: m.forwardCall("repr"),
+ next: function () { return m.map(next, iterables); }
+ };
+ },
+
+ /** @id MochiKit.Iter.ifilter */
+ ifilter: function (pred, seq) {
+ var m = MochiKit.Base;
+ seq = MochiKit.Iter.iter(seq);
+ if (pred === null) {
+ pred = m.operator.truth;
+ }
+ return {
+ repr: function () { return "ifilter(...)"; },
+ toString: m.forwardCall("repr"),
+ next: function () {
+ while (true) {
+ var rval = seq.next();
+ if (pred(rval)) {
+ return rval;
+ }
+ }
+ // mozilla warnings aren't too bright
+ return undefined;
+ }
+ };
+ },
+
+ /** @id MochiKit.Iter.ifilterfalse */
+ ifilterfalse: function (pred, seq) {
+ var m = MochiKit.Base;
+ seq = MochiKit.Iter.iter(seq);
+ if (pred === null) {
+ pred = m.operator.truth;
+ }
+ return {
+ repr: function () { return "ifilterfalse(...)"; },
+ toString: m.forwardCall("repr"),
+ next: function () {
+ while (true) {
+ var rval = seq.next();
+ if (!pred(rval)) {
+ return rval;
+ }
+ }
+ // mozilla warnings aren't too bright
+ return undefined;
+ }
+ };
+ },
+
+ /** @id MochiKit.Iter.islice */
+ islice: function (seq/*, [start,] stop[, step] */) {
+ var self = MochiKit.Iter;
+ var m = MochiKit.Base;
+ seq = self.iter(seq);
+ var start = 0;
+ var stop = 0;
+ var step = 1;
+ var i = -1;
+ if (arguments.length == 2) {
+ stop = arguments[1];
+ } else if (arguments.length == 3) {
+ start = arguments[1];
+ stop = arguments[2];
+ } else {
+ start = arguments[1];
+ stop = arguments[2];
+ step = arguments[3];
+ }
+ return {
+ repr: function () {
+ return "islice(" + ["...", start, stop, step].join(", ") + ")";
+ },
+ toString: m.forwardCall("repr"),
+ next: function () {
+ var rval;
+ while (i < start) {
+ rval = seq.next();
+ i++;
+ }
+ if (start >= stop) {
+ throw self.StopIteration;
+ }
+ start += step;
+ return rval;
+ }
+ };
+ },
+
+ /** @id MochiKit.Iter.imap */
+ imap: function (fun, p, q/*, ...*/) {
+ var m = MochiKit.Base;
+ var self = MochiKit.Iter;
+ var iterables = m.map(self.iter, m.extend(null, arguments, 1));
+ var map = m.map;
+ var next = self.next;
+ return {
+ repr: function () { return "imap(...)"; },
+ toString: m.forwardCall("repr"),
+ next: function () {
+ return fun.apply(this, map(next, iterables));
+ }
+ };
+ },
+
+ /** @id MochiKit.Iter.applymap */
+ applymap: function (fun, seq, self) {
+ seq = MochiKit.Iter.iter(seq);
+ var m = MochiKit.Base;
+ return {
+ repr: function () { return "applymap(...)"; },
+ toString: m.forwardCall("repr"),
+ next: function () {
+ return fun.apply(self, seq.next());
+ }
+ };
+ },
+
+ /** @id MochiKit.Iter.chain */
+ chain: function (p, q/*, ...*/) {
+ // dumb fast path
+ var self = MochiKit.Iter;
+ var m = MochiKit.Base;
+ if (arguments.length == 1) {
+ return self.iter(arguments[0]);
+ }
+ var argiter = m.map(self.iter, arguments);
+ return {
+ repr: function () { return "chain(...)"; },
+ toString: m.forwardCall("repr"),
+ next: function () {
+ while (argiter.length > 1) {
+ try {
+ var result = argiter[0].next();
+ return result;
+ } catch (e) {
+ if (e != self.StopIteration) {
+ throw e;
+ }
+ argiter.shift();
+ var result = argiter[0].next();
+ return result;
+ }
+ }
+ if (argiter.length == 1) {
+ // optimize last element
+ var arg = argiter.shift();
+ this.next = m.bind("next", arg);
+ return this.next();
+ }
+ throw self.StopIteration;
+ }
+ };
+ },
+
+ /** @id MochiKit.Iter.takewhile */
+ takewhile: function (pred, seq) {
+ var self = MochiKit.Iter;
+ seq = self.iter(seq);
+ return {
+ repr: function () { return "takewhile(...)"; },
+ toString: MochiKit.Base.forwardCall("repr"),
+ next: function () {
+ var rval = seq.next();
+ if (!pred(rval)) {
+ this.next = function () {
+ throw self.StopIteration;
+ };
+ this.next();
+ }
+ return rval;
+ }
+ };
+ },
+
+ /** @id MochiKit.Iter.dropwhile */
+ dropwhile: function (pred, seq) {
+ seq = MochiKit.Iter.iter(seq);
+ var m = MochiKit.Base;
+ var bind = m.bind;
+ return {
+ "repr": function () { return "dropwhile(...)"; },
+ "toString": m.forwardCall("repr"),
+ "next": function () {
+ while (true) {
+ var rval = seq.next();
+ if (!pred(rval)) {
+ break;
+ }
+ }
+ this.next = bind("next", seq);
+ return rval;
+ }
+ };
+ },
+
+ _tee: function (ident, sync, iterable) {
+ sync.pos[ident] = -1;
+ var m = MochiKit.Base;
+ var listMin = m.listMin;
+ return {
+ repr: function () { return "tee(" + ident + ", ...)"; },
+ toString: m.forwardCall("repr"),
+ next: function () {
+ var rval;
+ var i = sync.pos[ident];
+
+ if (i == sync.max) {
+ rval = iterable.next();
+ sync.deque.push(rval);
+ sync.max += 1;
+ sync.pos[ident] += 1;
+ } else {
+ rval = sync.deque[i - sync.min];
+ sync.pos[ident] += 1;
+ if (i == sync.min && listMin(sync.pos) != sync.min) {
+ sync.min += 1;
+ sync.deque.shift();
+ }
+ }
+ return rval;
+ }
+ };
+ },
+
+ /** @id MochiKit.Iter.tee */
+ tee: function (iterable, n/* = 2 */) {
+ var rval = [];
+ var sync = {
+ "pos": [],
+ "deque": [],
+ "max": -1,
+ "min": -1
+ };
+ if (arguments.length == 1 || typeof(n) == "undefined" || n === null) {
+ n = 2;
+ }
+ var self = MochiKit.Iter;
+ iterable = self.iter(iterable);
+ var _tee = self._tee;
+ for (var i = 0; i < n; i++) {
+ rval.push(_tee(i, sync, iterable));
+ }
+ return rval;
+ },
+
+ /** @id MochiKit.Iter.list */
+ list: function (iterable) {
+ // Fast-path for Array and Array-like
+ var rval;
+ if (iterable instanceof Array) {
+ return iterable.slice();
+ }
+ // this is necessary to avoid a Safari crash
+ if (typeof(iterable) == "function" &&
+ !(iterable instanceof Function) &&
+ typeof(iterable.length) == 'number') {
+ rval = [];
+ for (var i = 0; i < iterable.length; i++) {
+ rval.push(iterable[i]);
+ }
+ return rval;
+ }
+
+ var self = MochiKit.Iter;
+ iterable = self.iter(iterable);
+ var rval = [];
+ var a_val;
+ try {
+ while (true) {
+ a_val = iterable.next();
+ rval.push(a_val);
+ }
+ } catch (e) {
+ if (e != self.StopIteration) {
+ throw e;
+ }
+ return rval;
+ }
+ // mozilla warnings aren't too bright
+ return undefined;
+ },
+
+
+ /** @id MochiKit.Iter.reduce */
+ reduce: function (fn, iterable, /* optional */initial) {
+ var i = 0;
+ var x = initial;
+ var self = MochiKit.Iter;
+ iterable = self.iter(iterable);
+ if (arguments.length < 3) {
+ try {
+ x = iterable.next();
+ } catch (e) {
+ if (e == self.StopIteration) {
+ e = new TypeError("reduce() of empty sequence with no initial value");
+ }
+ throw e;
+ }
+ i++;
+ }
+ try {
+ while (true) {
+ x = fn(x, iterable.next());
+ }
+ } catch (e) {
+ if (e != self.StopIteration) {
+ throw e;
+ }
+ }
+ return x;
+ },
+
+ /** @id MochiKit.Iter.range */
+ range: function (/* [start,] stop[, step] */) {
+ var start = 0;
+ var stop = 0;
+ var step = 1;
+ if (arguments.length == 1) {
+ stop = arguments[0];
+ } else if (arguments.length == 2) {
+ start = arguments[0];
+ stop = arguments[1];
+ } else if (arguments.length == 3) {
+ start = arguments[0];
+ stop = arguments[1];
+ step = arguments[2];
+ } else {
+ throw new TypeError("range() takes 1, 2, or 3 arguments!");
+ }
+ if (step === 0) {
+ throw new TypeError("range() step must not be 0");
+ }
+ return {
+ next: function () {
+ if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
+ throw MochiKit.Iter.StopIteration;
+ }
+ var rval = start;
+ start += step;
+ return rval;
+ },
+ repr: function () {
+ return "range(" + [start, stop, step].join(", ") + ")";
+ },
+ toString: MochiKit.Base.forwardCall("repr")
+ };
+ },
+
+ /** @id MochiKit.Iter.sum */
+ sum: function (iterable, start/* = 0 */) {
+ if (typeof(start) == "undefined" || start === null) {
+ start = 0;
+ }
+ var x = start;
+ var self = MochiKit.Iter;
+ iterable = self.iter(iterable);
+ try {
+ while (true) {
+ x += iterable.next();
+ }
+ } catch (e) {
+ if (e != self.StopIteration) {
+ throw e;
+ }
+ }
+ return x;
+ },
+
+ /** @id MochiKit.Iter.exhaust */
+ exhaust: function (iterable) {
+ var self = MochiKit.Iter;
+ iterable = self.iter(iterable);
+ try {
+ while (true) {
+ iterable.next();
+ }
+ } catch (e) {
+ if (e != self.StopIteration) {
+ throw e;
+ }
+ }
+ },
+
+ /** @id MochiKit.Iter.forEach */
+ forEach: function (iterable, func, /* optional */obj) {
+ var m = MochiKit.Base;
+ var self = MochiKit.Iter;
+ if (arguments.length > 2) {
+ func = m.bind(func, obj);
+ }
+ // fast path for array
+ if (m.isArrayLike(iterable) && !self.isIterable(iterable)) {
+ try {
+ for (var i = 0; i < iterable.length; i++) {
+ func(iterable[i]);
+ }
+ } catch (e) {
+ if (e != self.StopIteration) {
+ throw e;
+ }
+ }
+ } else {
+ self.exhaust(self.imap(func, iterable));
+ }
+ },
+
+ /** @id MochiKit.Iter.every */
+ every: function (iterable, func) {
+ var self = MochiKit.Iter;
+ try {
+ self.ifilterfalse(func, iterable).next();
+ return false;
+ } catch (e) {
+ if (e != self.StopIteration) {
+ throw e;
+ }
+ return true;
+ }
+ },
+
+ /** @id MochiKit.Iter.sorted */
+ sorted: function (iterable, /* optional */cmp) {
+ var rval = MochiKit.Iter.list(iterable);
+ if (arguments.length == 1) {
+ cmp = MochiKit.Base.compare;
+ }
+ rval.sort(cmp);
+ return rval;
+ },
+
+ /** @id MochiKit.Iter.reversed */
+ reversed: function (iterable) {
+ var rval = MochiKit.Iter.list(iterable);
+ rval.reverse();
+ return rval;
+ },
+
+ /** @id MochiKit.Iter.some */
+ some: function (iterable, func) {
+ var self = MochiKit.Iter;
+ try {
+ self.ifilter(func, iterable).next();
+ return true;
+ } catch (e) {
+ if (e != self.StopIteration) {
+ throw e;
+ }
+ return false;
+ }
+ },
+
+ /** @id MochiKit.Iter.iextend */
+ iextend: function (lst, iterable) {
+ var m = MochiKit.Base;
+ var self = MochiKit.Iter;
+ if (m.isArrayLike(iterable) && !self.isIterable(iterable)) {
+ // fast-path for array-like
+ for (var i = 0; i < iterable.length; i++) {
+ lst.push(iterable[i]);
+ }
+ } else {
+ iterable = self.iter(iterable);
+ try {
+ while (true) {
+ lst.push(iterable.next());
+ }
+ } catch (e) {
+ if (e != self.StopIteration) {
+ throw e;
+ }
+ }
+ }
+ return lst;
+ },
+
+ /** @id MochiKit.Iter.groupby */
+ groupby: function(iterable, /* optional */ keyfunc) {
+ var m = MochiKit.Base;
+ var self = MochiKit.Iter;
+ if (arguments.length < 2) {
+ keyfunc = m.operator.identity;
+ }
+ iterable = self.iter(iterable);
+
+ // shared
+ var pk = undefined;
+ var k = undefined;
+ var v;
+
+ function fetch() {
+ v = iterable.next();
+ k = keyfunc(v);
+ };
+
+ function eat() {
+ var ret = v;
+ v = undefined;
+ return ret;
+ };
+
+ var first = true;
+ var compare = m.compare;
+ return {
+ repr: function () { return "groupby(...)"; },
+ next: function() {
+ // iterator-next
+
+ // iterate until meet next group
+ while (compare(k, pk) === 0) {
+ fetch();
+ if (first) {
+ first = false;
+ break;
+ }
+ }
+ pk = k;
+ return [k, {
+ next: function() {
+ // subiterator-next
+ if (v == undefined) { // Is there something to eat?
+ fetch();
+ }
+ if (compare(k, pk) !== 0) {
+ throw self.StopIteration;
+ }
+ return eat();
+ }
+ }];
+ }
+ };
+ },
+
+ /** @id MochiKit.Iter.groupby_as_array */
+ groupby_as_array: function (iterable, /* optional */ keyfunc) {
+ var m = MochiKit.Base;
+ var self = MochiKit.Iter;
+ if (arguments.length < 2) {
+ keyfunc = m.operator.identity;
+ }
+
+ iterable = self.iter(iterable);
+ var result = [];
+ var first = true;
+ var prev_key;
+ var compare = m.compare;
+ while (true) {
+ try {
+ var value = iterable.next();
+ var key = keyfunc(value);
+ } catch (e) {
+ if (e == self.StopIteration) {
+ break;
+ }
+ throw e;
+ }
+ if (first || compare(key, prev_key) !== 0) {
+ var values = [];
+ result.push([key, values]);
+ }
+ values.push(value);
+ first = false;
+ prev_key = key;
+ }
+ return result;
+ },
+
+ /** @id MochiKit.Iter.arrayLikeIter */
+ arrayLikeIter: function (iterable) {
+ var i = 0;
+ return {
+ repr: function () { return "arrayLikeIter(...)"; },
+ toString: MochiKit.Base.forwardCall("repr"),
+ next: function () {
+ if (i >= iterable.length) {
+ throw MochiKit.Iter.StopIteration;
+ }
+ return iterable[i++];
+ }
+ };
+ },
+
+ /** @id MochiKit.Iter.hasIterateNext */
+ hasIterateNext: function (iterable) {
+ return (iterable && typeof(iterable.iterateNext) == "function");
+ },
+
+ /** @id MochiKit.Iter.iterateNextIter */
+ iterateNextIter: function (iterable) {
+ return {
+ repr: function () { return "iterateNextIter(...)"; },
+ toString: MochiKit.Base.forwardCall("repr"),
+ next: function () {
+ var rval = iterable.iterateNext();
+ if (rval === null || rval === undefined) {
+ throw MochiKit.Iter.StopIteration;
+ }
+ return rval;
+ }
+ };
+ }
+});
+
+
+MochiKit.Iter.__new__ = function () {
+ var m = MochiKit.Base;
+ // Re-use StopIteration if exists (e.g. SpiderMonkey)
+ if (typeof(StopIteration) != "undefined") {
+ this.StopIteration = StopIteration;
+ } else {
+ /** @id MochiKit.Iter.StopIteration */
+ this.StopIteration = new m.NamedError("StopIteration");
+ }
+ this.iteratorRegistry = new m.AdapterRegistry();
+ // Register the iterator factory for arrays
+ this.registerIteratorFactory(
+ "arrayLike",
+ m.isArrayLike,
+ this.arrayLikeIter
+ );
+
+ this.registerIteratorFactory(
+ "iterateNext",
+ this.hasIterateNext,
+ this.iterateNextIter
+ );
+
+ m.nameFunctions(this);
+
+};
+
+MochiKit.Iter.__new__();
+
+//
+// XXX: Internet Explorer blows
+//
+if (MochiKit.__export__) {
+ reduce = MochiKit.Iter.reduce;
+}
+
+MochiKit.Base._exportSymbols(this, MochiKit.Iter);
diff --git a/frontend/gamma/js/MochiKit/Logging.js b/frontend/gamma/js/MochiKit/Logging.js
new file mode 100644
index 0000000..f00996b
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Logging.js
@@ -0,0 +1,262 @@
+/***
+
+MochiKit.Logging 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('Logging', '1.5', ['Base']);
+
+ /** @id MochiKit.Logging.LogMessage */
+MochiKit.Logging.LogMessage = function (num, level, info) {
+ this.num = num;
+ this.level = level;
+ this.info = info;
+ this.timestamp = new Date();
+};
+
+MochiKit.Logging.LogMessage.prototype = {
+ /** @id MochiKit.Logging.LogMessage.prototype.repr */
+ repr: function () {
+ var m = MochiKit.Base;
+ return 'LogMessage(' +
+ m.map(
+ m.repr,
+ [this.num, this.level, this.info]
+ ).join(', ') + ')';
+ },
+ /** @id MochiKit.Logging.LogMessage.prototype.toString */
+ toString: MochiKit.Base.forwardCall("repr")
+};
+
+MochiKit.Base.update(MochiKit.Logging, {
+ /** @id MochiKit.Logging.logLevelAtLeast */
+ logLevelAtLeast: function (minLevel) {
+ var self = MochiKit.Logging;
+ if (typeof(minLevel) == 'string') {
+ minLevel = self.LogLevel[minLevel];
+ }
+ return function (msg) {
+ var msgLevel = msg.level;
+ if (typeof(msgLevel) == 'string') {
+ msgLevel = self.LogLevel[msgLevel];
+ }
+ return msgLevel >= minLevel;
+ };
+ },
+
+ /** @id MochiKit.Logging.isLogMessage */
+ isLogMessage: function (/* ... */) {
+ var LogMessage = MochiKit.Logging.LogMessage;
+ for (var i = 0; i < arguments.length; i++) {
+ if (!(arguments[i] instanceof LogMessage)) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ /** @id MochiKit.Logging.compareLogMessage */
+ compareLogMessage: function (a, b) {
+ return MochiKit.Base.compare([a.level, a.info], [b.level, b.info]);
+ },
+
+ /** @id MochiKit.Logging.alertListener */
+ alertListener: function (msg) {
+ alert(
+ "num: " + msg.num +
+ "\nlevel: " + msg.level +
+ "\ninfo: " + msg.info.join(" ")
+ );
+ }
+
+});
+
+/** @id MochiKit.Logging.Logger */
+MochiKit.Logging.Logger = function (/* optional */maxSize) {
+ this.counter = 0;
+ if (typeof(maxSize) == 'undefined' || maxSize === null) {
+ maxSize = -1;
+ }
+ this.maxSize = maxSize;
+ this._messages = [];
+ this.listeners = {};
+ this.useNativeConsole = false;
+};
+
+MochiKit.Logging.Logger.prototype = {
+ /** @id MochiKit.Logging.Logger.prototype.clear */
+ clear: function () {
+ this._messages.splice(0, this._messages.length);
+ },
+
+ /** @id MochiKit.Logging.Logger.prototype.logToConsole */
+ logToConsole: function (msg) {
+ if (typeof(window) != "undefined" && window.console
+ && window.console.log) {
+ // Safari and FireBug 0.4
+ // Percent replacement is a workaround for cute Safari crashing bug
+ window.console.log(msg.replace(/%/g, '\uFF05'));
+ } else if (typeof(opera) != "undefined" && opera.postError) {
+ // Opera
+ opera.postError(msg);
+ } else if (typeof(Debug) != "undefined" && Debug.writeln) {
+ // IE Web Development Helper (?)
+ // http://www.nikhilk.net/Entry.aspx?id=93
+ Debug.writeln(msg);
+ } else if (typeof(debug) != "undefined" && debug.trace) {
+ // Atlas framework (?)
+ // http://www.nikhilk.net/Entry.aspx?id=93
+ debug.trace(msg);
+ }
+ },
+
+ /** @id MochiKit.Logging.Logger.prototype.dispatchListeners */
+ dispatchListeners: function (msg) {
+ for (var k in this.listeners) {
+ var pair = this.listeners[k];
+ if (pair.ident != k || (pair[0] && !pair[0](msg))) {
+ continue;
+ }
+ pair[1](msg);
+ }
+ },
+
+ /** @id MochiKit.Logging.Logger.prototype.addListener */
+ addListener: function (ident, filter, listener) {
+ if (typeof(filter) == 'string') {
+ filter = MochiKit.Logging.logLevelAtLeast(filter);
+ }
+ var entry = [filter, listener];
+ entry.ident = ident;
+ this.listeners[ident] = entry;
+ },
+
+ /** @id MochiKit.Logging.Logger.prototype.removeListener */
+ removeListener: function (ident) {
+ delete this.listeners[ident];
+ },
+
+ /** @id MochiKit.Logging.Logger.prototype.baseLog */
+ baseLog: function (level, message/*, ...*/) {
+ if (typeof(level) == "number") {
+ if (level >= MochiKit.Logging.LogLevel.FATAL) {
+ level = 'FATAL';
+ } else if (level >= MochiKit.Logging.LogLevel.ERROR) {
+ level = 'ERROR';
+ } else if (level >= MochiKit.Logging.LogLevel.WARNING) {
+ level = 'WARNING';
+ } else if (level >= MochiKit.Logging.LogLevel.INFO) {
+ level = 'INFO';
+ } else {
+ level = 'DEBUG';
+ }
+ }
+ var msg = new MochiKit.Logging.LogMessage(
+ this.counter,
+ level,
+ MochiKit.Base.extend(null, arguments, 1)
+ );
+ this._messages.push(msg);
+ this.dispatchListeners(msg);
+ if (this.useNativeConsole) {
+ this.logToConsole(msg.level + ": " + msg.info.join(" "));
+ }
+ this.counter += 1;
+ while (this.maxSize >= 0 && this._messages.length > this.maxSize) {
+ this._messages.shift();
+ }
+ },
+
+ /** @id MochiKit.Logging.Logger.prototype.getMessages */
+ getMessages: function (howMany) {
+ var firstMsg = 0;
+ if (!(typeof(howMany) == 'undefined' || howMany === null)) {
+ firstMsg = Math.max(0, this._messages.length - howMany);
+ }
+ return this._messages.slice(firstMsg);
+ },
+
+ /** @id MochiKit.Logging.Logger.prototype.getMessageText */
+ getMessageText: function (howMany) {
+ if (typeof(howMany) == 'undefined' || howMany === null) {
+ howMany = 30;
+ }
+ var messages = this.getMessages(howMany);
+ if (messages.length) {
+ var lst = map(function (m) {
+ return '\n [' + m.num + '] ' + m.level + ': ' + m.info.join(' ');
+ }, messages);
+ lst.unshift('LAST ' + messages.length + ' MESSAGES:');
+ return lst.join('');
+ }
+ return '';
+ },
+
+ /** @id MochiKit.Logging.Logger.prototype.debuggingBookmarklet */
+ debuggingBookmarklet: function (inline) {
+ if (typeof(MochiKit.LoggingPane) == "undefined") {
+ alert(this.getMessageText());
+ } else {
+ MochiKit.LoggingPane.createLoggingPane(inline || false);
+ }
+ }
+};
+
+MochiKit.Logging.__new__ = function () {
+ this.LogLevel = {
+ ERROR: 40,
+ FATAL: 50,
+ WARNING: 30,
+ INFO: 20,
+ DEBUG: 10
+ };
+
+ var m = MochiKit.Base;
+ m.registerComparator("LogMessage",
+ this.isLogMessage,
+ this.compareLogMessage
+ );
+
+ var partial = m.partial;
+
+ var Logger = this.Logger;
+ var baseLog = Logger.prototype.baseLog;
+ m.update(this.Logger.prototype, {
+ debug: partial(baseLog, 'DEBUG'),
+ log: partial(baseLog, 'INFO'),
+ error: partial(baseLog, 'ERROR'),
+ fatal: partial(baseLog, 'FATAL'),
+ warning: partial(baseLog, 'WARNING')
+ });
+
+ // indirectly find logger so it can be replaced
+ var self = this;
+ var connectLog = function (name) {
+ return function () {
+ self.logger[name].apply(self.logger, arguments);
+ };
+ };
+
+ /** @id MochiKit.Logging.log */
+ this.log = connectLog('log');
+ /** @id MochiKit.Logging.logError */
+ this.logError = connectLog('error');
+ /** @id MochiKit.Logging.logDebug */
+ this.logDebug = connectLog('debug');
+ /** @id MochiKit.Logging.logFatal */
+ this.logFatal = connectLog('fatal');
+ /** @id MochiKit.Logging.logWarning */
+ this.logWarning = connectLog('warning');
+ this.logger = new Logger();
+ this.logger.useNativeConsole = true;
+
+ m.nameFunctions(this);
+};
+
+MochiKit.Logging.__new__();
+
+MochiKit.Base._exportSymbols(this, MochiKit.Logging);
diff --git a/frontend/gamma/js/MochiKit/LoggingPane.js b/frontend/gamma/js/MochiKit/LoggingPane.js
new file mode 100644
index 0000000..c960c21
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/LoggingPane.js
@@ -0,0 +1,327 @@
+/***
+
+MochiKit.LoggingPane 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('LoggingPane', '1.5', ['Base', 'Logging']);
+
+/** @id MochiKit.LoggingPane.createLoggingPane */
+MochiKit.LoggingPane.createLoggingPane = function (inline/* = false */) {
+ var m = MochiKit.LoggingPane;
+ inline = !(!inline);
+ if (m._loggingPane && m._loggingPane.inline != inline) {
+ m._loggingPane.closePane();
+ m._loggingPane = null;
+ }
+ if (!m._loggingPane || m._loggingPane.closed) {
+ m._loggingPane = new m.LoggingPane(inline, MochiKit.Logging.logger);
+ }
+ return m._loggingPane;
+};
+
+/** @id MochiKit.LoggingPane.LoggingPane */
+MochiKit.LoggingPane.LoggingPane = function (inline/* = false */, logger/* = MochiKit.Logging.logger */) {
+
+ /* Use a div if inline, pop up a window if not */
+ /* Create the elements */
+ if (typeof(logger) == "undefined" || logger === null) {
+ logger = MochiKit.Logging.logger;
+ }
+ this.logger = logger;
+ var update = MochiKit.Base.update;
+ var updatetree = MochiKit.Base.updatetree;
+ var bind = MochiKit.Base.bind;
+ var clone = MochiKit.Base.clone;
+ var win = window;
+ var uid = "_MochiKit_LoggingPane";
+ if (typeof(MochiKit.DOM) != "undefined") {
+ win = MochiKit.DOM.currentWindow();
+ }
+ if (!inline) {
+ // name the popup with the base URL for uniqueness
+ var url = win.location.href.split("?")[0].replace(/[#:\/.><&%-]/g, "_");
+ var name = uid + "_" + url;
+ var nwin = win.open("", name, "dependent,resizable,height=200");
+ if (!nwin) {
+ alert("Not able to open debugging window due to pop-up blocking.");
+ return undefined;
+ }
+ nwin.document.write(
+ '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" '
+ + '"http://www.w3.org/TR/html4/loose.dtd">'
+ + '<html><head><title>[MochiKit.LoggingPane]</title></head>'
+ + '<body></body></html>'
+ );
+ nwin.document.close();
+ nwin.document.title += ' ' + win.document.title;
+ win = nwin;
+ }
+ var doc = win.document;
+ this.doc = doc;
+
+ // Connect to the debug pane if it already exists (i.e. in a window orphaned by the page being refreshed)
+ var debugPane = doc.getElementById(uid);
+ var existing_pane = !!debugPane;
+ if (debugPane && typeof(debugPane.loggingPane) != "undefined") {
+ debugPane.loggingPane.logger = this.logger;
+ debugPane.loggingPane.buildAndApplyFilter();
+ return debugPane.loggingPane;
+ }
+
+ if (existing_pane) {
+ // clear any existing contents
+ var child;
+ while ((child = debugPane.firstChild)) {
+ debugPane.removeChild(child);
+ }
+ } else {
+ debugPane = doc.createElement("div");
+ debugPane.id = uid;
+ }
+ debugPane.loggingPane = this;
+ var levelFilterField = doc.createElement("input");
+ var infoFilterField = doc.createElement("input");
+ var filterButton = doc.createElement("button");
+ var loadButton = doc.createElement("button");
+ var clearButton = doc.createElement("button");
+ var closeButton = doc.createElement("button");
+ var logPaneArea = doc.createElement("div");
+ var logPane = doc.createElement("div");
+
+ /* Set up the functions */
+ var listenerId = uid + "_Listener";
+ this.colorTable = clone(this.colorTable);
+ var messages = [];
+ var messageFilter = null;
+
+ /** @id MochiKit.LoggingPane.messageLevel */
+ var messageLevel = function (msg) {
+ var level = msg.level;
+ if (typeof(level) == "number") {
+ level = MochiKit.Logging.LogLevel[level];
+ }
+ return level;
+ };
+
+ /** @id MochiKit.LoggingPane.messageText */
+ var messageText = function (msg) {
+ return msg.info.join(" ");
+ };
+
+ /** @id MochiKit.LoggingPane.addMessageText */
+ var addMessageText = bind(function (msg) {
+ var level = messageLevel(msg);
+ var text = messageText(msg);
+ var c = this.colorTable[level];
+ var p = doc.createElement("span");
+ p.className = "MochiKit-LogMessage MochiKit-LogLevel-" + level;
+ p.style.cssText = "margin: 0px; white-space: -moz-pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; white-space: pre-line; word-wrap: break-word; wrap-option: emergency; color: " + c;
+ p.appendChild(doc.createTextNode(level + ": " + text));
+ logPane.appendChild(p);
+ logPane.appendChild(doc.createElement("br"));
+ if (logPaneArea.offsetHeight > logPaneArea.scrollHeight) {
+ logPaneArea.scrollTop = 0;
+ } else {
+ logPaneArea.scrollTop = logPaneArea.scrollHeight;
+ }
+ }, this);
+
+ /** @id MochiKit.LoggingPane.addMessage */
+ var addMessage = function (msg) {
+ messages[messages.length] = msg;
+ addMessageText(msg);
+ };
+
+ /** @id MochiKit.LoggingPane.buildMessageFilter */
+ var buildMessageFilter = function () {
+ var levelre, infore;
+ try {
+ /* Catch any exceptions that might arise due to invalid regexes */
+ levelre = new RegExp(levelFilterField.value);
+ infore = new RegExp(infoFilterField.value);
+ } catch(e) {
+ /* If there was an error with the regexes, do no filtering */
+ logDebug("Error in filter regex: " + e.message);
+ return null;
+ }
+
+ return function (msg) {
+ return (
+ levelre.test(messageLevel(msg)) &&
+ infore.test(messageText(msg))
+ );
+ };
+ };
+
+ /** @id MochiKit.LoggingPane.clearMessagePane */
+ var clearMessagePane = function () {
+ while (logPane.firstChild) {
+ logPane.removeChild(logPane.firstChild);
+ }
+ };
+
+ /** @id MochiKit.LoggingPane.clearMessages */
+ var clearMessages = function () {
+ messages = [];
+ clearMessagePane();
+ };
+
+ /** @id MochiKit.LoggingPane.closePane */
+ var closePane = bind(function () {
+ if (this.closed) {
+ return;
+ }
+ this.closed = true;
+ if (MochiKit.LoggingPane._loggingPane == this) {
+ MochiKit.LoggingPane._loggingPane = null;
+ }
+ this.logger.removeListener(listenerId);
+ try {
+ try {
+ debugPane.loggingPane = null;
+ } catch(e) { logFatal("Bookmarklet was closed incorrectly."); }
+ if (inline) {
+ debugPane.parentNode.removeChild(debugPane);
+ } else {
+ this.win.close();
+ }
+ } catch(e) {}
+ }, this);
+
+ /** @id MochiKit.LoggingPane.filterMessages */
+ var filterMessages = function () {
+ clearMessagePane();
+
+ for (var i = 0; i < messages.length; i++) {
+ var msg = messages[i];
+ if (messageFilter === null || messageFilter(msg)) {
+ addMessageText(msg);
+ }
+ }
+ };
+
+ this.buildAndApplyFilter = function () {
+ messageFilter = buildMessageFilter();
+
+ filterMessages();
+
+ this.logger.removeListener(listenerId);
+ this.logger.addListener(listenerId, messageFilter, addMessage);
+ };
+
+
+ /** @id MochiKit.LoggingPane.loadMessages */
+ var loadMessages = bind(function () {
+ messages = this.logger.getMessages();
+ filterMessages();
+ }, this);
+
+ /** @id MochiKit.LoggingPane.filterOnEnter */
+ var filterOnEnter = bind(function (event) {
+ event = event || window.event;
+ key = event.which || event.keyCode;
+ if (key == 13) {
+ this.buildAndApplyFilter();
+ }
+ }, this);
+
+ /* Create the debug pane */
+ var style = "display: block; z-index: 1000; left: 0px; bottom: 0px; position: fixed; width: 100%; background-color: white; font: " + this.logFont;
+ if (inline) {
+ style += "; height: 10em; border-top: 2px solid black";
+ } else {
+ style += "; height: 100%;";
+ }
+ debugPane.style.cssText = style;
+
+ if (!existing_pane) {
+ doc.body.appendChild(debugPane);
+ }
+
+ /* Create the filter fields */
+ style = {"cssText": "width: 33%; display: inline; font: " + this.logFont};
+
+ updatetree(levelFilterField, {
+ "value": "FATAL|ERROR|WARNING|INFO|DEBUG",
+ "onkeypress": filterOnEnter,
+ "style": style
+ });
+ debugPane.appendChild(levelFilterField);
+
+ updatetree(infoFilterField, {
+ "value": ".*",
+ "onkeypress": filterOnEnter,
+ "style": style
+ });
+ debugPane.appendChild(infoFilterField);
+
+ /* Create the buttons */
+ style = "width: 8%; display:inline; font: " + this.logFont;
+
+ filterButton.appendChild(doc.createTextNode("Filter"));
+ filterButton.onclick = bind("buildAndApplyFilter", this);
+ filterButton.style.cssText = style;
+ debugPane.appendChild(filterButton);
+
+ loadButton.appendChild(doc.createTextNode("Load"));
+ loadButton.onclick = loadMessages;
+ loadButton.style.cssText = style;
+ debugPane.appendChild(loadButton);
+
+ clearButton.appendChild(doc.createTextNode("Clear"));
+ clearButton.onclick = clearMessages;
+ clearButton.style.cssText = style;
+ debugPane.appendChild(clearButton);
+
+ closeButton.appendChild(doc.createTextNode("Close"));
+ closeButton.onclick = closePane;
+ closeButton.style.cssText = style;
+ debugPane.appendChild(closeButton);
+
+ /* Create the logging pane */
+ logPaneArea.style.cssText = "overflow: auto; width: 100%";
+ logPane.style.cssText = "width: 100%; height: " + (inline ? "8em" : "100%");
+
+ logPaneArea.appendChild(logPane);
+ debugPane.appendChild(logPaneArea);
+
+ this.buildAndApplyFilter();
+ loadMessages();
+
+ if (inline) {
+ this.win = undefined;
+ } else {
+ this.win = win;
+ }
+ this.inline = inline;
+ this.closePane = closePane;
+ this.closed = false;
+
+
+ return this;
+};
+
+MochiKit.LoggingPane.LoggingPane.prototype = {
+ "logFont": "8pt Verdana,sans-serif",
+ "colorTable": {
+ "ERROR": "red",
+ "FATAL": "darkred",
+ "WARNING": "blue",
+ "INFO": "black",
+ "DEBUG": "green"
+ }
+};
+
+MochiKit.LoggingPane.__new__ = function () {
+ MochiKit.Base.nameFunctions(this);
+ MochiKit.LoggingPane._loggingPane = null;
+};
+
+MochiKit.LoggingPane.__new__();
+
+MochiKit.Base._exportSymbols(this, MochiKit.LoggingPane);
diff --git a/frontend/gamma/js/MochiKit/MochiKit.js b/frontend/gamma/js/MochiKit/MochiKit.js
new file mode 100644
index 0000000..8e5be68
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/MochiKit.js
@@ -0,0 +1,136 @@
+/***
+
+MochiKit.MochiKit 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito. All rights Reserved.
+
+***/
+
+if (typeof(MochiKit) == 'undefined') {
+ MochiKit = {};
+}
+
+if (typeof(MochiKit.MochiKit) == 'undefined') {
+ /** @id MochiKit.MochiKit */
+ MochiKit.MochiKit = {};
+}
+
+MochiKit.MochiKit.NAME = "MochiKit.MochiKit";
+MochiKit.MochiKit.VERSION = "1.5";
+MochiKit.MochiKit.__repr__ = function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+};
+
+/** @id MochiKit.MochiKit.toString */
+MochiKit.MochiKit.toString = function () {
+ return this.__repr__();
+};
+
+/** @id MochiKit.MochiKit.SUBMODULES */
+MochiKit.MochiKit.SUBMODULES = [
+ "Base",
+ "Iter",
+ "Logging",
+ "DateTime",
+ "Format",
+ "Text",
+ "Async",
+ "DOM",
+ "Selector",
+ "Style",
+ "LoggingPane",
+ "Color",
+ "Signal",
+ "Position",
+ "Visual",
+ "DragAndDrop",
+ "Sortable"
+];
+
+(function () {
+ if (typeof(document) == "undefined") {
+ return;
+ }
+ var scripts = document.getElementsByTagName("script");
+ var kXHTMLNSURI = "http://www.w3.org/1999/xhtml";
+ var kSVGNSURI = "http://www.w3.org/2000/svg";
+ var kXLINKNSURI = "http://www.w3.org/1999/xlink";
+ var kXULNSURI = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ var base = null;
+ var baseElem = null;
+ var allScripts = {};
+ var i;
+ var src;
+ for (i = 0; i < scripts.length; i++) {
+ src = null;
+ switch (scripts[i].namespaceURI) {
+ case kSVGNSURI:
+ src = scripts[i].getAttributeNS(kXLINKNSURI, "href");
+ break;
+ /*
+ case null: // HTML
+ case '': // HTML
+ case kXHTMLNSURI:
+ case kXULNSURI:
+ */
+ default:
+ src = scripts[i].getAttribute("src");
+ break;
+ }
+ if (!src) {
+ continue;
+ }
+ allScripts[src] = true;
+ if (src.match(/MochiKit.js(\?.*)?$/)) {
+ base = src.substring(0, src.lastIndexOf('MochiKit.js'));
+ baseElem = scripts[i];
+ }
+ }
+ if (base === null) {
+ return;
+ }
+ var modules = MochiKit.MochiKit.SUBMODULES;
+ for (var i = 0; i < modules.length; i++) {
+ if (MochiKit[modules[i]]) {
+ continue;
+ }
+ var uri = base + modules[i] + '.js';
+ if (uri in allScripts) {
+ continue;
+ }
+ if (baseElem.namespaceURI == kSVGNSURI ||
+ baseElem.namespaceURI == kXULNSURI) {
+ // SVG, XUL
+ /*
+ SVG does not support document.write, so if Safari wants to
+ support SVG tests it should fix its deferred loading bug
+ (see following below).
+ */
+ var s = document.createElementNS(baseElem.namespaceURI, 'script');
+ s.setAttribute("id", "MochiKit_" + base + modules[i]);
+ if (baseElem.namespaceURI == kSVGNSURI) {
+ s.setAttributeNS(kXLINKNSURI, 'href', uri);
+ } else {
+ s.setAttribute('src', uri);
+ }
+ s.setAttribute("type", "application/x-javascript");
+ baseElem.parentNode.appendChild(s);
+ } else {
+ // HTML, XHTML
+ /*
+ DOM can not be used here because Safari does
+ deferred loading of scripts unless they are
+ in the document or inserted with document.write
+
+ This is not XHTML compliant. If you want XHTML
+ compliance then you must use the packed version of MochiKit
+ or include each script individually (basically unroll
+ these document.write calls into your XHTML source)
+ */
+ document.write('<' + baseElem.nodeName + ' src="' + uri +
+ '" type="text/javascript"></script>');
+ }
+ };
+})();
diff --git a/frontend/gamma/js/MochiKit/MockDOM.js b/frontend/gamma/js/MochiKit/MockDOM.js
new file mode 100644
index 0000000..abdb54a
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/MockDOM.js
@@ -0,0 +1,115 @@
+/***
+
+MochiKit.MockDOM 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito. All rights Reserved.
+
+***/
+
+if (typeof(MochiKit) == "undefined") {
+ MochiKit = {};
+}
+
+if (typeof(MochiKit.MockDOM) == "undefined") {
+ MochiKit.MockDOM = {};
+}
+
+MochiKit.MockDOM.NAME = "MochiKit.MockDOM";
+MochiKit.MockDOM.VERSION = "1.5";
+
+MochiKit.MockDOM.__repr__ = function () {
+ return "[" + this.NAME + " " + this.VERSION + "]";
+};
+
+/** @id MochiKit.MockDOM.toString */
+MochiKit.MockDOM.toString = function () {
+ return this.__repr__();
+};
+
+/** @id MochiKit.MockDOM.createDocument */
+MochiKit.MockDOM.createDocument = function () {
+ var doc = new MochiKit.MockDOM.MockElement("DOCUMENT");
+ doc.body = doc.createElement("BODY");
+ doc.appendChild(doc.body);
+ return doc;
+};
+
+/** @id MochiKit.MockDOM.MockElement */
+MochiKit.MockDOM.MockElement = function (name, data, ownerDocument) {
+ this.tagName = this.nodeName = name.toUpperCase();
+ this.ownerDocument = ownerDocument || null;
+ if (name == "DOCUMENT") {
+ this.nodeType = 9;
+ this.childNodes = [];
+ } else if (typeof(data) == "string") {
+ this.nodeValue = data;
+ this.nodeType = 3;
+ } else {
+ this.nodeType = 1;
+ this.childNodes = [];
+ }
+ if (name.substring(0, 1) == "<") {
+ var nameattr = name.substring(
+ name.indexOf('"') + 1, name.lastIndexOf('"'));
+ name = name.substring(1, name.indexOf(" "));
+ this.tagName = this.nodeName = name.toUpperCase();
+ this.setAttribute("name", nameattr);
+ }
+};
+
+MochiKit.MockDOM.MockElement.prototype = {
+ /** @id MochiKit.MockDOM.MockElement.prototype.createElement */
+ createElement: function (tagName) {
+ return new MochiKit.MockDOM.MockElement(tagName, null, this.nodeType == 9 ? this : this.ownerDocument);
+ },
+ /** @id MochiKit.MockDOM.MockElement.prototype.createTextNode */
+ createTextNode: function (text) {
+ return new MochiKit.MockDOM.MockElement("text", text, this.nodeType == 9 ? this : this.ownerDocument);
+ },
+ /** @id MochiKit.MockDOM.MockElement.prototype.setAttribute */
+ setAttribute: function (name, value) {
+ this[name] = value;
+ },
+ /** @id MochiKit.MockDOM.MockElement.prototype.getAttribute */
+ getAttribute: function (name) {
+ return this[name];
+ },
+ /** @id MochiKit.MockDOM.MockElement.prototype.appendChild */
+ appendChild: function (child) {
+ this.childNodes.push(child);
+ },
+ /** @id MochiKit.MockDOM.MockElement.prototype.toString */
+ toString: function () {
+ return "MockElement(" + this.tagName + ")";
+ },
+ /** @id MochiKit.MockDOM.MockElement.prototype.getElementsByTagName */
+ getElementsByTagName: function (tagName) {
+ var foundElements = [];
+ MochiKit.Base.nodeWalk(this, function(node){
+ if (tagName == '*' || tagName == node.tagName) {
+ foundElements.push(node);
+ return node.childNodes;
+ }
+ });
+ return foundElements;
+ }
+};
+
+ /** @id MochiKit.MockDOM.EXPORT_OK */
+MochiKit.MockDOM.EXPORT_OK = [
+ "mockElement",
+ "createDocument"
+];
+
+ /** @id MochiKit.MockDOM.EXPORT */
+MochiKit.MockDOM.EXPORT = [
+ "document"
+];
+
+MochiKit.MockDOM.__new__ = function () {
+ this.document = this.createDocument();
+};
+
+MochiKit.MockDOM.__new__();
diff --git a/frontend/gamma/js/MochiKit/Position.js b/frontend/gamma/js/MochiKit/Position.js
new file mode 100644
index 0000000..6bc5b39
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Position.js
@@ -0,0 +1,218 @@
+/***
+
+MochiKit.Position 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005-2006 Bob Ippolito and others. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('Position', '1.5', ['Base', 'DOM', 'Style']);
+
+MochiKit.Base.update(MochiKit.Position, {
+ // Don't export from this module
+ __export__: false,
+
+ // set to true if needed, warning: firefox performance problems
+ // NOT neeeded for page scrolling, only if draggable contained in
+ // scrollable elements
+ includeScrollOffsets: false,
+
+ /** @id MochiKit.Position.prepare */
+ prepare: function () {
+ var deltaX = window.pageXOffset
+ || document.documentElement.scrollLeft
+ || document.body.scrollLeft
+ || 0;
+ var deltaY = window.pageYOffset
+ || document.documentElement.scrollTop
+ || document.body.scrollTop
+ || 0;
+ this.windowOffset = new MochiKit.Style.Coordinates(deltaX, deltaY);
+ },
+
+ /** @id MochiKit.Position.cumulativeOffset */
+ cumulativeOffset: function (element) {
+ var valueT = 0;
+ var valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ } while (element);
+ return new MochiKit.Style.Coordinates(valueL, valueT);
+ },
+
+ /** @id MochiKit.Position.realOffset */
+ realOffset: function (element) {
+ var valueT = 0;
+ var valueL = 0;
+ do {
+ valueT += element.scrollTop || 0;
+ valueL += element.scrollLeft || 0;
+ element = element.parentNode;
+ } while (element);
+ return new MochiKit.Style.Coordinates(valueL, valueT);
+ },
+
+ /** @id MochiKit.Position.within */
+ within: function (element, x, y) {
+ if (this.includeScrollOffsets) {
+ return this.withinIncludingScrolloffsets(element, x, y);
+ }
+ this.xcomp = x;
+ this.ycomp = y;
+ this.offset = this.cumulativeOffset(element);
+ if (element.style.position == "fixed") {
+ this.offset.x += this.windowOffset.x;
+ this.offset.y += this.windowOffset.y;
+ }
+
+ return (y >= this.offset.y &&
+ y < this.offset.y + element.offsetHeight &&
+ x >= this.offset.x &&
+ x < this.offset.x + element.offsetWidth);
+ },
+
+ /** @id MochiKit.Position.withinIncludingScrolloffsets */
+ withinIncludingScrolloffsets: function (element, x, y) {
+ var offsetcache = this.realOffset(element);
+
+ this.xcomp = x + offsetcache.x - this.windowOffset.x;
+ this.ycomp = y + offsetcache.y - this.windowOffset.y;
+ this.offset = this.cumulativeOffset(element);
+
+ return (this.ycomp >= this.offset.y &&
+ this.ycomp < this.offset.y + element.offsetHeight &&
+ this.xcomp >= this.offset.x &&
+ this.xcomp < this.offset.x + element.offsetWidth);
+ },
+
+ // within must be called directly before
+ /** @id MochiKit.Position.overlap */
+ overlap: function (mode, element) {
+ if (!mode) {
+ return 0;
+ }
+ if (mode == 'vertical') {
+ return ((this.offset.y + element.offsetHeight) - this.ycomp) /
+ element.offsetHeight;
+ }
+ if (mode == 'horizontal') {
+ return ((this.offset.x + element.offsetWidth) - this.xcomp) /
+ element.offsetWidth;
+ }
+ },
+
+ /** @id MochiKit.Position.absolutize */
+ absolutize: function (element) {
+ element = MochiKit.DOM.getElement(element);
+ if (element.style.position == 'absolute') {
+ return;
+ }
+ MochiKit.Position.prepare();
+
+ var offsets = MochiKit.Position.positionedOffset(element);
+ var width = element.clientWidth;
+ var height = element.clientHeight;
+
+ var oldStyle = {
+ 'position': element.style.position,
+ 'left': offsets.x - parseFloat(element.style.left || 0),
+ 'top': offsets.y - parseFloat(element.style.top || 0),
+ 'width': element.style.width,
+ 'height': element.style.height
+ };
+
+ element.style.position = 'absolute';
+ element.style.top = offsets.y + 'px';
+ element.style.left = offsets.x + 'px';
+ element.style.width = width + 'px';
+ element.style.height = height + 'px';
+
+ return oldStyle;
+ },
+
+ /** @id MochiKit.Position.positionedOffset */
+ positionedOffset: function (element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ if (element) {
+ var p = MochiKit.Style.getStyle(element, 'position');
+ if (p == 'relative' || p == 'absolute') {
+ break;
+ }
+ }
+ } while (element);
+ return new MochiKit.Style.Coordinates(valueL, valueT);
+ },
+
+ /** @id MochiKit.Position.relativize */
+ relativize: function (element, oldPos) {
+ element = MochiKit.DOM.getElement(element);
+ if (element.style.position == 'relative') {
+ return;
+ }
+ MochiKit.Position.prepare();
+
+ var top = parseFloat(element.style.top || 0) -
+ (oldPos['top'] || 0);
+ var left = parseFloat(element.style.left || 0) -
+ (oldPos['left'] || 0);
+
+ element.style.position = oldPos['position'];
+ element.style.top = top + 'px';
+ element.style.left = left + 'px';
+ element.style.width = oldPos['width'];
+ element.style.height = oldPos['height'];
+ },
+
+ /** @id MochiKit.Position.clone */
+ clone: function (source, target) {
+ source = MochiKit.DOM.getElement(source);
+ target = MochiKit.DOM.getElement(target);
+ target.style.position = 'absolute';
+ var offsets = this.cumulativeOffset(source);
+ target.style.top = offsets.y + 'px';
+ target.style.left = offsets.x + 'px';
+ target.style.width = source.offsetWidth + 'px';
+ target.style.height = source.offsetHeight + 'px';
+ },
+
+ /** @id MochiKit.Position.page */
+ page: function (forElement) {
+ var valueT = 0;
+ var valueL = 0;
+
+ var element = forElement;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+
+ // Safari fix
+ if (element.offsetParent == document.body && MochiKit.Style.getStyle(element, 'position') == 'absolute') {
+ break;
+ }
+ } while (element = element.offsetParent);
+
+ element = forElement;
+ do {
+ valueT -= element.scrollTop || 0;
+ valueL -= element.scrollLeft || 0;
+ } while (element = element.parentNode);
+
+ return new MochiKit.Style.Coordinates(valueL, valueT);
+ }
+});
+
+MochiKit.Position.__new__ = function (win) {
+ MochiKit.Base.nameFunctions(this);
+};
+
+MochiKit.Position.__new__(this);
+
+MochiKit.Base._exportSymbols(this, MochiKit.Position);
diff --git a/frontend/gamma/js/MochiKit/Selector.js b/frontend/gamma/js/MochiKit/Selector.js
new file mode 100644
index 0000000..6aec892
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Selector.js
@@ -0,0 +1,387 @@
+/***
+
+MochiKit.Selector 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito and others. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('Selector', '1.5', ['Base', 'DOM', 'Iter']);
+
+MochiKit.Selector.Selector = function (expression) {
+ this.params = {classNames: [], pseudoClassNames: []};
+ this.expression = expression.toString().replace(/(^\s+|\s+$)/g, '');
+ this.parseExpression();
+ this.compileMatcher();
+};
+
+MochiKit.Selector.Selector.prototype = {
+ /***
+
+ Selector class: convenient object to make CSS selections.
+
+ ***/
+ __class__: MochiKit.Selector.Selector,
+
+ /** @id MochiKit.Selector.Selector.prototype.parseExpression */
+ parseExpression: function () {
+ function abort(message) {
+ throw 'Parse error in selector: ' + message;
+ }
+
+ if (this.expression == '') {
+ abort('empty expression');
+ }
+
+ var repr = MochiKit.Base.repr;
+ var params = this.params;
+ var expr = this.expression;
+ var match, modifier, clause, rest;
+ while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!^$*]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
+ params.attributes = params.attributes || [];
+ params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
+ expr = match[1];
+ }
+
+ if (expr == '*') {
+ return this.params.wildcard = true;
+ }
+
+ while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+(?:\([^)]*\))?)(.*)/i)) {
+ modifier = match[1];
+ clause = match[2];
+ rest = match[3];
+ switch (modifier) {
+ case '#':
+ params.id = clause;
+ break;
+ case '.':
+ params.classNames.push(clause);
+ break;
+ case ':':
+ params.pseudoClassNames.push(clause);
+ break;
+ case '':
+ case undefined:
+ params.tagName = clause.toUpperCase();
+ break;
+ default:
+ abort(repr(expr));
+ }
+ expr = rest;
+ }
+
+ if (expr.length > 0) {
+ abort(repr(expr));
+ }
+ },
+
+ /** @id MochiKit.Selector.Selector.prototype.buildMatchExpression */
+ buildMatchExpression: function () {
+ var repr = MochiKit.Base.repr;
+ var params = this.params;
+ var conditions = [];
+ var clause, i;
+
+ function childElements(element) {
+ return "MochiKit.Base.filter(function (node) { return node.nodeType == 1; }, " + element + ".childNodes)";
+ }
+
+ if (params.wildcard) {
+ conditions.push('true');
+ }
+ if (clause = params.id) {
+ conditions.push('element.id == ' + repr(clause));
+ }
+ if (clause = params.tagName) {
+ conditions.push('element.tagName.toUpperCase() == ' + repr(clause));
+ }
+ if ((clause = params.classNames).length > 0) {
+ for (i = 0; i < clause.length; i++) {
+ conditions.push('MochiKit.DOM.hasElementClass(element, ' + repr(clause[i]) + ')');
+ }
+ }
+ if ((clause = params.pseudoClassNames).length > 0) {
+ for (i = 0; i < clause.length; i++) {
+ var match = clause[i].match(/^([^(]+)(?:\((.*)\))?$/);
+ var pseudoClass = match[1];
+ var pseudoClassArgument = match[2];
+ switch (pseudoClass) {
+ case 'root':
+ conditions.push('element.nodeType == 9 || element === element.ownerDocument.documentElement'); break;
+ case 'nth-child':
+ case 'nth-last-child':
+ case 'nth-of-type':
+ case 'nth-last-of-type':
+ match = pseudoClassArgument.match(/^((?:(\d+)n\+)?(\d+)|odd|even)$/);
+ if (!match) {
+ throw "Invalid argument to pseudo element nth-child: " + pseudoClassArgument;
+ }
+ var a, b;
+ if (match[0] == 'odd') {
+ a = 2;
+ b = 1;
+ } else if (match[0] == 'even') {
+ a = 2;
+ b = 0;
+ } else {
+ a = match[2] && parseInt(match) || null;
+ b = parseInt(match[3]);
+ }
+ conditions.push('this.nthChild(element,' + a + ',' + b
+ + ',' + !!pseudoClass.match('^nth-last') // Reverse
+ + ',' + !!pseudoClass.match('of-type$') // Restrict to same tagName
+ + ')');
+ break;
+ case 'first-child':
+ conditions.push('this.nthChild(element, null, 1)');
+ break;
+ case 'last-child':
+ conditions.push('this.nthChild(element, null, 1, true)');
+ break;
+ case 'first-of-type':
+ conditions.push('this.nthChild(element, null, 1, false, true)');
+ break;
+ case 'last-of-type':
+ conditions.push('this.nthChild(element, null, 1, true, true)');
+ break;
+ case 'only-child':
+ conditions.push(childElements('element.parentNode') + '.length == 1');
+ break;
+ case 'only-of-type':
+ conditions.push('MochiKit.Base.filter(function (node) { return node.tagName == element.tagName; }, ' + childElements('element.parentNode') + ').length == 1');
+ break;
+ case 'empty':
+ conditions.push('element.childNodes.length == 0');
+ break;
+ case 'enabled':
+ conditions.push('(this.isUIElement(element) && element.disabled === false)');
+ break;
+ case 'disabled':
+ conditions.push('(this.isUIElement(element) && element.disabled === true)');
+ break;
+ case 'checked':
+ conditions.push('(this.isUIElement(element) && element.checked === true)');
+ break;
+ case 'not':
+ var subselector = new MochiKit.Selector.Selector(pseudoClassArgument);
+ conditions.push('!( ' + subselector.buildMatchExpression() + ')')
+ break;
+ }
+ }
+ }
+ if (clause = params.attributes) {
+ MochiKit.Base.map(function (attribute) {
+ var value = 'MochiKit.DOM.getNodeAttribute(element, ' + repr(attribute.name) + ')';
+ var splitValueBy = function (delimiter) {
+ return value + '.split(' + repr(delimiter) + ')';
+ }
+ conditions.push(value + ' != null');
+ switch (attribute.operator) {
+ case '=':
+ conditions.push(value + ' == ' + repr(attribute.value));
+ break;
+ case '~=':
+ conditions.push('MochiKit.Base.findValue(' + splitValueBy(' ') + ', ' + repr(attribute.value) + ') > -1');
+ break;
+ case '^=':
+ conditions.push(value + '.substring(0, ' + attribute.value.length + ') == ' + repr(attribute.value));
+ break;
+ case '$=':
+ conditions.push(value + '.substring(' + value + '.length - ' + attribute.value.length + ') == ' + repr(attribute.value));
+ break;
+ case '*=':
+ conditions.push(value + '.match(' + repr(attribute.value) + ')');
+ break;
+ case '|=':
+ conditions.push(splitValueBy('-') + '[0].toUpperCase() == ' + repr(attribute.value.toUpperCase()));
+ break;
+ case '!=':
+ conditions.push(value + ' != ' + repr(attribute.value));
+ break;
+ case '':
+ case undefined:
+ // Condition already added above
+ break;
+ default:
+ throw 'Unknown operator ' + attribute.operator + ' in selector';
+ }
+ }, clause);
+ }
+
+ return conditions.join(' && ');
+ },
+
+ /** @id MochiKit.Selector.Selector.prototype.compileMatcher */
+ compileMatcher: function () {
+ var code = 'return (!element.tagName) ? false : ' +
+ this.buildMatchExpression() + ';';
+ this.match = new Function('element', code);
+ },
+
+ /** @id MochiKit.Selector.Selector.prototype.nthChild */
+ nthChild: function (element, a, b, reverse, sametag){
+ var siblings = MochiKit.Base.filter(function (node) {
+ return node.nodeType == 1;
+ }, element.parentNode.childNodes);
+ if (sametag) {
+ siblings = MochiKit.Base.filter(function (node) {
+ return node.tagName == element.tagName;
+ }, siblings);
+ }
+ if (reverse) {
+ siblings = MochiKit.Iter.reversed(siblings);
+ }
+ if (a) {
+ var actualIndex = MochiKit.Base.findIdentical(siblings, element);
+ return ((actualIndex + 1 - b) / a) % 1 == 0;
+ } else {
+ return b == MochiKit.Base.findIdentical(siblings, element) + 1;
+ }
+ },
+
+ /** @id MochiKit.Selector.Selector.prototype.isUIElement */
+ isUIElement: function (element) {
+ return MochiKit.Base.findValue(['input', 'button', 'select', 'option', 'textarea', 'object'],
+ element.tagName.toLowerCase()) > -1;
+ },
+
+ /** @id MochiKit.Selector.Selector.prototype.findElements */
+ findElements: function (scope, axis) {
+ var element;
+
+ if (axis == undefined) {
+ axis = "";
+ }
+
+ function inScope(element, scope) {
+ if (axis == "") {
+ return MochiKit.DOM.isChildNode(element, scope);
+ } else if (axis == ">") {
+ return element.parentNode === scope;
+ } else if (axis == "+") {
+ return element === nextSiblingElement(scope);
+ } else if (axis == "~") {
+ var sibling = scope;
+ while (sibling = nextSiblingElement(sibling)) {
+ if (element === sibling) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ throw "Invalid axis: " + axis;
+ }
+ }
+
+ if (element = MochiKit.DOM.getElement(this.params.id)) {
+ if (this.match(element)) {
+ if (!scope || inScope(element, scope)) {
+ return [element];
+ }
+ }
+ }
+
+ function nextSiblingElement(node) {
+ node = node.nextSibling;
+ while (node && node.nodeType != 1) {
+ node = node.nextSibling;
+ }
+ return node;
+ }
+
+ if (axis == "") {
+ scope = (scope || MochiKit.DOM.currentDocument()).getElementsByTagName(this.params.tagName || '*');
+ } else if (axis == ">") {
+ if (!scope) {
+ throw "> combinator not allowed without preceeding expression";
+ }
+ scope = MochiKit.Base.filter(function (node) {
+ return node.nodeType == 1;
+ }, scope.childNodes);
+ } else if (axis == "+") {
+ if (!scope) {
+ throw "+ combinator not allowed without preceeding expression";
+ }
+ scope = nextSiblingElement(scope) && [nextSiblingElement(scope)];
+ } else if (axis == "~") {
+ if (!scope) {
+ throw "~ combinator not allowed without preceeding expression";
+ }
+ var newscope = [];
+ while (nextSiblingElement(scope)) {
+ scope = nextSiblingElement(scope);
+ newscope.push(scope);
+ }
+ scope = newscope;
+ }
+
+ if (!scope) {
+ return [];
+ }
+
+ var results = MochiKit.Base.filter(MochiKit.Base.bind(function (scopeElt) {
+ return this.match(scopeElt);
+ }, this), scope);
+
+ return results;
+ },
+
+ /** @id MochiKit.Selector.Selector.prototype.repr */
+ repr: function () {
+ return 'Selector(' + this.expression + ')';
+ },
+
+ toString: MochiKit.Base.forwardCall("repr")
+};
+
+MochiKit.Base.update(MochiKit.Selector, {
+
+ /** @id MochiKit.Selector.findChildElements */
+ findChildElements: function (element, expressions) {
+ element = MochiKit.DOM.getElement(element);
+ var uniq = function(arr) {
+ var res = [];
+ for (var i = 0; i < arr.length; i++) {
+ if (MochiKit.Base.findIdentical(res, arr[i]) < 0) {
+ res.push(arr[i]);
+ }
+ }
+ return res;
+ };
+ return MochiKit.Base.flattenArray(MochiKit.Base.map(function (expression) {
+ var nextScope = "";
+ var reducer = function (results, expr) {
+ var match = expr.match(/^[>+~]$/);
+ if (match) {
+ nextScope = match[0];
+ return results;
+ } else {
+ var selector = new MochiKit.Selector.Selector(expr);
+ var elements = MochiKit.Iter.reduce(function (elements, result) {
+ return MochiKit.Base.extend(elements, selector.findElements(result || element, nextScope));
+ }, results, []);
+ nextScope = "";
+ return elements;
+ }
+ };
+ var exprs = expression.replace(/(^\s+|\s+$)/g, '').split(/\s+/);
+ return uniq(MochiKit.Iter.reduce(reducer, exprs, [null]));
+ }, expressions));
+ },
+
+ findDocElements: function () {
+ return MochiKit.Selector.findChildElements(MochiKit.DOM.currentDocument(), arguments);
+ },
+
+ __new__: function () {
+ this.$$ = this.findDocElements;
+ MochiKit.Base.nameFunctions(this);
+ }
+});
+
+MochiKit.Selector.__new__();
+
+MochiKit.Base._exportSymbols(this, MochiKit.Selector);
diff --git a/frontend/gamma/js/MochiKit/Signal.js b/frontend/gamma/js/MochiKit/Signal.js
new file mode 100644
index 0000000..7df5619
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Signal.js
@@ -0,0 +1,888 @@
+/***
+
+MochiKit.Signal 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2006 Jonathan Gardner, Beau Hartshorne, Bob Ippolito. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('Signal', '1.5', ['Base', 'DOM', 'Style']);
+
+MochiKit.Signal._observers = [];
+
+/** @id MochiKit.Signal.Event */
+MochiKit.Signal.Event = function (src, e) {
+ this._event = e || window.event;
+ this._src = src;
+};
+MochiKit.Signal.Event.__export__ = false;
+
+MochiKit.Base.update(MochiKit.Signal.Event.prototype, {
+
+ __repr__: function () {
+ var repr = MochiKit.Base.repr;
+ var str = '{event(): ' + repr(this.event()) +
+ ', src(): ' + repr(this.src()) +
+ ', type(): ' + repr(this.type()) +
+ ', target(): ' + repr(this.target());
+
+ if (this.type() &&
+ this.type().indexOf('key') === 0 ||
+ this.type().indexOf('mouse') === 0 ||
+ this.type().indexOf('click') != -1 ||
+ this.type() == 'contextmenu') {
+ str += ', modifier(): ' + '{alt: ' + repr(this.modifier().alt) +
+ ', ctrl: ' + repr(this.modifier().ctrl) +
+ ', meta: ' + repr(this.modifier().meta) +
+ ', shift: ' + repr(this.modifier().shift) +
+ ', any: ' + repr(this.modifier().any) + '}';
+ }
+
+ if (this.type() && this.type().indexOf('key') === 0) {
+ str += ', key(): {code: ' + repr(this.key().code) +
+ ', string: ' + repr(this.key().string) + '}';
+ }
+
+ if (this.type() && (
+ this.type().indexOf('mouse') === 0 ||
+ this.type().indexOf('click') != -1 ||
+ this.type() == 'contextmenu')) {
+
+ str += ', mouse(): {page: ' + repr(this.mouse().page) +
+ ', client: ' + repr(this.mouse().client);
+
+ if (this.type() != 'mousemove' && this.type() != 'mousewheel') {
+ str += ', button: {left: ' + repr(this.mouse().button.left) +
+ ', middle: ' + repr(this.mouse().button.middle) +
+ ', right: ' + repr(this.mouse().button.right) + '}';
+ }
+ if (this.type() == 'mousewheel') {
+ str += ', wheel: ' + repr(this.mouse().wheel);
+ }
+ str += '}';
+ }
+ if (this.type() == 'mouseover' || this.type() == 'mouseout' ||
+ this.type() == 'mouseenter' || this.type() == 'mouseleave') {
+ str += ', relatedTarget(): ' + repr(this.relatedTarget());
+ }
+ str += '}';
+ return str;
+ },
+
+ /** @id MochiKit.Signal.Event.prototype.toString */
+ toString: function () {
+ return this.__repr__();
+ },
+
+ /** @id MochiKit.Signal.Event.prototype.src */
+ src: function () {
+ return this._src;
+ },
+
+ /** @id MochiKit.Signal.Event.prototype.event */
+ event: function () {
+ return this._event;
+ },
+
+ /** @id MochiKit.Signal.Event.prototype.type */
+ type: function () {
+ if (this._event.type === "DOMMouseScroll") {
+ return "mousewheel";
+ } else {
+ return this._event.type || undefined;
+ }
+ },
+
+ /** @id MochiKit.Signal.Event.prototype.target */
+ target: function () {
+ return this._event.target || this._event.srcElement;
+ },
+
+ _relatedTarget: null,
+ /** @id MochiKit.Signal.Event.prototype.relatedTarget */
+ relatedTarget: function () {
+ if (this._relatedTarget !== null) {
+ return this._relatedTarget;
+ }
+
+ var elem = null;
+ if (this.type() == 'mouseover' || this.type() == 'mouseenter') {
+ elem = (this._event.relatedTarget ||
+ this._event.fromElement);
+ } else if (this.type() == 'mouseout' || this.type() == 'mouseleave') {
+ elem = (this._event.relatedTarget ||
+ this._event.toElement);
+ }
+ try {
+ if (elem !== null && elem.nodeType !== null) {
+ this._relatedTarget = elem;
+ return elem;
+ }
+ } catch (ignore) {
+ // Firefox 3 throws a permission denied error when accessing
+ // any property on XUL elements (e.g. scrollbars)...
+ }
+
+ return undefined;
+ },
+
+ _modifier: null,
+ /** @id MochiKit.Signal.Event.prototype.modifier */
+ modifier: function () {
+ if (this._modifier !== null) {
+ return this._modifier;
+ }
+ var m = {};
+ m.alt = this._event.altKey;
+ m.ctrl = this._event.ctrlKey;
+ m.meta = this._event.metaKey || false; // IE and Opera punt here
+ m.shift = this._event.shiftKey;
+ m.any = m.alt || m.ctrl || m.shift || m.meta;
+ this._modifier = m;
+ return m;
+ },
+
+ _key: null,
+ /** @id MochiKit.Signal.Event.prototype.key */
+ key: function () {
+ if (this._key !== null) {
+ return this._key;
+ }
+ var k = {};
+ if (this.type() && this.type().indexOf('key') === 0) {
+
+ /*
+
+ If you're looking for a special key, look for it in keydown or
+ keyup, but never keypress. If you're looking for a Unicode
+ chracter, look for it with keypress, but never keyup or
+ keydown.
+
+ Notes:
+
+ FF key event behavior:
+ key event charCode keyCode
+ DOWN ku,kd 0 40
+ DOWN kp 0 40
+ ESC ku,kd 0 27
+ ESC kp 0 27
+ a ku,kd 0 65
+ a kp 97 0
+ shift+a ku,kd 0 65
+ shift+a kp 65 0
+ 1 ku,kd 0 49
+ 1 kp 49 0
+ shift+1 ku,kd 0 0
+ shift+1 kp 33 0
+
+ IE key event behavior:
+ (IE doesn't fire keypress events for special keys.)
+ key event keyCode
+ DOWN ku,kd 40
+ DOWN kp undefined
+ ESC ku,kd 27
+ ESC kp 27
+ a ku,kd 65
+ a kp 97
+ shift+a ku,kd 65
+ shift+a kp 65
+ 1 ku,kd 49
+ 1 kp 49
+ shift+1 ku,kd 49
+ shift+1 kp 33
+
+ Safari key event behavior:
+ (Safari sets charCode and keyCode to something crazy for
+ special keys.)
+ key event charCode keyCode
+ DOWN ku,kd 63233 40
+ DOWN kp 63233 63233
+ ESC ku,kd 27 27
+ ESC kp 27 27
+ a ku,kd 97 65
+ a kp 97 97
+ shift+a ku,kd 65 65
+ shift+a kp 65 65
+ 1 ku,kd 49 49
+ 1 kp 49 49
+ shift+1 ku,kd 33 49
+ shift+1 kp 33 33
+
+ */
+
+ /* look for special keys here */
+ if (this.type() == 'keydown' || this.type() == 'keyup') {
+ k.code = this._event.keyCode;
+ k.string = (MochiKit.Signal._specialKeys[k.code] ||
+ 'KEY_UNKNOWN');
+ this._key = k;
+ return k;
+
+ /* look for characters here */
+ } else if (this.type() == 'keypress') {
+
+ /*
+
+ Special key behavior:
+
+ IE: does not fire keypress events for special keys
+ FF: sets charCode to 0, and sets the correct keyCode
+ Safari: sets keyCode and charCode to something stupid
+
+ */
+
+ k.code = 0;
+ k.string = '';
+
+ if (typeof(this._event.charCode) != 'undefined' &&
+ this._event.charCode !== 0 &&
+ !MochiKit.Signal._specialMacKeys[this._event.charCode]) {
+ k.code = this._event.charCode;
+ k.string = String.fromCharCode(k.code);
+ } else if (this._event.keyCode &&
+ typeof(this._event.charCode) == 'undefined') { // IE
+ k.code = this._event.keyCode;
+ k.string = String.fromCharCode(k.code);
+ }
+
+ this._key = k;
+ return k;
+ }
+ }
+ return undefined;
+ },
+
+ _mouse: null,
+ /** @id MochiKit.Signal.Event.prototype.mouse */
+ mouse: function () {
+ if (this._mouse !== null) {
+ return this._mouse;
+ }
+
+ var m = {};
+ var e = this._event;
+
+ if (this.type() && (
+ this.type().indexOf('mouse') === 0 ||
+ this.type().indexOf('click') != -1 ||
+ this.type() == 'contextmenu')) {
+
+ m.client = new MochiKit.Style.Coordinates(0, 0);
+ if (e.clientX || e.clientY) {
+ m.client.x = (!e.clientX || e.clientX < 0) ? 0 : e.clientX;
+ m.client.y = (!e.clientY || e.clientY < 0) ? 0 : e.clientY;
+ }
+
+ m.page = new MochiKit.Style.Coordinates(0, 0);
+ if (e.pageX || e.pageY) {
+ m.page.x = (!e.pageX || e.pageX < 0) ? 0 : e.pageX;
+ m.page.y = (!e.pageY || e.pageY < 0) ? 0 : e.pageY;
+ } else {
+ /*
+
+ The IE shortcut can be off by two. We fix it. See:
+ http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp
+
+ This is similar to the method used in
+ MochiKit.Style.getElementPosition().
+
+ */
+ var de = MochiKit.DOM._document.documentElement;
+ var b = MochiKit.DOM._document.body;
+
+ m.page.x = e.clientX +
+ (de.scrollLeft || b.scrollLeft) -
+ (de.clientLeft || 0);
+
+ m.page.y = e.clientY +
+ (de.scrollTop || b.scrollTop) -
+ (de.clientTop || 0);
+
+ }
+ if (this.type() != 'mousemove' && this.type() != 'mousewheel') {
+ m.button = {};
+ m.button.left = false;
+ m.button.right = false;
+ m.button.middle = false;
+
+ /* we could check e.button, but which is more consistent */
+ if (e.which) {
+ m.button.left = (e.which == 1);
+ m.button.middle = (e.which == 2);
+ m.button.right = (e.which == 3);
+
+ /*
+
+ Mac browsers and right click:
+
+ - Safari doesn't fire any click events on a right
+ click:
+ http://bugs.webkit.org/show_bug.cgi?id=6595
+
+ - Firefox fires the event, and sets ctrlKey = true
+
+ - Opera fires the event, and sets metaKey = true
+
+ oncontextmenu is fired on right clicks between
+ browsers and across platforms.
+
+ */
+
+ } else {
+ m.button.left = !!(e.button & 1);
+ m.button.right = !!(e.button & 2);
+ m.button.middle = !!(e.button & 4);
+ }
+ }
+ if (this.type() == 'mousewheel') {
+ m.wheel = new MochiKit.Style.Coordinates(0, 0);
+ if (e.wheelDeltaX || e.wheelDeltaY) {
+ m.wheel.x = e.wheelDeltaX / -40 || 0;
+ m.wheel.y = e.wheelDeltaY / -40 || 0;
+ } else if (e.wheelDelta) {
+ m.wheel.y = e.wheelDelta / -40;
+ } else {
+ m.wheel.y = e.detail || 0;
+ }
+ }
+ this._mouse = m;
+ return m;
+ }
+ return undefined;
+ },
+
+ /** @id MochiKit.Signal.Event.prototype.stop */
+ stop: function () {
+ this.stopPropagation();
+ this.preventDefault();
+ },
+
+ /** @id MochiKit.Signal.Event.prototype.stopPropagation */
+ stopPropagation: function () {
+ if (this._event.stopPropagation) {
+ this._event.stopPropagation();
+ } else {
+ this._event.cancelBubble = true;
+ }
+ },
+
+ /** @id MochiKit.Signal.Event.prototype.preventDefault */
+ preventDefault: function () {
+ if (this._event.preventDefault) {
+ this._event.preventDefault();
+ } else if (this._confirmUnload === null) {
+ this._event.returnValue = false;
+ }
+ },
+
+ _confirmUnload: null,
+
+ /** @id MochiKit.Signal.Event.prototype.confirmUnload */
+ confirmUnload: function (msg) {
+ if (this.type() == 'beforeunload') {
+ this._confirmUnload = msg;
+ this._event.returnValue = msg;
+ }
+ }
+});
+
+/* Safari sets keyCode to these special values onkeypress. */
+MochiKit.Signal._specialMacKeys = {
+ 3: 'KEY_ENTER',
+ 63289: 'KEY_NUM_PAD_CLEAR',
+ 63276: 'KEY_PAGE_UP',
+ 63277: 'KEY_PAGE_DOWN',
+ 63275: 'KEY_END',
+ 63273: 'KEY_HOME',
+ 63234: 'KEY_ARROW_LEFT',
+ 63232: 'KEY_ARROW_UP',
+ 63235: 'KEY_ARROW_RIGHT',
+ 63233: 'KEY_ARROW_DOWN',
+ 63302: 'KEY_INSERT',
+ 63272: 'KEY_DELETE'
+};
+
+/* for KEY_F1 - KEY_F12 */
+(function () {
+ var _specialMacKeys = MochiKit.Signal._specialMacKeys;
+ for (var i = 63236; i <= 63242; i++) {
+ // no F0
+ _specialMacKeys[i] = 'KEY_F' + (i - 63236 + 1);
+ }
+})();
+
+/* Standard keyboard key codes. */
+MochiKit.Signal._specialKeys = {
+ 8: 'KEY_BACKSPACE',
+ 9: 'KEY_TAB',
+ 12: 'KEY_NUM_PAD_CLEAR', // weird, for Safari and Mac FF only
+ 13: 'KEY_ENTER',
+ 16: 'KEY_SHIFT',
+ 17: 'KEY_CTRL',
+ 18: 'KEY_ALT',
+ 19: 'KEY_PAUSE',
+ 20: 'KEY_CAPS_LOCK',
+ 27: 'KEY_ESCAPE',
+ 32: 'KEY_SPACEBAR',
+ 33: 'KEY_PAGE_UP',
+ 34: 'KEY_PAGE_DOWN',
+ 35: 'KEY_END',
+ 36: 'KEY_HOME',
+ 37: 'KEY_ARROW_LEFT',
+ 38: 'KEY_ARROW_UP',
+ 39: 'KEY_ARROW_RIGHT',
+ 40: 'KEY_ARROW_DOWN',
+ 44: 'KEY_PRINT_SCREEN',
+ 45: 'KEY_INSERT',
+ 46: 'KEY_DELETE',
+ 59: 'KEY_SEMICOLON', // weird, for Safari and IE only
+ 91: 'KEY_WINDOWS_LEFT',
+ 92: 'KEY_WINDOWS_RIGHT',
+ 93: 'KEY_SELECT',
+ 106: 'KEY_NUM_PAD_ASTERISK',
+ 107: 'KEY_NUM_PAD_PLUS_SIGN',
+ 109: 'KEY_NUM_PAD_HYPHEN-MINUS',
+ 110: 'KEY_NUM_PAD_FULL_STOP',
+ 111: 'KEY_NUM_PAD_SOLIDUS',
+ 144: 'KEY_NUM_LOCK',
+ 145: 'KEY_SCROLL_LOCK',
+ 186: 'KEY_SEMICOLON',
+ 187: 'KEY_EQUALS_SIGN',
+ 188: 'KEY_COMMA',
+ 189: 'KEY_HYPHEN-MINUS',
+ 190: 'KEY_FULL_STOP',
+ 191: 'KEY_SOLIDUS',
+ 192: 'KEY_GRAVE_ACCENT',
+ 219: 'KEY_LEFT_SQUARE_BRACKET',
+ 220: 'KEY_REVERSE_SOLIDUS',
+ 221: 'KEY_RIGHT_SQUARE_BRACKET',
+ 222: 'KEY_APOSTROPHE'
+ // undefined: 'KEY_UNKNOWN'
+};
+
+(function () {
+ /* for KEY_0 - KEY_9 */
+ var _specialKeys = MochiKit.Signal._specialKeys;
+ for (var i = 48; i <= 57; i++) {
+ _specialKeys[i] = 'KEY_' + (i - 48);
+ }
+
+ /* for KEY_A - KEY_Z */
+ for (i = 65; i <= 90; i++) {
+ _specialKeys[i] = 'KEY_' + String.fromCharCode(i);
+ }
+
+ /* for KEY_NUM_PAD_0 - KEY_NUM_PAD_9 */
+ for (i = 96; i <= 105; i++) {
+ _specialKeys[i] = 'KEY_NUM_PAD_' + (i - 96);
+ }
+
+ /* for KEY_F1 - KEY_F12 */
+ for (i = 112; i <= 123; i++) {
+ // no F0
+ _specialKeys[i] = 'KEY_F' + (i - 112 + 1);
+ }
+})();
+
+/* Internal object to keep track of created signals. */
+MochiKit.Signal.Ident = function (ident) {
+ this.source = ident.source;
+ this.signal = ident.signal;
+ this.listener = ident.listener;
+ this.isDOM = ident.isDOM;
+ this.objOrFunc = ident.objOrFunc;
+ this.funcOrStr = ident.funcOrStr;
+ this.connected = ident.connected;
+};
+MochiKit.Signal.Ident.__export__ = false;
+MochiKit.Signal.Ident.prototype = {};
+
+MochiKit.Base.update(MochiKit.Signal, {
+
+ _unloadCache: function () {
+ var self = MochiKit.Signal;
+ var observers = self._observers;
+
+ for (var i = 0; i < observers.length; i++) {
+ if (observers[i].signal !== 'onload' && observers[i].signal !== 'onunload') {
+ self._disconnect(observers[i]);
+ }
+ }
+ },
+
+ _listener: function (src, sig, func, obj, isDOM) {
+ var self = MochiKit.Signal;
+ var E = self.Event;
+ if (!isDOM) {
+ /* We don't want to re-bind already bound methods */
+ if (typeof(func.im_self) == 'undefined') {
+ return MochiKit.Base.bindLate(func, obj);
+ } else {
+ return func;
+ }
+ }
+ obj = obj || src;
+ if (typeof(func) == "string") {
+ if (sig === 'onload' || sig === 'onunload') {
+ return function (nativeEvent) {
+ obj[func].apply(obj, [new E(src, nativeEvent)]);
+
+ var ident = new MochiKit.Signal.Ident({
+ source: src, signal: sig, objOrFunc: obj, funcOrStr: func});
+
+ MochiKit.Signal._disconnect(ident);
+ };
+ } else {
+ return function (nativeEvent) {
+ obj[func].apply(obj, [new E(src, nativeEvent)]);
+ };
+ }
+ } else {
+ if (sig === 'onload' || sig === 'onunload') {
+ return function (nativeEvent) {
+ func.apply(obj, [new E(src, nativeEvent)]);
+
+ var ident = new MochiKit.Signal.Ident({
+ source: src, signal: sig, objOrFunc: func});
+
+ MochiKit.Signal._disconnect(ident);
+ };
+ } else {
+ return function (nativeEvent) {
+ func.apply(obj, [new E(src, nativeEvent)]);
+ };
+ }
+ }
+ },
+
+ _browserAlreadyHasMouseEnterAndLeave: function () {
+ return /MSIE/.test(navigator.userAgent);
+ },
+
+ _browserLacksMouseWheelEvent: function () {
+ return /Gecko\//.test(navigator.userAgent);
+ },
+
+ _mouseEnterListener: function (src, sig, func, obj) {
+ var E = MochiKit.Signal.Event;
+ return function (nativeEvent) {
+ var e = new E(src, nativeEvent);
+ try {
+ e.relatedTarget().nodeName;
+ } catch (err) {
+ /* probably hit a permission denied error; possibly one of
+ * firefox's screwy anonymous DIVs inside an input element.
+ * Allow this event to propogate up.
+ */
+ return;
+ }
+ e.stop();
+ if (MochiKit.DOM.isChildNode(e.relatedTarget(), src)) {
+ /* We've moved between our node and a child. Ignore. */
+ return;
+ }
+ e.type = function () { return sig; };
+ if (typeof(func) == "string") {
+ return obj[func].apply(obj, [e]);
+ } else {
+ return func.apply(obj, [e]);
+ }
+ };
+ },
+
+ _getDestPair: function (objOrFunc, funcOrStr) {
+ var obj = null;
+ var func = null;
+ if (typeof(funcOrStr) != 'undefined') {
+ obj = objOrFunc;
+ func = funcOrStr;
+ if (typeof(funcOrStr) == 'string') {
+ if (typeof(objOrFunc[funcOrStr]) != "function") {
+ throw new Error("'funcOrStr' must be a function on 'objOrFunc'");
+ }
+ } else if (typeof(funcOrStr) != 'function') {
+ throw new Error("'funcOrStr' must be a function or string");
+ }
+ } else if (typeof(objOrFunc) != "function") {
+ throw new Error("'objOrFunc' must be a function if 'funcOrStr' is not given");
+ } else {
+ func = objOrFunc;
+ }
+ return [obj, func];
+ },
+
+ /** @id MochiKit.Signal.connect */
+ connect: function (src, sig, objOrFunc/* optional */, funcOrStr) {
+ if (typeof(src) == "string") {
+ src = MochiKit.DOM.getElement(src);
+ }
+ var self = MochiKit.Signal;
+
+ if (typeof(sig) != 'string') {
+ throw new Error("'sig' must be a string");
+ }
+
+ var destPair = self._getDestPair(objOrFunc, funcOrStr);
+ var obj = destPair[0];
+ var func = destPair[1];
+ if (typeof(obj) == 'undefined' || obj === null) {
+ obj = src;
+ }
+
+ var isDOM = !!(src.addEventListener || src.attachEvent);
+ if (isDOM && (sig === "onmouseenter" || sig === "onmouseleave")
+ && !self._browserAlreadyHasMouseEnterAndLeave()) {
+ var listener = self._mouseEnterListener(src, sig.substr(2), func, obj);
+ if (sig === "onmouseenter") {
+ sig = "onmouseover";
+ } else {
+ sig = "onmouseout";
+ }
+ } else if (isDOM && sig == "onmousewheel" && self._browserLacksMouseWheelEvent()) {
+ var listener = self._listener(src, sig, func, obj, isDOM);
+ sig = "onDOMMouseScroll";
+ } else {
+ var listener = self._listener(src, sig, func, obj, isDOM);
+ }
+
+ if (src.addEventListener) {
+ src.addEventListener(sig.substr(2), listener, false);
+ } else if (src.attachEvent) {
+ src.attachEvent(sig, listener); // useCapture unsupported
+ }
+
+ var ident = new MochiKit.Signal.Ident({
+ source: src,
+ signal: sig,
+ listener: listener,
+ isDOM: isDOM,
+ objOrFunc: objOrFunc,
+ funcOrStr: funcOrStr,
+ connected: true
+ });
+ self._observers.push(ident);
+
+ if (!isDOM && typeof(src.__connect__) == 'function') {
+ var args = MochiKit.Base.extend([ident], arguments, 1);
+ src.__connect__.apply(src, args);
+ }
+
+ return ident;
+ },
+
+ _disconnect: function (ident) {
+ // already disconnected
+ if (!ident.connected) {
+ return;
+ }
+ ident.connected = false;
+ var src = ident.source;
+ var sig = ident.signal;
+ var listener = ident.listener;
+ // check isDOM
+ if (!ident.isDOM) {
+ if (typeof(src.__disconnect__) == 'function') {
+ src.__disconnect__(ident, sig, ident.objOrFunc, ident.funcOrStr);
+ }
+ return;
+ }
+ if (src.removeEventListener) {
+ src.removeEventListener(sig.substr(2), listener, false);
+ } else if (src.detachEvent) {
+ src.detachEvent(sig, listener); // useCapture unsupported
+ } else {
+ throw new Error("'src' must be a DOM element");
+ }
+ },
+
+ /** @id MochiKit.Signal.disconnect */
+ disconnect: function (ident) {
+ var self = MochiKit.Signal;
+ var observers = self._observers;
+ var m = MochiKit.Base;
+ if (arguments.length > 1) {
+ // compatibility API
+ var src = arguments[0];
+ if (typeof(src) == "string") {
+ src = MochiKit.DOM.getElement(src);
+ }
+ var sig = arguments[1];
+ var obj = arguments[2];
+ var func = arguments[3];
+ for (var i = observers.length - 1; i >= 0; i--) {
+ var o = observers[i];
+ if (o.source === src && o.signal === sig && o.objOrFunc === obj && o.funcOrStr === func) {
+ self._disconnect(o);
+ if (!self._lock) {
+ observers.splice(i, 1);
+ } else {
+ self._dirty = true;
+ }
+ return true;
+ }
+ }
+ } else {
+ var idx = m.findIdentical(observers, ident);
+ if (idx >= 0) {
+ self._disconnect(ident);
+ if (!self._lock) {
+ observers.splice(idx, 1);
+ } else {
+ self._dirty = true;
+ }
+ return true;
+ }
+ }
+ return false;
+ },
+
+ /** @id MochiKit.Signal.disconnectAllTo */
+ disconnectAllTo: function (objOrFunc, /* optional */funcOrStr) {
+ var self = MochiKit.Signal;
+ var observers = self._observers;
+ var disconnect = self._disconnect;
+ var locked = self._lock;
+ var dirty = self._dirty;
+ if (typeof(funcOrStr) === 'undefined') {
+ funcOrStr = null;
+ }
+ for (var i = observers.length - 1; i >= 0; i--) {
+ var ident = observers[i];
+ if (ident.objOrFunc === objOrFunc &&
+ (funcOrStr === null || ident.funcOrStr === funcOrStr)) {
+ disconnect(ident);
+ if (locked) {
+ dirty = true;
+ } else {
+ observers.splice(i, 1);
+ }
+ }
+ }
+ self._dirty = dirty;
+ },
+
+ /** @id MochiKit.Signal.disconnectAll */
+ disconnectAll: function (src/* optional */, sig) {
+ if (typeof(src) == "string") {
+ src = MochiKit.DOM.getElement(src);
+ }
+ var m = MochiKit.Base;
+ var signals = m.flattenArguments(m.extend(null, arguments, 1));
+ var self = MochiKit.Signal;
+ var disconnect = self._disconnect;
+ var observers = self._observers;
+ var i, ident;
+ var locked = self._lock;
+ var dirty = self._dirty;
+ if (signals.length === 0) {
+ // disconnect all
+ for (i = observers.length - 1; i >= 0; i--) {
+ ident = observers[i];
+ if (ident.source === src) {
+ disconnect(ident);
+ if (!locked) {
+ observers.splice(i, 1);
+ } else {
+ dirty = true;
+ }
+ }
+ }
+ } else {
+ var sigs = {};
+ for (i = 0; i < signals.length; i++) {
+ sigs[signals[i]] = true;
+ }
+ for (i = observers.length - 1; i >= 0; i--) {
+ ident = observers[i];
+ if (ident.source === src && ident.signal in sigs) {
+ disconnect(ident);
+ if (!locked) {
+ observers.splice(i, 1);
+ } else {
+ dirty = true;
+ }
+ }
+ }
+ }
+ self._dirty = dirty;
+ },
+
+ /** @id MochiKit.Signal.signal */
+ signal: function (src, sig) {
+ var self = MochiKit.Signal;
+ var observers = self._observers;
+ if (typeof(src) == "string") {
+ src = MochiKit.DOM.getElement(src);
+ }
+ var args = MochiKit.Base.extend(null, arguments, 2);
+ var errors = [];
+ self._lock = true;
+ for (var i = 0; i < observers.length; i++) {
+ var ident = observers[i];
+ if (ident.source === src && ident.signal === sig &&
+ ident.connected) {
+ try {
+ if (ident.isDOM && ident.funcOrStr != null) {
+ var obj = ident.objOrFunc;
+ obj[ident.funcOrStr].apply(obj, args);
+ } else if (ident.isDOM) {
+ ident.objOrFunc.apply(src, args);
+ } else {
+ ident.listener.apply(src, args);
+ }
+ } catch (e) {
+ errors.push(e);
+ }
+ }
+ }
+ self._lock = false;
+ if (self._dirty) {
+ self._dirty = false;
+ for (var i = observers.length - 1; i >= 0; i--) {
+ if (!observers[i].connected) {
+ observers.splice(i, 1);
+ }
+ }
+ }
+ if (errors.length == 1) {
+ throw errors[0];
+ } else if (errors.length > 1) {
+ var e = new Error("Multiple errors thrown in handling 'sig', see errors property");
+ e.errors = errors;
+ throw e;
+ }
+ }
+
+});
+
+MochiKit.Signal.__new__ = function (win) {
+ var m = MochiKit.Base;
+ this._document = document;
+ this._window = win;
+ this._lock = false;
+ this._dirty = false;
+
+ try {
+ this.connect(window, 'onunload', this._unloadCache);
+ } catch (e) {
+ // pass: might not be a browser
+ }
+
+ m.nameFunctions(this);
+};
+
+MochiKit.Signal.__new__(this);
+
+//
+// XXX: Internet Explorer blows
+//
+if (MochiKit.__export__) {
+ connect = MochiKit.Signal.connect;
+ disconnect = MochiKit.Signal.disconnect;
+ disconnectAll = MochiKit.Signal.disconnectAll;
+ signal = MochiKit.Signal.signal;
+}
+
+MochiKit.Base._exportSymbols(this, MochiKit.Signal);
diff --git a/frontend/gamma/js/MochiKit/Sortable.js b/frontend/gamma/js/MochiKit/Sortable.js
new file mode 100644
index 0000000..863b506
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Sortable.js
@@ -0,0 +1,569 @@
+/***
+Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
+ Mochi-ized By Thomas Herve (_firstname_@nimail.org)
+
+See scriptaculous.js for full license.
+
+***/
+
+MochiKit.Base._module('Sortable', '1.5', ['Base', 'Iter', 'DOM', 'Position', 'DragAndDrop']);
+
+MochiKit.Base.update(MochiKit.Sortable, {
+ __export__: false,
+
+ /***
+
+ Manage sortables. Mainly use the create function to add a sortable.
+
+ ***/
+ sortables: {},
+
+ _findRootElement: function (element) {
+ while (element.tagName.toUpperCase() != "BODY") {
+ if (element.id && MochiKit.Sortable.sortables[element.id]) {
+ return element;
+ }
+ element = element.parentNode;
+ }
+ },
+
+ _createElementId: function(element) {
+ if (element.id == null || element.id == "") {
+ var d = MochiKit.DOM;
+ var id;
+ var count = 1;
+ while (d.getElement(id = "sortable" + count) != null) {
+ count += 1;
+ }
+ d.setNodeAttribute(element, "id", id);
+ }
+ },
+
+ /** @id MochiKit.Sortable.options */
+ options: function (element) {
+ element = MochiKit.Sortable._findRootElement(MochiKit.DOM.getElement(element));
+ if (!element) {
+ return;
+ }
+ return MochiKit.Sortable.sortables[element.id];
+ },
+
+ /** @id MochiKit.Sortable.destroy */
+ destroy: function (element){
+ var s = MochiKit.Sortable.options(element);
+ var b = MochiKit.Base;
+ var d = MochiKit.DragAndDrop;
+
+ if (s) {
+ MochiKit.Signal.disconnect(s.startHandle);
+ MochiKit.Signal.disconnect(s.endHandle);
+ b.map(function (dr) {
+ d.Droppables.remove(dr);
+ }, s.droppables);
+ b.map(function (dr) {
+ dr.destroy();
+ }, s.draggables);
+
+ delete MochiKit.Sortable.sortables[s.element.id];
+ }
+ },
+
+ /** @id MochiKit.Sortable.create */
+ create: function (element, options) {
+ element = MochiKit.DOM.getElement(element);
+ var self = MochiKit.Sortable;
+ self._createElementId(element);
+
+ /** @id MochiKit.Sortable.options */
+ options = MochiKit.Base.update({
+
+ /** @id MochiKit.Sortable.element */
+ element: element,
+
+ /** @id MochiKit.Sortable.tag */
+ tag: 'li', // assumes li children, override with tag: 'tagname'
+
+ /** @id MochiKit.Sortable.dropOnEmpty */
+ dropOnEmpty: false,
+
+ /** @id MochiKit.Sortable.tree */
+ tree: false,
+
+ /** @id MochiKit.Sortable.treeTag */
+ treeTag: 'ul',
+
+ /** @id MochiKit.Sortable.overlap */
+ overlap: 'vertical', // one of 'vertical', 'horizontal'
+
+ /** @id MochiKit.Sortable.constraint */
+ constraint: 'vertical', // one of 'vertical', 'horizontal', false
+ // also takes array of elements (or ids); or false
+
+ /** @id MochiKit.Sortable.containment */
+ containment: [element],
+
+ /** @id MochiKit.Sortable.handle */
+ handle: false, // or a CSS class
+
+ /** @id MochiKit.Sortable.only */
+ only: false,
+
+ /** @id MochiKit.Sortable.hoverclass */
+ hoverclass: null,
+
+ /** @id MochiKit.Sortable.ghosting */
+ ghosting: false,
+
+ /** @id MochiKit.Sortable.scroll */
+ scroll: false,
+
+ /** @id MochiKit.Sortable.scrollSensitivity */
+ scrollSensitivity: 20,
+
+ /** @id MochiKit.Sortable.scrollSpeed */
+ scrollSpeed: 15,
+
+ /** @id MochiKit.Sortable.format */
+ format: /^[^_]*_(.*)$/,
+
+ /** @id MochiKit.Sortable.onChange */
+ onChange: MochiKit.Base.noop,
+
+ /** @id MochiKit.Sortable.onUpdate */
+ onUpdate: MochiKit.Base.noop,
+
+ /** @id MochiKit.Sortable.accept */
+ accept: null
+ }, options);
+
+ // clear any old sortable with same element
+ self.destroy(element);
+
+ // build options for the draggables
+ var options_for_draggable = {
+ revert: true,
+ ghosting: options.ghosting,
+ scroll: options.scroll,
+ scrollSensitivity: options.scrollSensitivity,
+ scrollSpeed: options.scrollSpeed,
+ constraint: options.constraint,
+ handle: options.handle
+ };
+
+ if (options.starteffect) {
+ options_for_draggable.starteffect = options.starteffect;
+ }
+
+ if (options.reverteffect) {
+ options_for_draggable.reverteffect = options.reverteffect;
+ } else if (options.ghosting) {
+ options_for_draggable.reverteffect = function (innerelement) {
+ innerelement.style.top = 0;
+ innerelement.style.left = 0;
+ };
+ }
+
+ if (options.endeffect) {
+ options_for_draggable.endeffect = options.endeffect;
+ }
+
+ if (options.zindex) {
+ options_for_draggable.zindex = options.zindex;
+ }
+
+ // build options for the droppables
+ var options_for_droppable = {
+ overlap: options.overlap,
+ containment: options.containment,
+ hoverclass: options.hoverclass,
+ onhover: self.onHover,
+ tree: options.tree,
+ accept: options.accept
+ }
+
+ var options_for_tree = {
+ onhover: self.onEmptyHover,
+ overlap: options.overlap,
+ containment: options.containment,
+ hoverclass: options.hoverclass,
+ accept: options.accept
+ }
+
+ // fix for gecko engine
+ MochiKit.DOM.removeEmptyTextNodes(element);
+
+ options.draggables = [];
+ options.droppables = [];
+
+ // drop on empty handling
+ if (options.dropOnEmpty || options.tree) {
+ new MochiKit.DragAndDrop.Droppable(element, options_for_tree);
+ options.droppables.push(element);
+ }
+ MochiKit.Base.map(function (e) {
+ // handles are per-draggable
+ var handle = options.handle ?
+ MochiKit.DOM.getFirstElementByTagAndClassName(null,
+ options.handle, e) : e;
+ options.draggables.push(
+ new MochiKit.DragAndDrop.Draggable(e,
+ MochiKit.Base.update(options_for_draggable,
+ {handle: handle})));
+ new MochiKit.DragAndDrop.Droppable(e, options_for_droppable);
+ if (options.tree) {
+ e.treeNode = element;
+ }
+ options.droppables.push(e);
+ }, (self.findElements(element, options) || []));
+
+ if (options.tree) {
+ MochiKit.Base.map(function (e) {
+ new MochiKit.DragAndDrop.Droppable(e, options_for_tree);
+ e.treeNode = element;
+ options.droppables.push(e);
+ }, (self.findTreeElements(element, options) || []));
+ }
+
+ // keep reference
+ self.sortables[element.id] = options;
+
+ options.lastValue = self.serialize(element);
+ options.startHandle = MochiKit.Signal.connect(MochiKit.DragAndDrop.Draggables, 'start',
+ MochiKit.Base.partial(self.onStart, element));
+ options.endHandle = MochiKit.Signal.connect(MochiKit.DragAndDrop.Draggables, 'end',
+ MochiKit.Base.partial(self.onEnd, element));
+ },
+
+ /** @id MochiKit.Sortable.onStart */
+ onStart: function (element, draggable) {
+ var self = MochiKit.Sortable;
+ var options = self.options(element);
+ options.lastValue = self.serialize(options.element);
+ },
+
+ /** @id MochiKit.Sortable.onEnd */
+ onEnd: function (element, draggable) {
+ var self = MochiKit.Sortable;
+ self.unmark();
+ var options = self.options(element);
+ if (options.lastValue != self.serialize(options.element)) {
+ options.onUpdate(options.element);
+ }
+ },
+
+ // return all suitable-for-sortable elements in a guaranteed order
+
+ /** @id MochiKit.Sortable.findElements */
+ findElements: function (element, options) {
+ return MochiKit.Sortable.findChildren(element, options.only, options.tree, options.tag);
+ },
+
+ /** @id MochiKit.Sortable.findTreeElements */
+ findTreeElements: function (element, options) {
+ return MochiKit.Sortable.findChildren(
+ element, options.only, options.tree ? true : false, options.treeTag);
+ },
+
+ /** @id MochiKit.Sortable.findChildren */
+ findChildren: function (element, only, recursive, tagName) {
+ if (!element.hasChildNodes()) {
+ return null;
+ }
+ tagName = tagName.toUpperCase();
+ if (only) {
+ only = MochiKit.Base.flattenArray([only]);
+ }
+ var elements = [];
+ MochiKit.Base.map(function (e) {
+ if (e.tagName &&
+ e.tagName.toUpperCase() == tagName &&
+ (!only ||
+ MochiKit.Iter.some(only, function (c) {
+ return MochiKit.DOM.hasElementClass(e, c);
+ }))) {
+ elements.push(e);
+ }
+ if (recursive) {
+ var grandchildren = MochiKit.Sortable.findChildren(e, only, recursive, tagName);
+ if (grandchildren && grandchildren.length > 0) {
+ elements = elements.concat(grandchildren);
+ }
+ }
+ }, element.childNodes);
+ return elements;
+ },
+
+ /** @id MochiKit.Sortable.onHover */
+ onHover: function (element, dropon, overlap) {
+ if (MochiKit.DOM.isChildNode(dropon, element)) {
+ return;
+ }
+ var self = MochiKit.Sortable;
+
+ if (overlap > .33 && overlap < .66 && self.options(dropon).tree) {
+ return;
+ } else if (overlap > 0.5) {
+ self.mark(dropon, 'before');
+ if (dropon.previousSibling != element) {
+ var oldParentNode = element.parentNode;
+ element.style.visibility = 'hidden'; // fix gecko rendering
+ dropon.parentNode.insertBefore(element, dropon);
+ if (dropon.parentNode != oldParentNode) {
+ self.options(oldParentNode).onChange(element);
+ }
+ self.options(dropon.parentNode).onChange(element);
+ }
+ } else {
+ self.mark(dropon, 'after');
+ var nextElement = dropon.nextSibling || null;
+ if (nextElement != element) {
+ var oldParentNode = element.parentNode;
+ element.style.visibility = 'hidden'; // fix gecko rendering
+ dropon.parentNode.insertBefore(element, nextElement);
+ if (dropon.parentNode != oldParentNode) {
+ self.options(oldParentNode).onChange(element);
+ }
+ self.options(dropon.parentNode).onChange(element);
+ }
+ }
+ },
+
+ _offsetSize: function (element, type) {
+ if (type == 'vertical' || type == 'height') {
+ return element.offsetHeight;
+ } else {
+ return element.offsetWidth;
+ }
+ },
+
+ /** @id MochiKit.Sortable.onEmptyHover */
+ onEmptyHover: function (element, dropon, overlap) {
+ var oldParentNode = element.parentNode;
+ var self = MochiKit.Sortable;
+ var droponOptions = self.options(dropon);
+
+ if (!MochiKit.DOM.isChildNode(dropon, element)) {
+ var index;
+
+ var children = self.findElements(dropon, {tag: droponOptions.tag,
+ only: droponOptions.only});
+ var child = null;
+
+ if (children) {
+ var offset = self._offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
+
+ for (index = 0; index < children.length; index += 1) {
+ if (offset - self._offsetSize(children[index], droponOptions.overlap) >= 0) {
+ offset -= self._offsetSize(children[index], droponOptions.overlap);
+ } else if (offset - (self._offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
+ child = index + 1 < children.length ? children[index + 1] : null;
+ break;
+ } else {
+ child = children[index];
+ break;
+ }
+ }
+ }
+
+ dropon.insertBefore(element, child);
+
+ self.options(oldParentNode).onChange(element);
+ droponOptions.onChange(element);
+ }
+ },
+
+ /** @id MochiKit.Sortable.unmark */
+ unmark: function () {
+ var m = MochiKit.Sortable._marker;
+ if (m) {
+ MochiKit.Style.hideElement(m);
+ }
+ },
+
+ /** @id MochiKit.Sortable.mark */
+ mark: function (dropon, position) {
+ // mark on ghosting only
+ var d = MochiKit.DOM;
+ var self = MochiKit.Sortable;
+ var sortable = self.options(dropon.parentNode);
+ if (sortable && !sortable.ghosting) {
+ return;
+ }
+
+ if (!self._marker) {
+ self._marker = d.getElement('dropmarker') ||
+ document.createElement('DIV');
+ MochiKit.Style.hideElement(self._marker);
+ d.addElementClass(self._marker, 'dropmarker');
+ self._marker.style.position = 'absolute';
+ document.getElementsByTagName('body').item(0).appendChild(self._marker);
+ }
+ var offsets = MochiKit.Position.cumulativeOffset(dropon);
+ self._marker.style.left = offsets.x + 'px';
+ self._marker.style.top = offsets.y + 'px';
+
+ if (position == 'after') {
+ if (sortable.overlap == 'horizontal') {
+ self._marker.style.left = (offsets.x + dropon.clientWidth) + 'px';
+ } else {
+ self._marker.style.top = (offsets.y + dropon.clientHeight) + 'px';
+ }
+ }
+ MochiKit.Style.showElement(self._marker);
+ },
+
+ _tree: function (element, options, parent) {
+ var self = MochiKit.Sortable;
+ var children = self.findElements(element, options) || [];
+
+ for (var i = 0; i < children.length; ++i) {
+ var match = children[i].id.match(options.format);
+
+ if (!match) {
+ continue;
+ }
+
+ var child = {
+ id: encodeURIComponent(match ? match[1] : null),
+ element: element,
+ parent: parent,
+ children: [],
+ position: parent.children.length,
+ container: self._findChildrenElement(children[i], options.treeTag.toUpperCase())
+ }
+
+ /* Get the element containing the children and recurse over it */
+ if (child.container) {
+ self._tree(child.container, options, child)
+ }
+
+ parent.children.push (child);
+ }
+
+ return parent;
+ },
+
+ /* Finds the first element of the given tag type within a parent element.
+ Used for finding the first LI[ST] within a L[IST]I[TEM].*/
+ _findChildrenElement: function (element, containerTag) {
+ if (element && element.hasChildNodes) {
+ containerTag = containerTag.toUpperCase();
+ for (var i = 0; i < element.childNodes.length; ++i) {
+ if (element.childNodes[i].tagName.toUpperCase() == containerTag) {
+ return element.childNodes[i];
+ }
+ }
+ }
+ return null;
+ },
+
+ /** @id MochiKit.Sortable.tree */
+ tree: function (element, options) {
+ element = MochiKit.DOM.getElement(element);
+ var sortableOptions = MochiKit.Sortable.options(element);
+ options = MochiKit.Base.update({
+ tag: sortableOptions.tag,
+ treeTag: sortableOptions.treeTag,
+ only: sortableOptions.only,
+ name: element.id,
+ format: sortableOptions.format
+ }, options || {});
+
+ var root = {
+ id: null,
+ parent: null,
+ children: new Array,
+ container: element,
+ position: 0
+ }
+
+ return MochiKit.Sortable._tree(element, options, root);
+ },
+
+ /**
+ * Specifies the sequence for the Sortable.
+ * @param {Node} element Element to use as the Sortable.
+ * @param {Object} newSequence New sequence to use.
+ * @param {Object} options Options to use fro the Sortable.
+ */
+ setSequence: function (element, newSequence, options) {
+ var self = MochiKit.Sortable;
+ var b = MochiKit.Base;
+ element = MochiKit.DOM.getElement(element);
+ options = b.update(self.options(element), options || {});
+
+ var nodeMap = {};
+ b.map(function (n) {
+ var m = n.id.match(options.format);
+ if (m) {
+ nodeMap[m[1]] = [n, n.parentNode];
+ }
+ n.parentNode.removeChild(n);
+ }, self.findElements(element, options));
+
+ b.map(function (ident) {
+ var n = nodeMap[ident];
+ if (n) {
+ n[1].appendChild(n[0]);
+ delete nodeMap[ident];
+ }
+ }, newSequence);
+ },
+
+ /* Construct a [i] index for a particular node */
+ _constructIndex: function (node) {
+ var index = '';
+ do {
+ if (node.id) {
+ index = '[' + node.position + ']' + index;
+ }
+ } while ((node = node.parent) != null);
+ return index;
+ },
+
+ /** @id MochiKit.Sortable.sequence */
+ sequence: function (element, options) {
+ element = MochiKit.DOM.getElement(element);
+ var self = MochiKit.Sortable;
+ var options = MochiKit.Base.update(self.options(element), options || {});
+
+ return MochiKit.Base.map(function (item) {
+ return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
+ }, MochiKit.DOM.getElement(self.findElements(element, options) || []));
+ },
+
+ /**
+ * Serializes the content of a Sortable. Useful to send this content through a XMLHTTPRequest.
+ * These options override the Sortable options for the serialization only.
+ * @param {Node} element Element to serialize.
+ * @param {Object} options Serialization options.
+ */
+ serialize: function (element, options) {
+ element = MochiKit.DOM.getElement(element);
+ var self = MochiKit.Sortable;
+ options = MochiKit.Base.update(self.options(element), options || {});
+ var name = encodeURIComponent(options.name || element.id);
+
+ if (options.tree) {
+ return MochiKit.Base.flattenArray(MochiKit.Base.map(function (item) {
+ return [name + self._constructIndex(item) + "[id]=" +
+ encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
+ }, self.tree(element, options).children)).join('&');
+ } else {
+ return MochiKit.Base.map(function (item) {
+ return name + "[]=" + encodeURIComponent(item);
+ }, self.sequence(element, options)).join('&');
+ }
+ }
+});
+
+// trunk compatibility
+MochiKit.Sortable.Sortable = MochiKit.Sortable;
+
+MochiKit.Sortable.__new__ = function () {
+ MochiKit.Base.nameFunctions(this);
+};
+
+MochiKit.Sortable.__new__();
+
+MochiKit.Base._exportSymbols(this, MochiKit.Sortable);
diff --git a/frontend/gamma/js/MochiKit/Style.js b/frontend/gamma/js/MochiKit/Style.js
new file mode 100644
index 0000000..7f10117
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Style.js
@@ -0,0 +1,558 @@
+/***
+
+MochiKit.Style 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005-2006 Bob Ippolito, Beau Hartshorne. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('Style', '1.5', ['Base', 'DOM']);
+
+
+/** @id MochiKit.Style.Dimensions */
+MochiKit.Style.Dimensions = function (w, h) {
+ if (!(this instanceof MochiKit.Style.Dimensions)) {
+ return new MochiKit.Style.Dimensions(w, h);
+ }
+ this.w = w;
+ this.h = h;
+};
+
+MochiKit.Style.Dimensions.prototype.__repr__ = function () {
+ var repr = MochiKit.Base.repr;
+ return '{w: ' + repr(this.w) + ', h: ' + repr(this.h) + '}';
+};
+
+MochiKit.Style.Dimensions.prototype.toString = function () {
+ return this.__repr__();
+};
+
+
+/** @id MochiKit.Style.Coordinates */
+MochiKit.Style.Coordinates = function (x, y) {
+ if (!(this instanceof MochiKit.Style.Coordinates)) {
+ return new MochiKit.Style.Coordinates(x, y);
+ }
+ this.x = x;
+ this.y = y;
+};
+
+MochiKit.Style.Coordinates.prototype.__repr__ = function () {
+ var repr = MochiKit.Base.repr;
+ return '{x: ' + repr(this.x) + ', y: ' + repr(this.y) + '}';
+};
+
+MochiKit.Style.Coordinates.prototype.toString = function () {
+ return this.__repr__();
+};
+
+
+MochiKit.Base.update(MochiKit.Style, {
+
+ /** @id MochiKit.Style.getStyle */
+ getStyle: function (elem, cssProperty) {
+ var dom = MochiKit.DOM;
+ var d = dom._document;
+
+ elem = dom.getElement(elem);
+ cssProperty = MochiKit.Base.camelize(cssProperty);
+
+ if (!elem || elem == d) {
+ return undefined;
+ }
+ if (cssProperty == 'opacity' && typeof(elem.filters) != 'undefined') {
+ var opacity = (MochiKit.Style.getStyle(elem, 'filter') || '').match(/alpha\(opacity=(.*)\)/);
+ if (opacity && opacity[1]) {
+ return parseFloat(opacity[1]) / 100;
+ }
+ return 1.0;
+ }
+ if (cssProperty == 'float' || cssProperty == 'cssFloat' || cssProperty == 'styleFloat') {
+ if (elem.style["float"]) {
+ return elem.style["float"];
+ } else if (elem.style.cssFloat) {
+ return elem.style.cssFloat;
+ } else if (elem.style.styleFloat) {
+ return elem.style.styleFloat;
+ } else {
+ return "none";
+ }
+ }
+ var value = elem.style ? elem.style[cssProperty] : null;
+ if (!value) {
+ if (d.defaultView && d.defaultView.getComputedStyle) {
+ var css = d.defaultView.getComputedStyle(elem, null);
+ cssProperty = cssProperty.replace(/([A-Z])/g, '-$1'
+ ).toLowerCase(); // from dojo.style.toSelectorCase
+ value = css ? css.getPropertyValue(cssProperty) : null;
+ } else if (elem.currentStyle) {
+ value = elem.currentStyle[cssProperty];
+ if (/^\d/.test(value) && !/px$/.test(value) && cssProperty != 'fontWeight') {
+ /* Convert to px using an hack from Dean Edwards */
+ var left = elem.style.left;
+ var rsLeft = elem.runtimeStyle.left;
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ elem.style.left = value || 0;
+ value = elem.style.pixelLeft + "px";
+ elem.style.left = left;
+ elem.runtimeStyle.left = rsLeft;
+ }
+ }
+ }
+ if (cssProperty == 'opacity') {
+ value = parseFloat(value);
+ }
+
+ if (/Opera/.test(navigator.userAgent) && (MochiKit.Base.findValue(['left', 'top', 'right', 'bottom'], cssProperty) != -1)) {
+ if (MochiKit.Style.getStyle(elem, 'position') == 'static') {
+ value = 'auto';
+ }
+ }
+
+ return value == 'auto' ? null : value;
+ },
+
+ /** @id MochiKit.Style.setStyle */
+ setStyle: function (elem, style) {
+ elem = MochiKit.DOM.getElement(elem);
+ for (var name in style) {
+ switch (name) {
+ case 'opacity':
+ MochiKit.Style.setOpacity(elem, style[name]);
+ break;
+ case 'float':
+ case 'cssFloat':
+ case 'styleFloat':
+ if (typeof(elem.style["float"]) != "undefined") {
+ elem.style["float"] = style[name];
+ } else if (typeof(elem.style.cssFloat) != "undefined") {
+ elem.style.cssFloat = style[name];
+ } else {
+ elem.style.styleFloat = style[name];
+ }
+ break;
+ default:
+ elem.style[MochiKit.Base.camelize(name)] = style[name];
+ }
+ }
+ },
+
+ /** @id MochiKit.Style.setOpacity */
+ setOpacity: function (elem, o) {
+ elem = MochiKit.DOM.getElement(elem);
+ var self = MochiKit.Style;
+ if (o == 1) {
+ var toSet = /Gecko/.test(navigator.userAgent) && !(/Konqueror|AppleWebKit|KHTML/.test(navigator.userAgent));
+ elem.style["opacity"] = toSet ? 0.999999 : 1.0;
+ if (/MSIE/.test(navigator.userAgent)) {
+ elem.style['filter'] =
+ self.getStyle(elem, 'filter').replace(/alpha\([^\)]*\)/gi, '');
+ }
+ } else {
+ if (o < 0.00001) {
+ o = 0;
+ }
+ elem.style["opacity"] = o;
+ if (/MSIE/.test(navigator.userAgent)) {
+ elem.style['filter'] =
+ self.getStyle(elem, 'filter').replace(/alpha\([^\)]*\)/gi, '') + 'alpha(opacity=' + o * 100 + ')';
+ }
+ }
+ },
+
+ /*
+
+ getElementPosition is adapted from YAHOO.util.Dom.getXY v0.9.0.
+ Copyright: Copyright (c) 2006, Yahoo! Inc. All rights reserved.
+ License: BSD, http://developer.yahoo.net/yui/license.txt
+
+ */
+
+ /** @id MochiKit.Style.getElementPosition */
+ getElementPosition: function (elem, /* optional */relativeTo) {
+ var self = MochiKit.Style;
+ var dom = MochiKit.DOM;
+ var isCoordinates = function (o) {
+ return o != null &&
+ o.nodeType == null &&
+ typeof(o.x) == "number" &&
+ typeof(o.y) == "number";
+ }
+
+ if (typeof(elem) == "string") {
+ elem = dom.getElement(elem);
+ }
+ if (elem == null ||
+ (!isCoordinates(elem) && self.getStyle(elem, 'display') == 'none')) {
+ return undefined;
+ }
+
+ var c = new self.Coordinates(0, 0);
+ var box = null;
+ var parent = null;
+
+ var d = MochiKit.DOM._document;
+ var de = d.documentElement;
+ var b = d.body;
+
+ if (!elem.parentNode && elem.x && elem.y) {
+ /* it's just a MochiKit.Style.Coordinates object */
+ c.x += elem.x || 0;
+ c.y += elem.y || 0;
+ } else if (elem.getBoundingClientRect) { // IE shortcut
+ /*
+
+ The IE shortcut can be off by two. We fix it. See:
+ http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp
+
+ This is similar to the method used in
+ MochiKit.Signal.Event.mouse().
+
+ */
+ box = elem.getBoundingClientRect();
+
+ c.x += box.left +
+ (de.scrollLeft || b.scrollLeft) -
+ (de.clientLeft || 0);
+
+ c.y += box.top +
+ (de.scrollTop || b.scrollTop) -
+ (de.clientTop || 0);
+
+ } else if (elem.offsetParent) {
+ c.x += elem.offsetLeft;
+ c.y += elem.offsetTop;
+ parent = elem.offsetParent;
+
+ if (parent != elem) {
+ while (parent) {
+ c.x += parseInt(parent.style.borderLeftWidth) || 0;
+ c.y += parseInt(parent.style.borderTopWidth) || 0;
+ c.x += parent.offsetLeft;
+ c.y += parent.offsetTop;
+ parent = parent.offsetParent;
+ }
+ }
+
+ /*
+
+ Opera < 9 and old Safari (absolute) incorrectly account for
+ body offsetTop and offsetLeft.
+
+ */
+ var ua = navigator.userAgent.toLowerCase();
+ if ((typeof(opera) != 'undefined' &&
+ parseFloat(opera.version()) < 9) ||
+ (ua.indexOf('AppleWebKit') != -1 &&
+ self.getStyle(elem, 'position') == 'absolute')) {
+
+ c.x -= b.offsetLeft;
+ c.y -= b.offsetTop;
+
+ }
+
+ // Adjust position for strange Opera scroll bug
+ if (elem.parentNode) {
+ parent = elem.parentNode;
+ } else {
+ parent = null;
+ }
+ while (parent) {
+ var tagName = parent.tagName.toUpperCase();
+ if (tagName === 'BODY' || tagName === 'HTML') {
+ break;
+ }
+ var disp = self.getStyle(parent, 'display');
+ // Handle strange Opera bug for some display
+ if (disp.search(/^inline|table-row.*$/i)) {
+ c.x -= parent.scrollLeft;
+ c.y -= parent.scrollTop;
+ }
+ if (parent.parentNode) {
+ parent = parent.parentNode;
+ } else {
+ parent = null;
+ }
+ }
+ }
+
+ if (relativeTo) {
+ relativeTo = arguments.callee(relativeTo);
+ if (relativeTo) {
+ c.x -= (relativeTo.x || 0);
+ c.y -= (relativeTo.y || 0);
+ }
+ }
+
+ return c;
+ },
+
+ /** @id MochiKit.Style.setElementPosition */
+ setElementPosition: function (elem, newPos/* optional */, units) {
+ elem = MochiKit.DOM.getElement(elem);
+ if (typeof(units) == 'undefined') {
+ units = 'px';
+ }
+ var newStyle = {};
+ var isUndefNull = MochiKit.Base.isUndefinedOrNull;
+ if (!isUndefNull(newPos.x)) {
+ newStyle['left'] = newPos.x + units;
+ }
+ if (!isUndefNull(newPos.y)) {
+ newStyle['top'] = newPos.y + units;
+ }
+ MochiKit.DOM.updateNodeAttributes(elem, {'style': newStyle});
+ },
+
+ /** @id MochiKit.Style.makePositioned */
+ makePositioned: function (element) {
+ element = MochiKit.DOM.getElement(element);
+ var pos = MochiKit.Style.getStyle(element, 'position');
+ if (pos == 'static' || !pos) {
+ element.style.position = 'relative';
+ // Opera returns the offset relative to the positioning context,
+ // when an element is position relative but top and left have
+ // not been defined
+ if (/Opera/.test(navigator.userAgent)) {
+ element.style.top = 0;
+ element.style.left = 0;
+ }
+ }
+ },
+
+ /** @id MochiKit.Style.undoPositioned */
+ undoPositioned: function (element) {
+ element = MochiKit.DOM.getElement(element);
+ if (element.style.position == 'relative') {
+ element.style.position = element.style.top = element.style.left = element.style.bottom = element.style.right = '';
+ }
+ },
+
+ /** @id MochiKit.Style.makeClipping */
+ makeClipping: function (element) {
+ element = MochiKit.DOM.getElement(element);
+ var s = element.style;
+ var oldOverflow = { 'overflow': s.overflow,
+ 'overflow-x': s.overflowX,
+ 'overflow-y': s.overflowY };
+ if ((MochiKit.Style.getStyle(element, 'overflow') || 'visible') != 'hidden') {
+ element.style.overflow = 'hidden';
+ element.style.overflowX = 'hidden';
+ element.style.overflowY = 'hidden';
+ }
+ return oldOverflow;
+ },
+
+ /** @id MochiKit.Style.undoClipping */
+ undoClipping: function (element, overflow) {
+ element = MochiKit.DOM.getElement(element);
+ if (typeof(overflow) == 'string') {
+ element.style.overflow = overflow;
+ } else if (overflow != null) {
+ element.style.overflow = overflow['overflow'];
+ element.style.overflowX = overflow['overflow-x'];
+ element.style.overflowY = overflow['overflow-y'];
+ }
+ },
+
+ /** @id MochiKit.Style.getElementDimensions */
+ getElementDimensions: function (elem, contentSize/*optional*/) {
+ var self = MochiKit.Style;
+ var dom = MochiKit.DOM;
+ if (typeof(elem.w) == 'number' || typeof(elem.h) == 'number') {
+ return new self.Dimensions(elem.w || 0, elem.h || 0);
+ }
+ elem = dom.getElement(elem);
+ if (!elem) {
+ return undefined;
+ }
+ var disp = self.getStyle(elem, 'display');
+ // display can be empty/undefined on WebKit/KHTML
+ if (disp == 'none' || disp == '' || typeof(disp) == 'undefined') {
+ var s = elem.style;
+ var originalVisibility = s.visibility;
+ var originalPosition = s.position;
+ var originalDisplay = s.display;
+ s.visibility = 'hidden';
+ s.position = 'absolute';
+ s.display = self._getDefaultDisplay(elem);
+ var originalWidth = elem.offsetWidth;
+ var originalHeight = elem.offsetHeight;
+ s.display = originalDisplay;
+ s.position = originalPosition;
+ s.visibility = originalVisibility;
+ } else {
+ originalWidth = elem.offsetWidth || 0;
+ originalHeight = elem.offsetHeight || 0;
+ }
+ if (contentSize) {
+ var tableCell = 'colSpan' in elem && 'rowSpan' in elem;
+ var collapse = (tableCell && elem.parentNode && self.getStyle(
+ elem.parentNode, 'borderCollapse') == 'collapse')
+ if (collapse) {
+ if (/MSIE/.test(navigator.userAgent)) {
+ var borderLeftQuota = elem.previousSibling? 0.5 : 1;
+ var borderRightQuota = elem.nextSibling? 0.5 : 1;
+ }
+ else {
+ var borderLeftQuota = 0.5;
+ var borderRightQuota = 0.5;
+ }
+ } else {
+ var borderLeftQuota = 1;
+ var borderRightQuota = 1;
+ }
+ originalWidth -= Math.round(
+ (parseFloat(self.getStyle(elem, 'paddingLeft')) || 0)
+ + (parseFloat(self.getStyle(elem, 'paddingRight')) || 0)
+ + borderLeftQuota *
+ (parseFloat(self.getStyle(elem, 'borderLeftWidth')) || 0)
+ + borderRightQuota *
+ (parseFloat(self.getStyle(elem, 'borderRightWidth')) || 0)
+ );
+ if (tableCell) {
+ if (/Gecko|Opera/.test(navigator.userAgent)
+ && !/Konqueror|AppleWebKit|KHTML/.test(navigator.userAgent)) {
+ var borderHeightQuota = 0;
+ } else if (/MSIE/.test(navigator.userAgent)) {
+ var borderHeightQuota = 1;
+ } else {
+ var borderHeightQuota = collapse? 0.5 : 1;
+ }
+ } else {
+ var borderHeightQuota = 1;
+ }
+ originalHeight -= Math.round(
+ (parseFloat(self.getStyle(elem, 'paddingTop')) || 0)
+ + (parseFloat(self.getStyle(elem, 'paddingBottom')) || 0)
+ + borderHeightQuota * (
+ (parseFloat(self.getStyle(elem, 'borderTopWidth')) || 0)
+ + (parseFloat(self.getStyle(elem, 'borderBottomWidth')) || 0))
+ );
+ }
+ return new self.Dimensions(originalWidth, originalHeight);
+ },
+
+ /** @id MochiKit.Style.setElementDimensions */
+ setElementDimensions: function (elem, newSize/* optional */, units) {
+ elem = MochiKit.DOM.getElement(elem);
+ if (typeof(units) == 'undefined') {
+ units = 'px';
+ }
+ var newStyle = {};
+ var isUndefNull = MochiKit.Base.isUndefinedOrNull;
+ if (!isUndefNull(newSize.w)) {
+ newStyle['width'] = newSize.w + units;
+ }
+ if (!isUndefNull(newSize.h)) {
+ newStyle['height'] = newSize.h + units;
+ }
+ MochiKit.DOM.updateNodeAttributes(elem, {'style': newStyle});
+ },
+
+ _getDefaultDisplay: function (elem) {
+ var self = MochiKit.Style;
+ var dom = MochiKit.DOM;
+ elem = dom.getElement(elem);
+ if (!elem) {
+ return undefined;
+ }
+ var tagName = elem.tagName.toUpperCase();
+ return self._defaultDisplay[tagName] || 'block';
+ },
+
+ /** @id MochiKit.Style.setDisplayForElement */
+ setDisplayForElement: function (display, element/*, ...*/) {
+ var elements = MochiKit.Base.extend(null, arguments, 1);
+ var getElement = MochiKit.DOM.getElement;
+ for (var i = 0; i < elements.length; i++) {
+ element = getElement(elements[i]);
+ if (element) {
+ element.style.display = display;
+ }
+ }
+ },
+
+ /** @id MochiKit.Style.getViewportDimensions */
+ getViewportDimensions: function () {
+ var d = new MochiKit.Style.Dimensions();
+ var w = MochiKit.DOM._window;
+ var b = MochiKit.DOM._document.body;
+ if (w.innerWidth) {
+ d.w = w.innerWidth;
+ d.h = w.innerHeight;
+ } else if (b && b.parentElement && b.parentElement.clientWidth) {
+ d.w = b.parentElement.clientWidth;
+ d.h = b.parentElement.clientHeight;
+ } else if (b && b.clientWidth) {
+ d.w = b.clientWidth;
+ d.h = b.clientHeight;
+ }
+ return d;
+ },
+
+ /** @id MochiKit.Style.getViewportPosition */
+ getViewportPosition: function () {
+ var c = new MochiKit.Style.Coordinates(0, 0);
+ var d = MochiKit.DOM._document;
+ var de = d.documentElement;
+ var db = d.body;
+ if (de && (de.scrollTop || de.scrollLeft)) {
+ c.x = de.scrollLeft;
+ c.y = de.scrollTop;
+ } else if (db) {
+ c.x = db.scrollLeft;
+ c.y = db.scrollTop;
+ }
+ return c;
+ },
+
+ __new__: function () {
+ var m = MochiKit.Base;
+
+ var inlines = ['A','ABBR','ACRONYM','B','BASEFONT','BDO','BIG','BR',
+ 'CITE','CODE','DFN','EM','FONT','I','IMG','KBD','LABEL',
+ 'Q','S','SAMP','SMALL','SPAN','STRIKE','STRONG','SUB',
+ 'SUP','TEXTAREA','TT','U','VAR'];
+ this._defaultDisplay = { 'TABLE': 'table',
+ 'THEAD': 'table-header-group',
+ 'TBODY': 'table-row-group',
+ 'TFOOT': 'table-footer-group',
+ 'COLGROUP': 'table-column-group',
+ 'COL': 'table-column',
+ 'TR': 'table-row',
+ 'TD': 'table-cell',
+ 'TH': 'table-cell',
+ 'CAPTION': 'table-caption',
+ 'LI': 'list-item',
+ 'INPUT': 'inline-block',
+ 'SELECT': 'inline-block' };
+ // CSS 'display' support in IE6/7 is just broken...
+ if (/MSIE/.test(navigator.userAgent)) {
+ for (var k in this._defaultDisplay) {
+ var v = this._defaultDisplay[k];
+ if (v.indexOf('table') == 0) {
+ this._defaultDisplay[k] = 'block';
+ }
+ }
+ }
+ for (var i = 0; i < inlines.length; i++) {
+ this._defaultDisplay[inlines[i]] = 'inline';
+ }
+
+ // Backwards compatibility aliases
+ m._deprecated(this, 'elementPosition', 'MochiKit.Style.getElementPosition', '1.3');
+ m._deprecated(this, 'elementDimensions', 'MochiKit.Style.getElementDimensions', '1.3');
+
+ this.hideElement = m.partial(this.setDisplayForElement, 'none');
+ // TODO: showElement could be improved by using getDefaultDisplay.
+ this.showElement = m.partial(this.setDisplayForElement, 'block');
+
+ m.nameFunctions(this);
+ }
+});
+
+MochiKit.Style.__new__();
+MochiKit.Base._exportSymbols(this, MochiKit.Style);
diff --git a/frontend/gamma/js/MochiKit/Test.js b/frontend/gamma/js/MochiKit/Test.js
new file mode 100644
index 0000000..9520ab2
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Test.js
@@ -0,0 +1,144 @@
+/***
+
+MochiKit.Test 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('Test', '1.5', ['Base']);
+
+MochiKit.Test.runTests = function (obj) {
+ if (typeof(obj) == "string") {
+ // TODO: Remove this temporary API change advertisement
+ throw new TypeError("Automatic module import not supported, call runTests() with proper object: " + obj);
+ }
+ var suite = new MochiKit.Test.Suite();
+ suite.run(obj);
+};
+
+MochiKit.Test.Suite = function () {
+ this.testIndex = 0;
+ MochiKit.Base.bindMethods(this);
+};
+
+MochiKit.Test.Suite.prototype = {
+ run: function (obj) {
+ try {
+ obj(this);
+ } catch (e) {
+ this.traceback(e);
+ }
+ },
+ traceback: function (e) {
+ var items = MochiKit.Iter.sorted(MochiKit.Base.items(e));
+ print("not ok " + this.testIndex + " - Error thrown");
+ for (var i = 0; i < items.length; i++) {
+ var kv = items[i];
+ if (kv[0] == "stack") {
+ kv[1] = kv[1].split(/\n/)[0];
+ }
+ this.print("# " + kv.join(": "));
+ }
+ },
+ print: function (s) {
+ print(s);
+ },
+ is: function (got, expected, /* optional */message) {
+ var res = 1;
+ var msg = null;
+ try {
+ res = MochiKit.Base.compare(got, expected);
+ } catch (e) {
+ msg = "Can not compare " + typeof(got) + ":" + typeof(expected);
+ }
+ if (res) {
+ msg = "Expected value did not compare equal";
+ }
+ if (!res) {
+ return this.testResult(true, message);
+ }
+ return this.testResult(false, message,
+ [[msg], ["got:", got], ["expected:", expected]]);
+ },
+
+ testResult: function (pass, msg, failures) {
+ this.testIndex += 1;
+ if (pass) {
+ this.print("ok " + this.testIndex + " - " + msg);
+ return;
+ }
+ this.print("not ok " + this.testIndex + " - " + msg);
+ if (failures) {
+ for (var i = 0; i < failures.length; i++) {
+ this.print("# " + failures[i].join(" "));
+ }
+ }
+ },
+
+ isDeeply: function (got, expected, /* optional */message) {
+ var m = MochiKit.Base;
+ var res = 1;
+ try {
+ res = m.compare(got, expected);
+ } catch (e) {
+ // pass
+ }
+ if (res === 0) {
+ return this.ok(true, message);
+ }
+ var gk = m.keys(got);
+ var ek = m.keys(expected);
+ gk.sort();
+ ek.sort();
+ if (m.compare(gk, ek)) {
+ // differing keys
+ var cmp = {};
+ var i;
+ for (i = 0; i < gk.length; i++) {
+ cmp[gk[i]] = "got";
+ }
+ for (i = 0; i < ek.length; i++) {
+ if (ek[i] in cmp) {
+ delete cmp[ek[i]];
+ } else {
+ cmp[ek[i]] = "expected";
+ }
+ }
+ var diffkeys = m.keys(cmp);
+ diffkeys.sort();
+ var gotkeys = [];
+ var expkeys = [];
+ while (diffkeys.length) {
+ var k = diffkeys.shift();
+ if (k in Object.prototype) {
+ continue;
+ }
+ (cmp[k] == "got" ? gotkeys : expkeys).push(k);
+ }
+
+
+ }
+
+ return this.testResult((!res), msg,
+ (msg ? [["got:", got], ["expected:", expected]] : undefined)
+ );
+ },
+
+ ok: function (res, message) {
+ return this.testResult(res, message);
+ }
+};
+
+MochiKit.Test.__new__ = function () {
+ var m = MochiKit.Base;
+ this.Suite.__export__ = false;
+ m.nameFunctions(this);
+
+};
+
+MochiKit.Test.__new__();
+
+MochiKit.Base._exportSymbols(this, MochiKit.Test);
diff --git a/frontend/gamma/js/MochiKit/Text.js b/frontend/gamma/js/MochiKit/Text.js
new file mode 100644
index 0000000..a44f7e4
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Text.js
@@ -0,0 +1,577 @@
+/***
+
+MochiKit.Text 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2008 Per Cederberg. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('Text', '1.5', ['Base', 'Format']);
+
+/**
+ * Checks if a text string starts with the specified substring. If
+ * either of the two strings is null, false will be returned.
+ *
+ * @param {String} substr the substring to search for
+ * @param {String} str the string to search in
+ *
+ * @return {Boolean} true if the string starts with the substring, or
+ * false otherwise
+ */
+MochiKit.Text.startsWith = function (substr, str) {
+ return str != null && substr != null && str.indexOf(substr) == 0;
+}
+
+/**
+ * Checks if a text string ends with the specified substring. If
+ * either of the two strings is null, false will be returned.
+ *
+ * @param {String} substr the substring to search for
+ * @param {String} str the string to search in
+ *
+ * @return {Boolean} true if the string ends with the substring, or
+ * false otherwise
+ */
+MochiKit.Text.endsWith = function (substr, str) {
+ return str != null && substr != null &&
+ str.lastIndexOf(substr) == Math.max(str.length - substr.length, 0);
+}
+
+/**
+ * Checks if a text string contains the specified substring. If
+ * either of the two strings is null, false will be returned.
+ *
+ * @param {String} substr the substring to search for
+ * @param {String} str the string to search in
+ *
+ * @return {Boolean} true if the string contains the substring, or
+ * false otherwise
+ */
+MochiKit.Text.contains = function (substr, str) {
+ return str != null && substr != null && str.indexOf(substr) >= 0;
+}
+
+/**
+ * Adds a character to the left-hand side of a string until it
+ * reaches the specified minimum length.
+ *
+ * @param {String} str the string to process
+ * @param {Number} minLength the requested minimum length
+ * @param {String} fillChar the padding character to add, defaults
+ * to a space
+ *
+ * @return {String} the padded string
+ */
+MochiKit.Text.padLeft = function (str, minLength, fillChar) {
+ str = str || "";
+ fillChar = fillChar || " ";
+ while (str.length < minLength) {
+ str = fillChar + str;
+ }
+ return str;
+}
+
+/**
+ * Adds a character to the right-hand side of a string until it
+ * reaches the specified minimum length.
+ *
+ * @param {String} str the string to process
+ * @param {Number} minLength the requested minimum length
+ * @param {String} fillChar the padding character to add, defaults
+ * to a space
+ *
+ * @return {String} the padded string
+ */
+MochiKit.Text.padRight = function (str, minLength, fillChar) {
+ str = str || "";
+ fillChar = fillChar || " ";
+ while (str.length < minLength) {
+ str += fillChar;
+ }
+ return str;
+}
+
+/**
+ * Returns a truncated copy of a string. If the string is shorter
+ * than the specified maximum length, the object will be returned
+ * unmodified. If an optional tail string is specified, additional
+ * elements will be removed in order to accomodate the tail (that
+ * will be appended). This function also works on arrays.
+ *
+ * @param {String} str the string to truncate
+ * @param {Number} maxLength the maximum length
+ * @param {String} [tail] the tail to append on truncation
+ *
+ * @return {String} the truncated string
+ */
+MochiKit.Text.truncate = function (str, maxLength, tail) {
+ if (str == null || str.length <= maxLength || maxLength < 0) {
+ return str;
+ } else if (tail != null) {
+ str = str.slice(0, Math.max(0, maxLength - tail.length));
+ if (typeof(str) == "string") {
+ return str + tail;
+ } else {
+ return MochiKit.Base.extend(str, tail);
+ }
+ } else {
+ return str.slice(0, maxLength);
+ }
+}
+
+/**
+ * Splits a text string, applies a function and joins the results
+ * back together again. This is a convenience function for calling
+ * split(), map() and join() separately. It can be used to easily
+ * trim each line in a text string (using the strip function), or to
+ * translate a text word-by-word.
+ *
+ * @param {Function} func the function to apply
+ * @param {String} str the string to split
+ * @param {String} [separator] the separator character to use,
+ * defaults to newline
+ *
+ * @return {String} a string with the joined up results
+ */
+MochiKit.Text.splitJoin = function (func, str, separator) {
+ if (str == null || str.length == 0) {
+ return str;
+ }
+ separator = separator || '\n'
+ return MochiKit.Base.map(func, str.split(separator)).join(separator);
+}
+
+/**
+ * Creates a formatter function for the specified formatter pattern
+ * and locale. The returned function takes as many arguments as the
+ * formatter pattern requires. See separate documentation for
+ * information about the formatter pattern syntax.
+ *
+ * @param {String} pattern the formatter pattern string
+ * @param {Object} [locale] the locale to use, defaults to
+ * LOCALE.en_US
+ *
+ * @return {Function} the formatter function created
+ *
+ * @throws FormatPatternError if the format pattern was invalid
+ */
+MochiKit.Text.formatter = function (pattern, locale) {
+ if (typeof(locale) == "undefined") {
+ locale = MochiKit.Format.formatLocale();
+ } else if (typeof(locale) == "string") {
+ locale = MochiKit.Format.formatLocale(locale);
+ }
+ var parts = MochiKit.Text._parsePattern(pattern);
+ return function() {
+ var values = MochiKit.Base.extend([], arguments);
+ var res = [];
+ for (var i = 0; i < parts.length; i++) {
+ if (typeof(parts[i]) == "string") {
+ res.push(parts[i]);
+ } else {
+ res.push(MochiKit.Text.formatValue(parts[i], values, locale));
+ }
+ }
+ return res.join("");
+ }
+}
+
+/**
+ * Formats the specified arguments according to a formatter pattern.
+ * See separate documentation for information about the formatter
+ * pattern syntax.
+ *
+ * @param {String} pattern the formatter pattern string
+ * @param {Object} [...] the optional values to format
+ *
+ * @return {String} the formatted output string
+ *
+ * @throws FormatPatternError if the format pattern was invalid
+ */
+MochiKit.Text.format = function (pattern/*, ...*/) {
+ var func = MochiKit.Text.formatter(pattern);
+ return func.apply(this, MochiKit.Base.extend([], arguments, 1));
+}
+
+/**
+ * Format a value with the specified format specifier.
+ *
+ * @param {String/Object} spec the format specifier string or parsed
+ * format specifier object
+ * @param {Object} value the value to format
+ * @param {Object} [locale] the locale to use, defaults to
+ * LOCALE.en_US
+ *
+ * @return {String} the formatted output string
+ */
+MochiKit.Text.formatValue = function (spec, value, locale) {
+ var self = MochiKit.Text;
+ if (typeof(spec) === "string") {
+ spec = self._parseFormatFlags(spec, 0, spec.length - 1);
+ }
+ for (var i = 0; spec.path != null && i < spec.path.length; i++) {
+ if (value != null) {
+ value = value[spec.path[i]];
+ }
+ }
+ if (typeof(locale) == "undefined") {
+ locale = MochiKit.Format.formatLocale();
+ } else if (typeof(locale) == "string") {
+ locale = MochiKit.Format.formatLocale(locale);
+ }
+ var str = "";
+ if (spec.numeric) {
+ if (typeof(value) != "number" || isNaN(value)) {
+ str = "";
+ } else if (value === Number.POSITIVE_INFINITY) {
+ str = "\u221e";
+ } else if (value === Number.NEGATIVE_INFINITY) {
+ str = "-\u221e";
+ } else {
+ var sign = (spec.sign === "-") ? "" : spec.sign;
+ sign = (value < 0) ? "-" : sign;
+ value = Math.abs(value);
+ if (spec.format === "%") {
+ str = self._truncToPercent(value, spec.precision);
+ } else if (spec.format === "d") {
+ str = MochiKit.Format.roundToFixed(value, 0);
+ } else if (spec.radix != 10) {
+ str = Math.floor(value).toString(spec.radix);
+ if (spec.format === "x") {
+ str = str.toLowerCase();
+ } else if (spec.format === "X") {
+ str = str.toUpperCase();
+ }
+ } else if (spec.precision >= 0) {
+ str = MochiKit.Format.roundToFixed(value, spec.precision);
+ } else {
+ str = value.toString();
+ }
+ if (spec.padding === "0" && spec.format === "%") {
+ str = self.padLeft(str, spec.width - sign.length - 1, "0");
+ } else if (spec.padding == "0") {
+ str = self.padLeft(str, spec.width - sign.length, "0");
+ }
+ str = self._localizeNumber(str, locale, spec.grouping);
+ str = sign + str;
+ }
+ if (str !== "" && spec.format === "%") {
+ str = str + locale.percent;
+ }
+ } else {
+ if (spec.format == "r") {
+ str = MochiKit.Base.repr(value);
+ } else {
+ str = (value == null) ? "null" : value.toString();
+ }
+ str = self.truncate(str, spec.precision);
+ }
+ if (spec.align == "<") {
+ str = self.padRight(str, spec.width);
+ } else {
+ str = self.padLeft(str, spec.width);
+ }
+ return str;
+}
+
+/**
+ * Adjust an already formatted numeric string for locale-specific
+ * grouping and decimal separators. The grouping is optional and
+ * will attempt to keep the number string length intact by removing
+ * padded zeros (if possible).
+ *
+ * @param {String} num the formatted number string
+ * @param {Object} locale the formatting locale to use
+ * @param {Boolean} grouping the grouping flag
+ *
+ * @return {String} the localized number string
+ */
+MochiKit.Text._localizeNumber = function (num, locale, grouping) {
+ var parts = num.split(/\./);
+ var whole = parts[0];
+ var frac = (parts.length == 1) ? "" : parts[1];
+ var res = (frac.length > 0) ? locale.decimal : "";
+ while (grouping && frac.length > 3) {
+ res = res + frac.substring(0, 3) + locale.separator;
+ frac = frac.substring(3);
+ if (whole.charAt(0) == "0") {
+ whole = whole.substring(1);
+ }
+ }
+ if (frac.length > 0) {
+ res += frac;
+ }
+ while (grouping && whole.length > 3) {
+ var pos = whole.length - 3;
+ res = locale.separator + whole.substring(pos) + res;
+ whole = whole.substring((whole.charAt(0) == "0") ? 1 : 0, pos);
+ }
+ return whole + res;
+}
+
+/**
+ * Parses a format pattern and returns an array of constant strings
+ * and format info objects.
+ *
+ * @param {String} pattern the format pattern to analyze
+ *
+ * @return {Array} an array of strings and format info objects
+ *
+ * @throws FormatPatternError if the format pattern was invalid
+ */
+MochiKit.Text._parsePattern = function (pattern) {
+ var self = MochiKit.Text;
+ var parts = [];
+ var start = 0;
+ var pos = 0;
+ for (pos = 0; pos < pattern.length; pos++) {
+ if (pattern.charAt(pos) == "{") {
+ if (pos + 1 >= pattern.length) {
+ var msg = "unescaped { char, should be escaped as {{";
+ throw new self.FormatPatternError(pattern, pos, msg);
+ } else if (pattern.charAt(pos + 1) == "{") {
+ parts.push(pattern.substring(start, pos + 1));
+ start = pos + 2;
+ pos++;
+ } else {
+ if (start < pos) {
+ parts.push(pattern.substring(start, pos));
+ }
+ start = pattern.indexOf("}", pos) + 1;
+ if (start <= 0) {
+ var msg = "unmatched { char, not followed by a } char";
+ throw new self.FormatPatternError(pattern, pos, msg);
+ }
+ parts.push(self._parseFormat(pattern, pos + 1, start - 1));
+ pos = start - 1;
+ }
+ } else if (pattern.charAt(pos) == "}") {
+ if (pos + 1 >= pattern.length || pattern.charAt(pos + 1) != "}") {
+ var msg = "unescaped } char, should be escaped as }}";
+ throw new self.FormatPatternError(pattern, pos, msg);
+ }
+ parts.push(pattern.substring(start, pos + 1));
+ start = pos + 2;
+ pos++;
+ }
+ }
+ if (start < pos) {
+ parts.push(pattern.substring(start, pos));
+ }
+ return parts;
+}
+
+/**
+ * Parses a format instruction and returns a format info object.
+ *
+ * @param {String} pattern the format pattern string
+ * @param {Number} startPos the first index of the format instruction
+ * @param {Number} endPos the last index of the format instruction
+ *
+ * @return {Object} the format info object
+ *
+ * @throws FormatPatternError if the format pattern was invalid
+ */
+MochiKit.Text._parseFormat = function (pattern, startPos, endPos) {
+ var self = MochiKit.Text;
+ var text = pattern.substring(startPos, endPos);
+ var info;
+ var pos = text.indexOf(":");
+ if (pos == 0) {
+ info = self._parseFormatFlags(pattern, startPos + 1, endPos);
+ info.path = [0];
+ } else if (pos > 0) {
+ info = self._parseFormatFlags(pattern, startPos + pos + 1, endPos);
+ info.path = text.substring(0, pos).split(".");
+ } else {
+ info = self._parseFormatFlags(pattern, endPos, endPos);
+ info.path = text.split(".");
+ }
+ var DIGITS = /^\d+$/;
+ for (var i = 0; i < info.path.length; i++) {
+ var e = info.path[i];
+ if (typeof(e) == "string") {
+ // TODO: replace with MochiKit.Format.strip?
+ e = e.replace(/^\s+/, "").replace(/\s+$/, "");
+ if (e == "" && info.path.length == 1) {
+ e = 0;
+ } else if (e == "") {
+ var msg = "format value path contains blanks";
+ throw new self.FormatPatternError(pattern, startPos, msg);
+ } else if (DIGITS.test(e)) {
+ e = parseInt(e);
+ }
+ }
+ info.path[i] = e;
+ }
+ if (info.path.length < 0 || typeof(info.path[0]) != "number") {
+ info.path.unshift(0);
+ }
+ return info;
+}
+
+/**
+ * Parses a string with format flags and returns a format info object.
+ *
+ * @param {String} pattern the format pattern string
+ * @param {Number} startPos the first index of the format instruction
+ * @param {Number} endPos the last index of the format instruction
+ *
+ * @return {Object} the format info object
+ *
+ * @throws FormatPatternError if the format pattern was invalid
+ */
+MochiKit.Text._parseFormatFlags = function (pattern, startPos, endPos) {
+ var self = MochiKit.Text;
+ var info = { numeric: false, format: "s", width: 0, precision: -1,
+ align: ">", sign: "-", padding: " ", grouping: false };
+ // TODO: replace with MochiKit.Format.rstrip?
+ var flags = pattern.substring(startPos, endPos).replace(/\s+$/, "");
+ while (flags.length > 0) {
+ switch (flags.charAt(0)) {
+ case ">":
+ case "<":
+ info.align = flags.charAt(0);
+ flags = flags.substring(1);
+ break;
+ case "+":
+ case "-":
+ case " ":
+ info.sign = flags.charAt(0);
+ flags = flags.substring(1);
+ break;
+ case ",":
+ info.grouping = true;
+ flags = flags.substring(1);
+ break;
+ case ".":
+ var chars = /^\d*/.exec(flags.substring(1))[0];
+ info.precision = parseInt(chars);
+ flags = flags.substring(1 + chars.length);
+ break;
+ case "0":
+ info.padding = flags.charAt(0);
+ flags = flags.substring(1);
+ break;
+ case "1":
+ case "2":
+ case "3":
+ case "4":
+ case "5":
+ case "6":
+ case "7":
+ case "8":
+ case "9":
+ var chars = /^\d*/.exec(flags)[0];
+ info.width = parseInt(chars);
+ flags = flags.substring(chars.length);
+ break;
+ case "s":
+ case "r":
+ info.format = flags.charAt(0);
+ flags = flags.substring(1);
+ break;
+ case "b":
+ case "d":
+ case "o":
+ case "x":
+ case "X":
+ case "f":
+ case "%":
+ info.numeric = true;
+ info.format = flags.charAt(0);
+ info.radix = 10;
+ if (info.format === "b") {
+ info.radix = 2;
+ } else if (info.format === "o") {
+ info.radix = 8;
+ } else if (info.format === "x" || info.format === "X") {
+ info.radix = 16;
+ }
+ flags = flags.substring(1);
+ break;
+ default:
+ var msg = "unsupported format flag: " + flags.charAt(0);
+ throw new self.FormatPatternError(pattern, startPos, msg);
+ }
+ }
+ return info;
+}
+
+/**
+ * Formats a value as a percentage. This method avoids multiplication
+ * by 100 since it leads to weird numeric rounding errors. Instead it
+ * just move the decimal separator in the text string. It is ugly,
+ * but works...
+ *
+ * @param {Number} value the value to format
+ * @param {Number} precision the number of precision digits
+ */
+MochiKit.Text._truncToPercent = function (value, precision) {
+ // TODO: This can be simplified by using the same helper function
+ // as roundToFixed now does.
+ var str;
+ if (precision >= 0) {
+ str = MochiKit.Format.roundToFixed(value, precision + 2);
+ } else {
+ str = (value == null) ? "0" : value.toString();
+ }
+ var fracPos = str.indexOf(".");
+ if (fracPos < 0) {
+ str = str + "00";
+ } else if (fracPos + 3 >= str.length) {
+ var fraction = str.substring(fracPos + 1);
+ while (fraction.length < 2) {
+ fraction = fraction + "0";
+ }
+ str = str.substring(0, fracPos) + fraction;
+ } else {
+ var fraction = str.substring(fracPos + 1);
+ str = str.substring(0, fracPos) + fraction.substring(0, 2) +
+ "." + fraction.substring(2);
+ }
+ while (str.length > 1 && str.charAt(0) == "0" && str.charAt(1) != ".") {
+ str = str.substring(1);
+ }
+ return str;
+}
+
+/**
+ * Creates a new format pattern error.
+ *
+ * @param {String} pattern the format pattern string
+ * @param {Number} pos the position of the error
+ * @param {String} message the error message text
+ *
+ * @return {Error} the format pattern error
+ *
+ * @class The format pattern error class. This error is thrown when
+ * a syntax error is encountered inside a format string.
+ * @property {String} pattern The format pattern string.
+ * @property {Number} pos The position of the error.
+ * @property {String} message The error message text.
+ * @extends MochiKit.Base.NamedError
+ */
+MochiKit.Text.FormatPatternError = function (pattern, pos, message) {
+ this.pattern = pattern;
+ this.pos = pos;
+ this.message = message;
+}
+MochiKit.Text.FormatPatternError.prototype =
+ new MochiKit.Base.NamedError("MochiKit.Text.FormatPatternError");
+
+
+//
+//XXX: Internet Explorer exception handling blows
+//
+if (MochiKit.__export__) {
+ formatter = MochiKit.Text.formatter;
+ format = MochiKit.Text.format;
+ formatValue = MochiKit.Text.formatValue;
+}
+
+
+MochiKit.Base.nameFunctions(MochiKit.Text);
+MochiKit.Base._exportSymbols(this, MochiKit.Text);
diff --git a/frontend/gamma/js/MochiKit/Visual.js b/frontend/gamma/js/MochiKit/Visual.js
new file mode 100644
index 0000000..648d82a
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/Visual.js
@@ -0,0 +1,1975 @@
+/***
+
+MochiKit.Visual 1.5
+
+See <http://mochikit.com/> for documentation, downloads, license, etc.
+
+(c) 2005 Bob Ippolito and others. All rights Reserved.
+
+***/
+
+MochiKit.Base._module('Visual', '1.5', ['Base', 'DOM', 'Style', 'Color', 'Position']);
+
+MochiKit.Visual._RoundCorners = function (e, options) {
+ e = MochiKit.DOM.getElement(e);
+ this._setOptions(options);
+ if (this.options.__unstable__wrapElement) {
+ e = this._doWrap(e);
+ }
+
+ var color = this.options.color;
+ var C = MochiKit.Color.Color;
+ if (this.options.color === "fromElement") {
+ color = C.fromBackground(e);
+ } else if (!(color instanceof C)) {
+ color = C.fromString(color);
+ }
+ this.isTransparent = (color.asRGB().a <= 0);
+
+ var bgColor = this.options.bgColor;
+ if (this.options.bgColor === "fromParent") {
+ bgColor = C.fromBackground(e.offsetParent);
+ } else if (!(bgColor instanceof C)) {
+ bgColor = C.fromString(bgColor);
+ }
+
+ this._roundCornersImpl(e, color, bgColor);
+};
+
+MochiKit.Visual._RoundCorners.prototype = {
+ _doWrap: function (e) {
+ var parent = e.parentNode;
+ var doc = MochiKit.DOM.currentDocument();
+ if (typeof(doc.defaultView) === "undefined"
+ || doc.defaultView === null) {
+ return e;
+ }
+ var style = doc.defaultView.getComputedStyle(e, null);
+ if (typeof(style) === "undefined" || style === null) {
+ return e;
+ }
+ var wrapper = MochiKit.DOM.DIV({"style": {
+ display: "block",
+ // convert padding to margin
+ marginTop: style.getPropertyValue("padding-top"),
+ marginRight: style.getPropertyValue("padding-right"),
+ marginBottom: style.getPropertyValue("padding-bottom"),
+ marginLeft: style.getPropertyValue("padding-left"),
+ // remove padding so the rounding looks right
+ padding: "0px"
+ /*
+ paddingRight: "0px",
+ paddingLeft: "0px"
+ */
+ }});
+ wrapper.innerHTML = e.innerHTML;
+ e.innerHTML = "";
+ e.appendChild(wrapper);
+ return e;
+ },
+
+ _roundCornersImpl: function (e, color, bgColor) {
+ if (this.options.border) {
+ this._renderBorder(e, bgColor);
+ }
+ if (this._isTopRounded()) {
+ this._roundTopCorners(e, color, bgColor);
+ }
+ if (this._isBottomRounded()) {
+ this._roundBottomCorners(e, color, bgColor);
+ }
+ },
+
+ _renderBorder: function (el, bgColor) {
+ var borderValue = "1px solid " + this._borderColor(bgColor);
+ var borderL = "border-left: " + borderValue;
+ var borderR = "border-right: " + borderValue;
+ var style = "style='" + borderL + ";" + borderR + "'";
+ el.innerHTML = "<div " + style + ">" + el.innerHTML + "</div>";
+ },
+
+ _roundTopCorners: function (el, color, bgColor) {
+ var corner = this._createCorner(bgColor);
+ for (var i = 0; i < this.options.numSlices; i++) {
+ corner.appendChild(
+ this._createCornerSlice(color, bgColor, i, "top")
+ );
+ }
+ el.style.paddingTop = 0;
+ el.insertBefore(corner, el.firstChild);
+ },
+
+ _roundBottomCorners: function (el, color, bgColor) {
+ var corner = this._createCorner(bgColor);
+ for (var i = (this.options.numSlices - 1); i >= 0; i--) {
+ corner.appendChild(
+ this._createCornerSlice(color, bgColor, i, "bottom")
+ );
+ }
+ el.style.paddingBottom = 0;
+ el.appendChild(corner);
+ },
+
+ _createCorner: function (bgColor) {
+ var dom = MochiKit.DOM;
+ return dom.DIV({style: {backgroundColor: bgColor.toString()}});
+ },
+
+ _createCornerSlice: function (color, bgColor, n, position) {
+ var slice = MochiKit.DOM.SPAN();
+
+ var inStyle = slice.style;
+ inStyle.backgroundColor = color.toString();
+ inStyle.display = "block";
+ inStyle.height = "1px";
+ inStyle.overflow = "hidden";
+ inStyle.fontSize = "1px";
+
+ var borderColor = this._borderColor(color, bgColor);
+ if (this.options.border && n === 0) {
+ inStyle.borderTopStyle = "solid";
+ inStyle.borderTopWidth = "1px";
+ inStyle.borderLeftWidth = "0px";
+ inStyle.borderRightWidth = "0px";
+ inStyle.borderBottomWidth = "0px";
+ // assumes css compliant box model
+ inStyle.height = "0px";
+ inStyle.borderColor = borderColor.toString();
+ } else if (borderColor) {
+ inStyle.borderColor = borderColor.toString();
+ inStyle.borderStyle = "solid";
+ inStyle.borderWidth = "0px 1px";
+ }
+
+ if (!this.options.compact && (n == (this.options.numSlices - 1))) {
+ inStyle.height = "2px";
+ }
+
+ this._setMargin(slice, n, position);
+ this._setBorder(slice, n, position);
+
+ return slice;
+ },
+
+ _setOptions: function (options) {
+ this.options = {
+ corners: "all",
+ color: "fromElement",
+ bgColor: "fromParent",
+ blend: true,
+ border: false,
+ compact: false,
+ __unstable__wrapElement: false
+ };
+ MochiKit.Base.update(this.options, options);
+
+ this.options.numSlices = (this.options.compact ? 2 : 4);
+ },
+
+ _whichSideTop: function () {
+ var corners = this.options.corners;
+ if (this._hasString(corners, "all", "top")) {
+ return "";
+ }
+
+ var has_tl = (corners.indexOf("tl") != -1);
+ var has_tr = (corners.indexOf("tr") != -1);
+ if (has_tl && has_tr) {
+ return "";
+ }
+ if (has_tl) {
+ return "left";
+ }
+ if (has_tr) {
+ return "right";
+ }
+ return "";
+ },
+
+ _whichSideBottom: function () {
+ var corners = this.options.corners;
+ if (this._hasString(corners, "all", "bottom")) {
+ return "";
+ }
+
+ var has_bl = (corners.indexOf('bl') != -1);
+ var has_br = (corners.indexOf('br') != -1);
+ if (has_bl && has_br) {
+ return "";
+ }
+ if (has_bl) {
+ return "left";
+ }
+ if (has_br) {
+ return "right";
+ }
+ return "";
+ },
+
+ _borderColor: function (color, bgColor) {
+ if (color == "transparent") {
+ return bgColor;
+ } else if (this.options.border) {
+ return this.options.border;
+ } else if (this.options.blend) {
+ return bgColor.blendedColor(color);
+ }
+ return "";
+ },
+
+
+ _setMargin: function (el, n, corners) {
+ var marginSize = this._marginSize(n) + "px";
+ var whichSide = (
+ corners == "top" ? this._whichSideTop() : this._whichSideBottom()
+ );
+ var style = el.style;
+
+ if (whichSide == "left") {
+ style.marginLeft = marginSize;
+ style.marginRight = "0px";
+ } else if (whichSide == "right") {
+ style.marginRight = marginSize;
+ style.marginLeft = "0px";
+ } else {
+ style.marginLeft = marginSize;
+ style.marginRight = marginSize;
+ }
+ },
+
+ _setBorder: function (el, n, corners) {
+ var borderSize = this._borderSize(n) + "px";
+ var whichSide = (
+ corners == "top" ? this._whichSideTop() : this._whichSideBottom()
+ );
+
+ var style = el.style;
+ if (whichSide == "left") {
+ style.borderLeftWidth = borderSize;
+ style.borderRightWidth = "0px";
+ } else if (whichSide == "right") {
+ style.borderRightWidth = borderSize;
+ style.borderLeftWidth = "0px";
+ } else {
+ style.borderLeftWidth = borderSize;
+ style.borderRightWidth = borderSize;
+ }
+ },
+
+ _marginSize: function (n) {
+ if (this.isTransparent) {
+ return 0;
+ }
+
+ var o = this.options;
+ if (o.compact && o.blend) {
+ var smBlendedMarginSizes = [1, 0];
+ return smBlendedMarginSizes[n];
+ } else if (o.compact) {
+ var compactMarginSizes = [2, 1];
+ return compactMarginSizes[n];
+ } else if (o.blend) {
+ var blendedMarginSizes = [3, 2, 1, 0];
+ return blendedMarginSizes[n];
+ } else {
+ var marginSizes = [5, 3, 2, 1];
+ return marginSizes[n];
+ }
+ },
+
+ _borderSize: function (n) {
+ var o = this.options;
+ var borderSizes;
+ if (o.compact && (o.blend || this.isTransparent)) {
+ return 1;
+ } else if (o.compact) {
+ borderSizes = [1, 0];
+ } else if (o.blend) {
+ borderSizes = [2, 1, 1, 1];
+ } else if (o.border) {
+ borderSizes = [0, 2, 0, 0];
+ } else if (this.isTransparent) {
+ borderSizes = [5, 3, 2, 1];
+ } else {
+ return 0;
+ }
+ return borderSizes[n];
+ },
+
+ _hasString: function (str) {
+ for (var i = 1; i< arguments.length; i++) {
+ if (str.indexOf(arguments[i]) != -1) {
+ return true;
+ }
+ }
+ return false;
+ },
+
+ _isTopRounded: function () {
+ return this._hasString(this.options.corners,
+ "all", "top", "tl", "tr"
+ );
+ },
+
+ _isBottomRounded: function () {
+ return this._hasString(this.options.corners,
+ "all", "bottom", "bl", "br"
+ );
+ },
+
+ _hasSingleTextChild: function (el) {
+ return (el.childNodes.length == 1 && el.childNodes[0].nodeType == 3);
+ }
+};
+
+/** @id MochiKit.Visual.roundElement */
+MochiKit.Visual.roundElement = function (e, options) {
+ new MochiKit.Visual._RoundCorners(e, options);
+};
+
+/** @id MochiKit.Visual.roundClass */
+MochiKit.Visual.roundClass = function (tagName, className, options) {
+ var elements = MochiKit.DOM.getElementsByTagAndClassName(
+ tagName, className
+ );
+ for (var i = 0; i < elements.length; i++) {
+ MochiKit.Visual.roundElement(elements[i], options);
+ }
+};
+
+/** @id MochiKit.Visual.tagifyText */
+MochiKit.Visual.tagifyText = function (element, /* optional */tagifyStyle) {
+ /***
+
+ Change a node text to character in tags.
+
+ @param tagifyStyle: the style to apply to character nodes, default to
+ 'position: relative'.
+
+ ***/
+ tagifyStyle = tagifyStyle || 'position:relative';
+ if (/MSIE/.test(navigator.userAgent)) {
+ tagifyStyle += ';zoom:1';
+ }
+ element = MochiKit.DOM.getElement(element);
+ var ma = MochiKit.Base.map;
+ ma(function (child) {
+ if (child.nodeType == 3) {
+ ma(function (character) {
+ element.insertBefore(
+ MochiKit.DOM.SPAN({style: tagifyStyle},
+ character == ' ' ? String.fromCharCode(160) : character), child);
+ }, child.nodeValue.split(''));
+ MochiKit.DOM.removeElement(child);
+ }
+ }, element.childNodes);
+};
+
+MochiKit.Visual._forceRerendering = function (element) {
+ try {
+ element = MochiKit.DOM.getElement(element);
+ var n = document.createTextNode(' ');
+ element.appendChild(n);
+ element.removeChild(n);
+ } catch(e) {
+ }
+};
+
+/** @id MochiKit.Visual.multiple */
+MochiKit.Visual.multiple = function (elements, effect, /* optional */options) {
+ /***
+
+ Launch the same effect subsequently on given elements.
+
+ ***/
+ options = MochiKit.Base.update({
+ speed: 0.1, delay: 0.0
+ }, options);
+ var masterDelay = options.delay;
+ var index = 0;
+ MochiKit.Base.map(function (innerelement) {
+ options.delay = index * options.speed + masterDelay;
+ new effect(innerelement, options);
+ index += 1;
+ }, elements);
+};
+
+MochiKit.Visual.PAIRS = {
+ 'slide': ['slideDown', 'slideUp'],
+ 'blind': ['blindDown', 'blindUp'],
+ 'appear': ['appear', 'fade'],
+ 'size': ['grow', 'shrink']
+};
+
+/** @id MochiKit.Visual.toggle */
+MochiKit.Visual.toggle = function (element, /* optional */effect, /* optional */options) {
+ /***
+
+ Toggle an item between two state depending of its visibility, making
+ a effect between these states. Default effect is 'appear', can be
+ 'slide' or 'blind'.
+
+ ***/
+ element = MochiKit.DOM.getElement(element);
+ effect = (effect || 'appear').toLowerCase();
+ options = MochiKit.Base.update({
+ queue: {position: 'end', scope: (element.id || 'global'), limit: 1}
+ }, options);
+ var v = MochiKit.Visual;
+ v[MochiKit.Style.getStyle(element, 'display') != 'none' ?
+ v.PAIRS[effect][1] : v.PAIRS[effect][0]](element, options);
+};
+
+/***
+
+Transitions: define functions calculating variations depending of a position.
+
+***/
+
+MochiKit.Visual.Transitions = { __export__: false };
+
+/** @id MochiKit.Visual.Transitions.linear */
+MochiKit.Visual.Transitions.linear = function (pos) {
+ return pos;
+};
+
+/** @id MochiKit.Visual.Transitions.sinoidal */
+MochiKit.Visual.Transitions.sinoidal = function (pos) {
+ return 0.5 - Math.cos(pos*Math.PI)/2;
+};
+
+/** @id MochiKit.Visual.Transitions.reverse */
+MochiKit.Visual.Transitions.reverse = function (pos) {
+ return 1 - pos;
+};
+
+/** @id MochiKit.Visual.Transitions.flicker */
+MochiKit.Visual.Transitions.flicker = function (pos) {
+ return 0.25 - Math.cos(pos*Math.PI)/4 + Math.random()/2;
+};
+
+/** @id MochiKit.Visual.Transitions.wobble */
+MochiKit.Visual.Transitions.wobble = function (pos) {
+ return 0.5 - Math.cos(9*pos*Math.PI)/2;
+};
+
+/** @id MochiKit.Visual.Transitions.pulse */
+MochiKit.Visual.Transitions.pulse = function (pos, pulses) {
+ if (pulses) {
+ pos *= 2 * pulses;
+ } else {
+ pos *= 10;
+ }
+ var decimals = pos - Math.floor(pos);
+ return (Math.floor(pos) % 2 == 0) ? decimals : 1 - decimals;
+};
+
+/** @id MochiKit.Visual.Transitions.parabolic */
+MochiKit.Visual.Transitions.parabolic = function (pos) {
+ return pos * pos;
+};
+
+/** @id MochiKit.Visual.Transitions.none */
+MochiKit.Visual.Transitions.none = function (pos) {
+ return 0;
+};
+
+/** @id MochiKit.Visual.Transitions.full */
+MochiKit.Visual.Transitions.full = function (pos) {
+ return 1;
+};
+
+/***
+
+Core effects
+
+***/
+
+MochiKit.Visual.ScopedQueue = function () {
+ var cls = arguments.callee;
+ if (!(this instanceof cls)) {
+ return new cls();
+ }
+ this.__init__();
+};
+MochiKit.Visual.ScopedQueue.__export__ = false;
+
+MochiKit.Base.update(MochiKit.Visual.ScopedQueue.prototype, {
+ __init__: function () {
+ this.effects = [];
+ this.interval = null;
+ },
+
+ /** @id MochiKit.Visual.ScopedQueue.prototype.add */
+ add: function (effect) {
+ var timestamp = new Date().getTime();
+
+ var position = (typeof(effect.options.queue) == 'string') ?
+ effect.options.queue : effect.options.queue.position;
+
+ var ma = MochiKit.Base.map;
+ switch (position) {
+ case 'front':
+ // move unstarted effects after this effect
+ ma(function (e) {
+ if (e.state == 'idle') {
+ e.startOn += effect.finishOn;
+ e.finishOn += effect.finishOn;
+ }
+ }, this.effects);
+ break;
+ case 'end':
+ var finish;
+ // start effect after last queued effect has finished
+ ma(function (e) {
+ var i = e.finishOn;
+ if (i >= (finish || i)) {
+ finish = i;
+ }
+ }, this.effects);
+ timestamp = finish || timestamp;
+ break;
+ case 'break':
+ ma(function (e) {
+ e.finalize();
+ }, this.effects);
+ break;
+ }
+
+ effect.startOn += timestamp;
+ effect.finishOn += timestamp;
+ if (!effect.options.queue.limit ||
+ this.effects.length < effect.options.queue.limit) {
+ this.effects.push(effect);
+ }
+
+ if (!this.interval) {
+ this.interval = this.startLoop(MochiKit.Base.bind(this.loop, this),
+ 40);
+ }
+ },
+
+ /** @id MochiKit.Visual.ScopedQueue.prototype.startLoop */
+ startLoop: function (func, interval) {
+ return setInterval(func, interval);
+ },
+
+ /** @id MochiKit.Visual.ScopedQueue.prototype.remove */
+ remove: function (effect) {
+ this.effects = MochiKit.Base.filter(function (e) {
+ return e != effect;
+ }, this.effects);
+ if (!this.effects.length) {
+ this.stopLoop(this.interval);
+ this.interval = null;
+ }
+ },
+
+ /** @id MochiKit.Visual.ScopedQueue.prototype.stopLoop */
+ stopLoop: function (interval) {
+ clearInterval(interval);
+ },
+
+ /** @id MochiKit.Visual.ScopedQueue.prototype.loop */
+ loop: function () {
+ var timePos = new Date().getTime();
+ MochiKit.Base.map(function (effect) {
+ effect.loop(timePos);
+ }, this.effects);
+ }
+});
+
+MochiKit.Visual.Queues = {
+ __export__: false,
+ instances: {},
+ get: function (queueName) {
+ if (typeof(queueName) != 'string') {
+ return queueName;
+ }
+
+ if (!this.instances[queueName]) {
+ this.instances[queueName] = new MochiKit.Visual.ScopedQueue();
+ }
+ return this.instances[queueName];
+ }
+};
+
+MochiKit.Visual.Queue = MochiKit.Visual.Queues.get('global');
+MochiKit.Visual.Queue.__export__ = false;
+
+MochiKit.Visual.DefaultOptions = {
+ __export__: false,
+ transition: MochiKit.Visual.Transitions.sinoidal,
+ duration: 1.0, // seconds
+ fps: 25.0, // max. 25fps due to MochiKit.Visual.Queue implementation
+ sync: false, // true for combining
+ from: 0.0,
+ to: 1.0,
+ delay: 0.0,
+ queue: 'parallel'
+};
+
+MochiKit.Visual.Base = function () {};
+
+MochiKit.Visual.Base.prototype = {
+ /***
+
+ Basic class for all Effects. Define a looping mechanism called for each step
+ of an effect. Don't instantiate it, only subclass it.
+
+ ***/
+
+ __class__ : MochiKit.Visual.Base,
+
+ /** @id MochiKit.Visual.Base.prototype.start */
+ start: function (options) {
+ var v = MochiKit.Visual;
+ this.options = MochiKit.Base.setdefault(options,
+ v.DefaultOptions);
+ this.currentFrame = 0;
+ this.state = 'idle';
+ this.startOn = this.options.delay*1000;
+ this.finishOn = this.startOn + (this.options.duration*1000);
+ this.event('beforeStart');
+ if (!this.options.sync) {
+ v.Queues.get(typeof(this.options.queue) == 'string' ?
+ 'global' : this.options.queue.scope).add(this);
+ }
+ },
+
+ /** @id MochiKit.Visual.Base.prototype.loop */
+ loop: function (timePos) {
+ if (timePos >= this.startOn) {
+ if (timePos >= this.finishOn) {
+ return this.finalize();
+ }
+ var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
+ var frame =
+ Math.round(pos * this.options.fps * this.options.duration);
+ if (frame > this.currentFrame) {
+ this.render(pos);
+ this.currentFrame = frame;
+ }
+ }
+ },
+
+ /** @id MochiKit.Visual.Base.prototype.render */
+ render: function (pos) {
+ if (this.state == 'idle') {
+ this.state = 'running';
+ this.event('beforeSetup');
+ this.setup();
+ this.event('afterSetup');
+ }
+ if (this.state == 'running') {
+ if (this.options.transition) {
+ pos = this.options.transition(pos);
+ }
+ pos *= (this.options.to - this.options.from);
+ pos += this.options.from;
+ this.event('beforeUpdate');
+ this.update(pos);
+ this.event('afterUpdate');
+ }
+ },
+
+ /** @id MochiKit.Visual.Base.prototype.cancel */
+ cancel: function () {
+ if (!this.options.sync) {
+ MochiKit.Visual.Queues.get(typeof(this.options.queue) == 'string' ?
+ 'global' : this.options.queue.scope).remove(this);
+ }
+ this.state = 'finished';
+ },
+
+ /** @id MochiKit.Visual.Base.prototype.finalize */
+ finalize: function () {
+ this.render(1.0);
+ this.cancel();
+ this.event('beforeFinish');
+ this.finish();
+ this.event('afterFinish');
+ },
+
+ setup: function () {
+ },
+
+ finish: function () {
+ },
+
+ update: function (position) {
+ },
+
+ /** @id MochiKit.Visual.Base.prototype.event */
+ event: function (eventName) {
+ if (this.options[eventName + 'Internal']) {
+ this.options[eventName + 'Internal'](this);
+ }
+ if (this.options[eventName]) {
+ this.options[eventName](this);
+ }
+ },
+
+ /** @id MochiKit.Visual.Base.prototype.repr */
+ repr: function () {
+ return '[' + this.__class__.NAME + ', options:' +
+ MochiKit.Base.repr(this.options) + ']';
+ }
+};
+
+/** @id MochiKit.Visual.Parallel */
+MochiKit.Visual.Parallel = function (effects, options) {
+ var cls = arguments.callee;
+ if (!(this instanceof cls)) {
+ return new cls(effects, options);
+ }
+
+ this.__init__(effects, options);
+};
+
+MochiKit.Visual.Parallel.prototype = new MochiKit.Visual.Base();
+
+MochiKit.Base.update(MochiKit.Visual.Parallel.prototype, {
+ /***
+
+ Run multiple effects at the same time.
+
+ ***/
+
+ __class__ : MochiKit.Visual.Parallel,
+
+ __init__: function (effects, options) {
+ this.effects = effects || [];
+ this.start(options);
+ },
+
+ /** @id MochiKit.Visual.Parallel.prototype.update */
+ update: function (position) {
+ MochiKit.Base.map(function (effect) {
+ effect.render(position);
+ }, this.effects);
+ },
+
+ /** @id MochiKit.Visual.Parallel.prototype.finish */
+ finish: function () {
+ MochiKit.Base.map(function (effect) {
+ effect.finalize();
+ }, this.effects);
+ }
+});
+
+/** @id MochiKit.Visual.Sequence */
+MochiKit.Visual.Sequence = function (effects, options) {
+ var cls = arguments.callee;
+ if (!(this instanceof cls)) {
+ return new cls(effects, options);
+ }
+ this.__init__(effects, options);
+};
+
+MochiKit.Visual.Sequence.prototype = new MochiKit.Visual.Base();
+
+MochiKit.Base.update(MochiKit.Visual.Sequence.prototype, {
+
+ __class__ : MochiKit.Visual.Sequence,
+
+ __init__: function (effects, options) {
+ var defs = { transition: MochiKit.Visual.Transitions.linear,
+ duration: 0 };
+ this.effects = effects || [];
+ MochiKit.Base.map(function (effect) {
+ defs.duration += effect.options.duration;
+ }, this.effects);
+ MochiKit.Base.setdefault(options, defs);
+ this.start(options);
+ },
+
+ /** @id MochiKit.Visual.Sequence.prototype.update */
+ update: function (position) {
+ var time = position * this.options.duration;
+ for (var i = 0; i < this.effects.length; i++) {
+ var effect = this.effects[i];
+ if (time <= effect.options.duration) {
+ effect.render(time / effect.options.duration);
+ break;
+ } else {
+ time -= effect.options.duration;
+ }
+ }
+ },
+
+ /** @id MochiKit.Visual.Sequence.prototype.finish */
+ finish: function () {
+ MochiKit.Base.map(function (effect) {
+ effect.finalize();
+ }, this.effects);
+ }
+});
+
+/** @id MochiKit.Visual.Opacity */
+MochiKit.Visual.Opacity = function (element, options) {
+ var cls = arguments.callee;
+ if (!(this instanceof cls)) {
+ return new cls(element, options);
+ }
+ this.__init__(element, options);
+};
+
+MochiKit.Visual.Opacity.prototype = new MochiKit.Visual.Base();
+
+MochiKit.Base.update(MochiKit.Visual.Opacity.prototype, {
+ /***
+
+ Change the opacity of an element.
+
+ @param options: 'from' and 'to' change the starting and ending opacities.
+ Must be between 0.0 and 1.0. Default to current opacity and 1.0.
+
+ ***/
+
+ __class__ : MochiKit.Visual.Opacity,
+
+ __init__: function (element, /* optional */options) {
+ var b = MochiKit.Base;
+ var s = MochiKit.Style;
+ this.element = MochiKit.DOM.getElement(element);
+ // make this work on IE on elements without 'layout'
+ if (this.element.currentStyle &&
+ (!this.element.currentStyle.hasLayout)) {
+ s.setStyle(this.element, {zoom: 1});
+ }
+ options = b.update({
+ from: s.getStyle(this.element, 'opacity') || 0.0,
+ to: 1.0
+ }, options);
+ this.start(options);
+ },
+
+ /** @id MochiKit.Visual.Opacity.prototype.update */
+ update: function (position) {
+ MochiKit.Style.setStyle(this.element, {'opacity': position});
+ }
+});
+
+/** @id MochiKit.Visual.Move.prototype */
+MochiKit.Visual.Move = function (element, options) {
+ var cls = arguments.callee;
+ if (!(this instanceof cls)) {
+ return new cls(element, options);
+ }
+ this.__init__(element, options);
+};
+
+MochiKit.Visual.Move.prototype = new MochiKit.Visual.Base();
+
+MochiKit.Base.update(MochiKit.Visual.Move.prototype, {
+ /***
+
+ Move an element between its current position to a defined position
+
+ @param options: 'x' and 'y' for final positions, default to 0, 0.
+
+ ***/
+
+ __class__ : MochiKit.Visual.Move,
+
+ __init__: function (element, /* optional */options) {
+ this.element = MochiKit.DOM.getElement(element);
+ options = MochiKit.Base.update({
+ x: 0,
+ y: 0,
+ mode: 'relative'
+ }, options);
+ this.start(options);
+ },
+
+ /** @id MochiKit.Visual.Move.prototype.setup */
+ setup: function () {
+ // Bug in Opera: Opera returns the 'real' position of a static element
+ // or relative element that does not have top/left explicitly set.
+ // ==> Always set top and left for position relative elements in your
+ // stylesheets (to 0 if you do not need them)
+ MochiKit.Style.makePositioned(this.element);
+
+ var s = this.element.style;
+ var originalVisibility = s.visibility;
+ var originalDisplay = s.display;
+ if (originalDisplay == 'none') {
+ s.visibility = 'hidden';
+ s.display = '';
+ }
+
+ this.originalLeft = parseFloat(MochiKit.Style.getStyle(this.element, 'left') || '0');
+ this.originalTop = parseFloat(MochiKit.Style.getStyle(this.element, 'top') || '0');
+
+ if (this.options.mode == 'absolute') {
+ // absolute movement, so we need to calc deltaX and deltaY
+ this.options.x -= this.originalLeft;
+ this.options.y -= this.originalTop;
+ }
+ if (originalDisplay == 'none') {
+ s.visibility = originalVisibility;
+ s.display = originalDisplay;
+ }
+ },
+
+ /** @id MochiKit.Visual.Move.prototype.update */
+ update: function (position) {
+ MochiKit.Style.setStyle(this.element, {
+ left: Math.round(this.options.x * position + this.originalLeft) + 'px',
+ top: Math.round(this.options.y * position + this.originalTop) + 'px'
+ });
+ }
+});
+
+/** @id MochiKit.Visual.Scale */
+MochiKit.Visual.Scale = function (element, percent, options) {
+ var cls = arguments.callee;
+ if (!(this instanceof cls)) {
+ return new cls(element, percent, options);
+ }
+ this.__init__(element, percent, options);
+};
+
+MochiKit.Visual.Scale.prototype = new MochiKit.Visual.Base();
+
+MochiKit.Base.update(MochiKit.Visual.Scale.prototype, {
+ /***
+
+ Change the size of an element.
+
+ @param percent: final_size = percent*original_size
+
+ @param options: several options changing scale behaviour
+
+ ***/
+
+ __class__ : MochiKit.Visual.Scale,
+
+ __init__: function (element, percent, /* optional */options) {
+ this.element = MochiKit.DOM.getElement(element);
+ options = MochiKit.Base.update({
+ scaleX: true,
+ scaleY: true,
+ scaleContent: true,
+ scaleFromCenter: false,
+ scaleMode: 'box', // 'box' or 'contents' or {} with provided values
+ scaleFrom: 100.0,
+ scaleTo: percent
+ }, options);
+ this.start(options);
+ },
+
+ /** @id MochiKit.Visual.Scale.prototype.setup */
+ setup: function () {
+ this.restoreAfterFinish = this.options.restoreAfterFinish || false;
+ this.elementPositioning = MochiKit.Style.getStyle(this.element,
+ 'position');
+
+ var ma = MochiKit.Base.map;
+ var b = MochiKit.Base.bind;
+ this.originalStyle = {};
+ ma(b(function (k) {
+ this.originalStyle[k] = this.element.style[k];
+ }, this), ['top', 'left', 'width', 'height', 'fontSize']);
+
+ this.originalTop = this.element.offsetTop;
+ this.originalLeft = this.element.offsetLeft;
+
+ var fontSize = MochiKit.Style.getStyle(this.element,
+ 'font-size') || '100%';
+ ma(b(function (fontSizeType) {
+ if (fontSize.indexOf(fontSizeType) > 0) {
+ this.fontSize = parseFloat(fontSize);
+ this.fontSizeType = fontSizeType;
+ }
+ }, this), ['em', 'px', '%']);
+
+ this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
+
+ if (/^content/.test(this.options.scaleMode)) {
+ this.dims = [this.element.scrollHeight, this.element.scrollWidth];
+ } else if (this.options.scaleMode == 'box') {
+ this.dims = [this.element.offsetHeight, this.element.offsetWidth];
+ } else {
+ this.dims = [this.options.scaleMode.originalHeight,
+ this.options.scaleMode.originalWidth];
+ }
+ },
+
+ /** @id MochiKit.Visual.Scale.prototype.update */
+ update: function (position) {
+ var currentScale = (this.options.scaleFrom/100.0) +
+ (this.factor * position);
+ if (this.options.scaleContent && this.fontSize) {
+ MochiKit.Style.setStyle(this.element, {
+ fontSize: this.fontSize * currentScale + this.fontSizeType
+ });
+ }
+ this.setDimensions(this.dims[0] * currentScale,
+ this.dims[1] * currentScale);
+ },
+
+ /** @id MochiKit.Visual.Scale.prototype.finish */
+ finish: function () {
+ if (this.restoreAfterFinish) {
+ MochiKit.Style.setStyle(this.element, this.originalStyle);
+ }
+ },
+
+ /** @id MochiKit.Visual.Scale.prototype.setDimensions */
+ setDimensions: function (height, width) {
+ var d = {};
+ var r = Math.round;
+ if (/MSIE/.test(navigator.userAgent)) {
+ r = Math.ceil;
+ }
+ if (this.options.scaleX) {
+ d.width = r(width) + 'px';
+ }
+ if (this.options.scaleY) {
+ d.height = r(height) + 'px';
+ }
+ if (this.options.scaleFromCenter) {
+ var topd = (height - this.dims[0])/2;
+ var leftd = (width - this.dims[1])/2;
+ if (this.elementPositioning == 'absolute') {
+ if (this.options.scaleY) {
+ d.top = this.originalTop - topd + 'px';
+ }
+ if (this.options.scaleX) {
+ d.left = this.originalLeft - leftd + 'px';
+ }
+ } else {
+ if (this.options.scaleY) {
+ d.top = -topd + 'px';
+ }
+ if (this.options.scaleX) {
+ d.left = -leftd + 'px';
+ }
+ }
+ }
+ MochiKit.Style.setStyle(this.element, d);
+ }
+});
+
+/** @id MochiKit.Visual.Highlight */
+MochiKit.Visual.Highlight = function (element, options) {
+ var cls = arguments.callee;
+ if (!(this instanceof cls)) {
+ return new cls(element, options);
+ }
+ this.__init__(element, options);
+};
+
+MochiKit.Visual.Highlight.prototype = new MochiKit.Visual.Base();
+
+MochiKit.Base.update(MochiKit.Visual.Highlight.prototype, {
+ /***
+
+ Highlight an item of the page.
+
+ @param options: 'startcolor' for choosing highlighting color, default
+ to '#ffff99'.
+
+ ***/
+
+ __class__ : MochiKit.Visual.Highlight,
+
+ __init__: function (element, /* optional */options) {
+ this.element = MochiKit.DOM.getElement(element);
+ options = MochiKit.Base.update({
+ startcolor: '#ffff99'
+ }, options);
+ this.start(options);
+ },
+
+ /** @id MochiKit.Visual.Highlight.prototype.setup */
+ setup: function () {
+ var b = MochiKit.Base;
+ var s = MochiKit.Style;
+ // Prevent executing on elements not in the layout flow
+ if (s.getStyle(this.element, 'display') == 'none') {
+ this.cancel();
+ return;
+ }
+ // Disable background image during the effect
+ this.oldStyle = {
+ backgroundImage: s.getStyle(this.element, 'background-image')
+ };
+ s.setStyle(this.element, {
+ backgroundImage: 'none'
+ });
+
+ if (!this.options.endcolor) {
+ this.options.endcolor =
+ MochiKit.Color.Color.fromBackground(this.element).toHexString();
+ }
+ if (b.isUndefinedOrNull(this.options.restorecolor)) {
+ this.options.restorecolor = s.getStyle(this.element,
+ 'background-color');
+ }
+ // init color calculations
+ this._base = b.map(b.bind(function (i) {
+ return parseInt(
+ this.options.startcolor.slice(i*2 + 1, i*2 + 3), 16);
+ }, this), [0, 1, 2]);
+ this._delta = b.map(b.bind(function (i) {
+ return parseInt(this.options.endcolor.slice(i*2 + 1, i*2 + 3), 16)
+ - this._base[i];
+ }, this), [0, 1, 2]);
+ },
+
+ /** @id MochiKit.Visual.Highlight.prototype.update */
+ update: function (position) {
+ var m = '#';
+ MochiKit.Base.map(MochiKit.Base.bind(function (i) {
+ m += MochiKit.Color.toColorPart(Math.round(this._base[i] +
+ this._delta[i]*position));
+ }, this), [0, 1, 2]);
+ MochiKit.Style.setStyle(this.element, {
+ backgroundColor: m
+ });
+ },
+
+ /** @id MochiKit.Visual.Highlight.prototype.finish */
+ finish: function () {
+ MochiKit.Style.setStyle(this.element,
+ MochiKit.Base.update(this.oldStyle, {
+ backgroundColor: this.options.restorecolor
+ }));
+ }
+});
+
+/** @id MochiKit.Visual.ScrollTo */
+MochiKit.Visual.ScrollTo = function (element, options) {
+ var cls = arguments.callee;
+ if (!(this instanceof cls)) {
+ return new cls(element, options);
+ }
+ this.__init__(element, options);
+};
+
+MochiKit.Visual.ScrollTo.prototype = new MochiKit.Visual.Base();
+
+MochiKit.Base.update(MochiKit.Visual.ScrollTo.prototype, {
+ /***
+
+ Scroll to an element in the page.
+
+ ***/
+
+ __class__ : MochiKit.Visual.ScrollTo,
+
+ __init__: function (element, /* optional */options) {
+ this.element = MochiKit.DOM.getElement(element);
+ this.start(options);
+ },
+
+ /** @id MochiKit.Visual.ScrollTo.prototype.setup */
+ setup: function () {
+ var p = MochiKit.Position;
+ p.prepare();
+ var offsets = p.cumulativeOffset(this.element);
+ if (this.options.offset) {
+ offsets.y += this.options.offset;
+ }
+ var max;
+ if (window.innerHeight) {
+ max = window.innerHeight - window.height;
+ } else if (document.documentElement &&
+ document.documentElement.clientHeight) {
+ max = document.documentElement.clientHeight -
+ document.body.scrollHeight;
+ } else if (document.body) {
+ max = document.body.clientHeight - document.body.scrollHeight;
+ }
+ this.scrollStart = p.windowOffset.y;
+ this.delta = (offsets.y > max ? max : offsets.y) - this.scrollStart;
+ },
+
+ /** @id MochiKit.Visual.ScrollTo.prototype.update */
+ update: function (position) {
+ var p = MochiKit.Position;
+ p.prepare();
+ window.scrollTo(p.windowOffset.x, this.scrollStart + (position * this.delta));
+ }
+});
+
+MochiKit.Visual._CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
+
+MochiKit.Visual.Morph = function (element, options) {
+ var cls = arguments.callee;
+ if (!(this instanceof cls)) {
+ return new cls(element, options);
+ }
+ this.__init__(element, options);
+};
+
+MochiKit.Visual.Morph.prototype = new MochiKit.Visual.Base();
+
+MochiKit.Base.update(MochiKit.Visual.Morph.prototype, {
+ /***
+
+ Morph effect: make a transformation from current style to the given style,
+ automatically making a transition between the two.
+
+ ***/
+
+ __class__ : MochiKit.Visual.Morph,
+
+ __init__: function (element, /* optional */options) {
+ this.element = MochiKit.DOM.getElement(element);
+ this.start(options);
+ },
+
+ /** @id MochiKit.Visual.Morph.prototype.setup */
+ setup: function () {
+ var b = MochiKit.Base;
+ var style = this.options.style;
+ this.styleStart = {};
+ this.styleEnd = {};
+ this.units = {};
+ var value, unit;
+ for (var s in style) {
+ value = style[s];
+ s = b.camelize(s);
+ if (MochiKit.Visual._CSS_LENGTH.test(value)) {
+ var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
+ value = parseFloat(components[1]);
+ unit = (components.length == 3) ? components[2] : null;
+ this.styleEnd[s] = value;
+ this.units[s] = unit;
+ value = MochiKit.Style.getStyle(this.element, s);
+ components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
+ value = parseFloat(components[1]);
+ this.styleStart[s] = value;
+ } else if (/[Cc]olor$/.test(s)) {
+ var c = MochiKit.Color.Color;
+ value = c.fromString(value);
+ if (value) {
+ this.units[s] = "color";
+ this.styleEnd[s] = value.toHexString();
+ value = MochiKit.Style.getStyle(this.element, s);
+ this.styleStart[s] = c.fromString(value).toHexString();
+
+ this.styleStart[s] = b.map(b.bind(function (i) {
+ return parseInt(
+ this.styleStart[s].slice(i*2 + 1, i*2 + 3), 16);
+ }, this), [0, 1, 2]);
+ this.styleEnd[s] = b.map(b.bind(function (i) {
+ return parseInt(
+ this.styleEnd[s].slice(i*2 + 1, i*2 + 3), 16);
+ }, this), [0, 1, 2]);
+ }
+ } else {
+ // For non-length & non-color properties, we just set the value
+ this.element.style[s] = value;
+ }
+ }
+ },
+
+ /** @id MochiKit.Visual.Morph.prototype.update */
+ update: function (position) {
+ var value;
+ for (var s in this.styleStart) {
+ if (this.units[s] == "color") {
+ var m = '#';
+ var start = this.styleStart[s];
+ var end = this.styleEnd[s];
+ MochiKit.Base.map(MochiKit.Base.bind(function (i) {
+ m += MochiKit.Color.toColorPart(Math.round(start[i] +
+ (end[i] - start[i])*position));
+ }, this), [0, 1, 2]);
+ this.element.style[s] = m;
+ } else {
+ value = this.styleStart[s] + Math.round((this.styleEnd[s] - this.styleStart[s]) * position * 1000) / 1000 + this.units[s];
+ this.element.style[s] = value;
+ }
+ }
+ }
+});
+
+/***
+
+Combination effects.
+
+***/
+
+/** @id MochiKit.Visual.fade */
+MochiKit.Visual.fade = function (element, /* optional */ options) {
+ /***
+
+ Fade a given element: change its opacity and hide it in the end.
+
+ @param options: 'to' and 'from' to change opacity.
+
+ ***/
+ var s = MochiKit.Style;
+ var oldOpacity = s.getStyle(element, 'opacity');
+ options = MochiKit.Base.update({
+ from: s.getStyle(element, 'opacity') || 1.0,
+ to: 0.0,
+ afterFinishInternal: function (effect) {
+ if (effect.options.to !== 0) {
+ return;
+ }
+ s.hideElement(effect.element);
+ s.setStyle(effect.element, {'opacity': oldOpacity});
+ }
+ }, options);
+ return new MochiKit.Visual.Opacity(element, options);
+};
+
+/** @id MochiKit.Visual.appear */
+MochiKit.Visual.appear = function (element, /* optional */ options) {
+ /***
+
+ Make an element appear.
+
+ @param options: 'to' and 'from' to change opacity.
+
+ ***/
+ var s = MochiKit.Style;
+ var v = MochiKit.Visual;
+ options = MochiKit.Base.update({
+ from: (s.getStyle(element, 'display') == 'none' ? 0.0 :
+ s.getStyle(element, 'opacity') || 0.0),
+ to: 1.0,
+ // force Safari to render floated elements properly
+ afterFinishInternal: function (effect) {
+ v._forceRerendering(effect.element);
+ },
+ beforeSetupInternal: function (effect) {
+ s.setStyle(effect.element, {'opacity': effect.options.from});
+ s.showElement(effect.element);
+ }
+ }, options);
+ return new v.Opacity(element, options);
+};
+
+/** @id MochiKit.Visual.puff */
+MochiKit.Visual.puff = function (element, /* optional */ options) {
+ /***
+
+ 'Puff' an element: grow it to double size, fading it and make it hidden.
+
+ ***/
+ var s = MochiKit.Style;
+ var v = MochiKit.Visual;
+ element = MochiKit.DOM.getElement(element);
+ var elementDimensions = MochiKit.Style.getElementDimensions(element, true);
+ var oldStyle = {
+ position: s.getStyle(element, 'position'),
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height,
+ opacity: s.getStyle(element, 'opacity')
+ };
+ options = MochiKit.Base.update({
+ beforeSetupInternal: function (effect) {
+ MochiKit.Position.absolutize(effect.effects[0].element);
+ },
+ afterFinishInternal: function (effect) {
+ s.hideElement(effect.effects[0].element);
+ s.setStyle(effect.effects[0].element, oldStyle);
+ },
+ scaleContent: true,
+ scaleFromCenter: true
+ }, options);
+ return new v.Parallel(
+ [new v.Scale(element, 200,
+ {sync: true, scaleFromCenter: options.scaleFromCenter,
+ scaleMode: {originalHeight: elementDimensions.h,
+ originalWidth: elementDimensions.w},
+ scaleContent: options.scaleContent, restoreAfterFinish: true}),
+ new v.Opacity(element, {sync: true, to: 0.0 })],
+ options);
+};
+
+/** @id MochiKit.Visual.blindUp */
+MochiKit.Visual.blindUp = function (element, /* optional */ options) {
+ /***
+
+ Blind an element up: change its vertical size to 0.
+
+ ***/
+ var d = MochiKit.DOM;
+ var s = MochiKit.Style;
+ element = d.getElement(element);
+ var elementDimensions = s.getElementDimensions(element, true);
+ var elemClip = s.makeClipping(element);
+ options = MochiKit.Base.update({
+ scaleContent: false,
+ scaleX: false,
+ scaleMode: {originalHeight: elementDimensions.h,
+ originalWidth: elementDimensions.w},
+ restoreAfterFinish: true,
+ afterFinishInternal: function (effect) {
+ s.hideElement(effect.element);
+ s.undoClipping(effect.element, elemClip);
+ }
+ }, options);
+ return new MochiKit.Visual.Scale(element, 0, options);
+};
+
+/** @id MochiKit.Visual.blindDown */
+MochiKit.Visual.blindDown = function (element, /* optional */ options) {
+ /***
+
+ Blind an element down: restore its vertical size.
+
+ ***/
+ var d = MochiKit.DOM;
+ var s = MochiKit.Style;
+ element = d.getElement(element);
+ var elementDimensions = s.getElementDimensions(element, true);
+ var elemClip;
+ options = MochiKit.Base.update({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: 0,
+ scaleMode: {originalHeight: elementDimensions.h,
+ originalWidth: elementDimensions.w},
+ restoreAfterFinish: true,
+ afterSetupInternal: function (effect) {
+ elemClip = s.makeClipping(effect.element);
+ s.setStyle(effect.element, {height: '0px'});
+ s.showElement(effect.element);
+ },
+ afterFinishInternal: function (effect) {
+ s.undoClipping(effect.element, elemClip);
+ }
+ }, options);
+ return new MochiKit.Visual.Scale(element, 100, options);
+};
+
+/** @id MochiKit.Visual.switchOff */
+MochiKit.Visual.switchOff = function (element, /* optional */ options) {
+ /***
+
+ Apply a switch-off-like effect.
+
+ ***/
+ var d = MochiKit.DOM;
+ var s = MochiKit.Style;
+ element = d.getElement(element);
+ var elementDimensions = s.getElementDimensions(element, true);
+ var oldOpacity = s.getStyle(element, 'opacity');
+ var elemClip;
+ options = MochiKit.Base.update({
+ duration: 0.7,
+ restoreAfterFinish: true,
+ beforeSetupInternal: function (effect) {
+ s.makePositioned(element);
+ elemClip = s.makeClipping(element);
+ },
+ afterFinishInternal: function (effect) {
+ s.hideElement(element);
+ s.undoClipping(element, elemClip);
+ s.undoPositioned(element);
+ s.setStyle(element, {'opacity': oldOpacity});
+ }
+ }, options);
+ var v = MochiKit.Visual;
+ return new v.Sequence(
+ [new v.appear(element,
+ { sync: true, duration: 0.57 * options.duration,
+ from: 0, transition: v.Transitions.flicker }),
+ new v.Scale(element, 1,
+ { sync: true, duration: 0.43 * options.duration,
+ scaleFromCenter: true, scaleX: false,
+ scaleMode: {originalHeight: elementDimensions.h,
+ originalWidth: elementDimensions.w},
+ scaleContent: false, restoreAfterFinish: true })],
+ options);
+};
+
+/** @id MochiKit.Visual.dropOut */
+MochiKit.Visual.dropOut = function (element, /* optional */ options) {
+ /***
+
+ Make an element fall and disappear.
+
+ ***/
+ var d = MochiKit.DOM;
+ var s = MochiKit.Style;
+ element = d.getElement(element);
+ var oldStyle = {
+ top: s.getStyle(element, 'top'),
+ left: s.getStyle(element, 'left'),
+ opacity: s.getStyle(element, 'opacity')
+ };
+
+ options = MochiKit.Base.update({
+ duration: 0.5,
+ distance: 100,
+ beforeSetupInternal: function (effect) {
+ s.makePositioned(effect.effects[0].element);
+ },
+ afterFinishInternal: function (effect) {
+ s.hideElement(effect.effects[0].element);
+ s.undoPositioned(effect.effects[0].element);
+ s.setStyle(effect.effects[0].element, oldStyle);
+ }
+ }, options);
+ var v = MochiKit.Visual;
+ return new v.Parallel(
+ [new v.Move(element, {x: 0, y: options.distance, sync: true}),
+ new v.Opacity(element, {sync: true, to: 0.0})],
+ options);
+};
+
+/** @id MochiKit.Visual.shake */
+MochiKit.Visual.shake = function (element, /* optional */ options) {
+ /***
+
+ Move an element from left to right several times.
+
+ ***/
+ var d = MochiKit.DOM;
+ var v = MochiKit.Visual;
+ var s = MochiKit.Style;
+ element = d.getElement(element);
+ var oldStyle = {
+ top: s.getStyle(element, 'top'),
+ left: s.getStyle(element, 'left')
+ };
+ options = MochiKit.Base.update({
+ duration: 0.5,
+ afterFinishInternal: function (effect) {
+ s.undoPositioned(element);
+ s.setStyle(element, oldStyle);
+ }
+ }, options);
+ return new v.Sequence(
+ [new v.Move(element, { sync: true, duration: 0.1 * options.duration,
+ x: 20, y: 0 }),
+ new v.Move(element, { sync: true, duration: 0.2 * options.duration,
+ x: -40, y: 0 }),
+ new v.Move(element, { sync: true, duration: 0.2 * options.duration,
+ x: 40, y: 0 }),
+ new v.Move(element, { sync: true, duration: 0.2 * options.duration,
+ x: -40, y: 0 }),
+ new v.Move(element, { sync: true, duration: 0.2 * options.duration,
+ x: 40, y: 0 }),
+ new v.Move(element, { sync: true, duration: 0.1 * options.duration,
+ x: -20, y: 0 })],
+ options);
+};
+
+/** @id MochiKit.Visual.slideDown */
+MochiKit.Visual.slideDown = function (element, /* optional */ options) {
+ /***
+
+ Slide an element down.
+ It needs to have the content of the element wrapped in a container
+ element with fixed height.
+
+ ***/
+ var d = MochiKit.DOM;
+ var b = MochiKit.Base;
+ var s = MochiKit.Style;
+ element = d.getElement(element);
+ if (!element.firstChild) {
+ throw new Error("MochiKit.Visual.slideDown must be used on a element with a child");
+ }
+ d.removeEmptyTextNodes(element);
+ var oldInnerBottom = s.getStyle(element.firstChild, 'bottom') || 0;
+ var elementDimensions = s.getElementDimensions(element, true);
+ var elemClip;
+ options = b.update({
+ scaleContent: false,
+ scaleX: false,
+ scaleFrom: 0,
+ scaleMode: {originalHeight: elementDimensions.h,
+ originalWidth: elementDimensions.w},
+ restoreAfterFinish: true,
+ afterSetupInternal: function (effect) {
+ s.makePositioned(effect.element);
+ s.makePositioned(effect.element.firstChild);
+ if (/Opera/.test(navigator.userAgent)) {
+ s.setStyle(effect.element, {top: ''});
+ }
+ elemClip = s.makeClipping(effect.element);
+ s.setStyle(effect.element, {height: '0px'});
+ s.showElement(effect.element);
+ },
+ afterUpdateInternal: function (effect) {
+ var elementDimensions = s.getElementDimensions(effect.element, true);
+ s.setStyle(effect.element.firstChild,
+ {bottom: (effect.dims[0] - elementDimensions.h) + 'px'});
+ },
+ afterFinishInternal: function (effect) {
+ s.undoClipping(effect.element, elemClip);
+ // IE will crash if child is undoPositioned first
+ if (/MSIE/.test(navigator.userAgent)) {
+ s.undoPositioned(effect.element);
+ s.undoPositioned(effect.element.firstChild);
+ } else {
+ s.undoPositioned(effect.element.firstChild);
+ s.undoPositioned(effect.element);
+ }
+ s.setStyle(effect.element.firstChild, {bottom: oldInnerBottom});
+ }
+ }, options);
+
+ return new MochiKit.Visual.Scale(element, 100, options);
+};
+
+/** @id MochiKit.Visual.slideUp */
+MochiKit.Visual.slideUp = function (element, /* optional */ options) {
+ /***
+
+ Slide an element up.
+ It needs to have the content of the element wrapped in a container
+ element with fixed height.
+
+ ***/
+ var d = MochiKit.DOM;
+ var b = MochiKit.Base;
+ var s = MochiKit.Style;
+ element = d.getElement(element);
+ if (!element.firstChild) {
+ throw new Error("MochiKit.Visual.slideUp must be used on a element with a child");
+ }
+ d.removeEmptyTextNodes(element);
+ var oldInnerBottom = s.getStyle(element.firstChild, 'bottom');
+ var elementDimensions = s.getElementDimensions(element, true);
+ var elemClip;
+ options = b.update({
+ scaleContent: false,
+ scaleX: false,
+ scaleMode: {originalHeight: elementDimensions.h,
+ originalWidth: elementDimensions.w},
+ scaleFrom: 100,
+ restoreAfterFinish: true,
+ beforeStartInternal: function (effect) {
+ s.makePositioned(effect.element);
+ s.makePositioned(effect.element.firstChild);
+ if (/Opera/.test(navigator.userAgent)) {
+ s.setStyle(effect.element, {top: ''});
+ }
+ elemClip = s.makeClipping(effect.element);
+ s.showElement(effect.element);
+ },
+ afterUpdateInternal: function (effect) {
+ var elementDimensions = s.getElementDimensions(effect.element, true);
+ s.setStyle(effect.element.firstChild,
+ {bottom: (effect.dims[0] - elementDimensions.h) + 'px'});
+ },
+ afterFinishInternal: function (effect) {
+ s.hideElement(effect.element);
+ s.undoClipping(effect.element, elemClip);
+ s.undoPositioned(effect.element.firstChild);
+ s.undoPositioned(effect.element);
+ s.setStyle(effect.element.firstChild, {bottom: oldInnerBottom});
+ }
+ }, options);
+ return new MochiKit.Visual.Scale(element, 0, options);
+};
+
+// Bug in opera makes the TD containing this element expand for a instance
+// after finish
+/** @id MochiKit.Visual.squish */
+MochiKit.Visual.squish = function (element, /* optional */ options) {
+ /***
+
+ Reduce an element and make it disappear.
+
+ ***/
+ var d = MochiKit.DOM;
+ var b = MochiKit.Base;
+ var s = MochiKit.Style;
+ var elementDimensions = s.getElementDimensions(element, true);
+ var elemClip;
+ options = b.update({
+ restoreAfterFinish: true,
+ scaleMode: {originalHeight: elementDimensions.w,
+ originalWidth: elementDimensions.h},
+ beforeSetupInternal: function (effect) {
+ elemClip = s.makeClipping(effect.element);
+ },
+ afterFinishInternal: function (effect) {
+ s.hideElement(effect.element);
+ s.undoClipping(effect.element, elemClip);
+ }
+ }, options);
+
+ return new MochiKit.Visual.Scale(element, /Opera/.test(navigator.userAgent) ? 1 : 0, options);
+};
+
+/** @id MochiKit.Visual.grow */
+MochiKit.Visual.grow = function (element, /* optional */ options) {
+ /***
+
+ Grow an element to its original size. Make it zero-sized before
+ if necessary.
+
+ ***/
+ var d = MochiKit.DOM;
+ var v = MochiKit.Visual;
+ var s = MochiKit.Style;
+ element = d.getElement(element);
+ options = MochiKit.Base.update({
+ direction: 'center',
+ moveTransition: v.Transitions.sinoidal,
+ scaleTransition: v.Transitions.sinoidal,
+ opacityTransition: v.Transitions.full,
+ scaleContent: true,
+ scaleFromCenter: false
+ }, options);
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: s.getStyle(element, 'opacity')
+ };
+ var dims = s.getElementDimensions(element, true);
+ var initialMoveX, initialMoveY;
+ var moveX, moveY;
+
+ switch (options.direction) {
+ case 'top-left':
+ initialMoveX = initialMoveY = moveX = moveY = 0;
+ break;
+ case 'top-right':
+ initialMoveX = dims.w;
+ initialMoveY = moveY = 0;
+ moveX = -dims.w;
+ break;
+ case 'bottom-left':
+ initialMoveX = moveX = 0;
+ initialMoveY = dims.h;
+ moveY = -dims.h;
+ break;
+ case 'bottom-right':
+ initialMoveX = dims.w;
+ initialMoveY = dims.h;
+ moveX = -dims.w;
+ moveY = -dims.h;
+ break;
+ case 'center':
+ initialMoveX = dims.w / 2;
+ initialMoveY = dims.h / 2;
+ moveX = -dims.w / 2;
+ moveY = -dims.h / 2;
+ break;
+ }
+
+ var optionsParallel = MochiKit.Base.update({
+ beforeSetupInternal: function (effect) {
+ s.setStyle(effect.effects[0].element, {height: '0px'});
+ s.showElement(effect.effects[0].element);
+ },
+ afterFinishInternal: function (effect) {
+ s.undoClipping(effect.effects[0].element);
+ s.undoPositioned(effect.effects[0].element);
+ s.setStyle(effect.effects[0].element, oldStyle);
+ }
+ }, options);
+
+ return new v.Move(element, {
+ x: initialMoveX,
+ y: initialMoveY,
+ duration: 0.01,
+ beforeSetupInternal: function (effect) {
+ s.hideElement(effect.element);
+ s.makeClipping(effect.element);
+ s.makePositioned(effect.element);
+ },
+ afterFinishInternal: function (effect) {
+ new v.Parallel(
+ [new v.Opacity(effect.element, {
+ sync: true, to: 1.0, from: 0.0,
+ transition: options.opacityTransition
+ }),
+ new v.Move(effect.element, {
+ x: moveX, y: moveY, sync: true,
+ transition: options.moveTransition
+ }),
+ new v.Scale(effect.element, 100, {
+ scaleMode: {originalHeight: dims.h,
+ originalWidth: dims.w},
+ sync: true,
+ scaleFrom: /Opera/.test(navigator.userAgent) ? 1 : 0,
+ transition: options.scaleTransition,
+ scaleContent: options.scaleContent,
+ scaleFromCenter: options.scaleFromCenter,
+ restoreAfterFinish: true
+ })
+ ], optionsParallel
+ );
+ }
+ });
+};
+
+/** @id MochiKit.Visual.shrink */
+MochiKit.Visual.shrink = function (element, /* optional */ options) {
+ /***
+
+ Shrink an element and make it disappear.
+
+ ***/
+ var d = MochiKit.DOM;
+ var v = MochiKit.Visual;
+ var s = MochiKit.Style;
+ element = d.getElement(element);
+ options = MochiKit.Base.update({
+ direction: 'center',
+ moveTransition: v.Transitions.sinoidal,
+ scaleTransition: v.Transitions.sinoidal,
+ opacityTransition: v.Transitions.none,
+ scaleContent: true,
+ scaleFromCenter: false
+ }, options);
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ height: element.style.height,
+ width: element.style.width,
+ opacity: s.getStyle(element, 'opacity')
+ };
+
+ var dims = s.getElementDimensions(element, true);
+ var moveX, moveY;
+
+ switch (options.direction) {
+ case 'top-left':
+ moveX = moveY = 0;
+ break;
+ case 'top-right':
+ moveX = dims.w;
+ moveY = 0;
+ break;
+ case 'bottom-left':
+ moveX = 0;
+ moveY = dims.h;
+ break;
+ case 'bottom-right':
+ moveX = dims.w;
+ moveY = dims.h;
+ break;
+ case 'center':
+ moveX = dims.w / 2;
+ moveY = dims.h / 2;
+ break;
+ }
+ var elemClip;
+
+ var optionsParallel = MochiKit.Base.update({
+ beforeStartInternal: function (effect) {
+ s.makePositioned(effect.effects[0].element);
+ elemClip = s.makeClipping(effect.effects[0].element);
+ },
+ afterFinishInternal: function (effect) {
+ s.hideElement(effect.effects[0].element);
+ s.undoClipping(effect.effects[0].element, elemClip);
+ s.undoPositioned(effect.effects[0].element);
+ s.setStyle(effect.effects[0].element, oldStyle);
+ }
+ }, options);
+
+ return new v.Parallel(
+ [new v.Opacity(element, {
+ sync: true, to: 0.0, from: 1.0,
+ transition: options.opacityTransition
+ }),
+ new v.Scale(element, /Opera/.test(navigator.userAgent) ? 1 : 0, {
+ scaleMode: {originalHeight: dims.h, originalWidth: dims.w},
+ sync: true, transition: options.scaleTransition,
+ scaleContent: options.scaleContent,
+ scaleFromCenter: options.scaleFromCenter,
+ restoreAfterFinish: true
+ }),
+ new v.Move(element, {
+ x: moveX, y: moveY, sync: true, transition: options.moveTransition
+ })
+ ], optionsParallel
+ );
+};
+
+/** @id MochiKit.Visual.pulsate */
+MochiKit.Visual.pulsate = function (element, /* optional */ options) {
+ /***
+
+ Pulse an element between appear/fade.
+
+ ***/
+ var d = MochiKit.DOM;
+ var v = MochiKit.Visual;
+ var b = MochiKit.Base;
+ var oldOpacity = MochiKit.Style.getStyle(element, 'opacity');
+ options = b.update({
+ duration: 3.0,
+ from: 0,
+ afterFinishInternal: function (effect) {
+ MochiKit.Style.setStyle(effect.element, {'opacity': oldOpacity});
+ }
+ }, options);
+ var transition = options.transition || v.Transitions.sinoidal;
+ options.transition = function (pos) {
+ return transition(1 - v.Transitions.pulse(pos, options.pulses));
+ };
+ return new v.Opacity(element, options);
+};
+
+/** @id MochiKit.Visual.fold */
+MochiKit.Visual.fold = function (element, /* optional */ options) {
+ /***
+
+ Fold an element, first vertically, then horizontally.
+
+ ***/
+ var d = MochiKit.DOM;
+ var v = MochiKit.Visual;
+ var s = MochiKit.Style;
+ element = d.getElement(element);
+ var elementDimensions = s.getElementDimensions(element, true);
+ var oldStyle = {
+ top: element.style.top,
+ left: element.style.left,
+ width: element.style.width,
+ height: element.style.height
+ };
+ var elemClip = s.makeClipping(element);
+ options = MochiKit.Base.update({
+ scaleContent: false,
+ scaleX: false,
+ scaleMode: {originalHeight: elementDimensions.h,
+ originalWidth: elementDimensions.w},
+ afterFinishInternal: function (effect) {
+ new v.Scale(element, 1, {
+ scaleContent: false,
+ scaleY: false,
+ scaleMode: {originalHeight: elementDimensions.h,
+ originalWidth: elementDimensions.w},
+ afterFinishInternal: function (effect) {
+ s.hideElement(effect.element);
+ s.undoClipping(effect.element, elemClip);
+ s.setStyle(effect.element, oldStyle);
+ }
+ });
+ }
+ }, options);
+ return new v.Scale(element, 5, options);
+};
+
+
+/* end of Rico adaptation */
+
+MochiKit.Visual.__new__ = function () {
+ var m = MochiKit.Base;
+
+ // Backwards compatibility aliases
+ m._deprecated(this, 'Color', 'MochiKit.Color.Color', '1.1');
+ m._deprecated(this, 'getElementsComputedStyle', 'MochiKit.Style.getStyle', '1.1');
+
+ m.nameFunctions(this);
+};
+
+MochiKit.Visual.__new__();
+
+MochiKit.Base._exportSymbols(this, MochiKit.Visual);
diff --git a/frontend/gamma/js/MochiKit/__package__.js b/frontend/gamma/js/MochiKit/__package__.js
new file mode 100644
index 0000000..8d644b1
--- a/dev/null
+++ b/frontend/gamma/js/MochiKit/__package__.js
@@ -0,0 +1,18 @@
+dojo.kwCompoundRequire({
+ "common": [
+ "MochiKit.Base",
+ "MochiKit.Iter",
+ "MochiKit.Logging",
+ "MochiKit.DateTime",
+ "MochiKit.Format",
+ "MochiKit.Async",
+ "MochiKit.DOM",
+ "MochiKit.Style",
+ "MochiKit.LoggingPane",
+ "MochiKit.Color",
+ "MochiKit.Signal",
+ "MochiKit.Position",
+ "MochiKit.Visual"
+ ]
+});
+dojo.provide("MochiKit.*");
diff --git a/frontend/gamma/js/main.js b/frontend/gamma/js/main.js
new file mode 100644
index 0000000..abb178f
--- a/dev/null
+++ b/frontend/gamma/js/main.js
@@ -0,0 +1,109 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+function _pm_logEvent(anEvent) {
+// console.log("####", anEvent);
+
+ anEvent.preventDefault();
+}
+
+function handleGenericDeferredError(anError) {
+ var result;
+
+ if (anError instanceof MochiKit.Async.CancelledError) {
+ result = anError;
+ } else {
+MochiKit.Logging.logError("## MainController - GENERIC ERROR" + "\n" + "==>> " + anError + " <<==\n" + anError.stack);
+//console.log(anError);
+ result = new MochiKit.Async.CancelledError(anError);
+ }
+
+ return result;
+}
+
+
+Clipperz.PM.RunTime = {};
+
+
+function run() {
+ var shouldShowRegistrationForm;
+ var useCompactDesign;
+ var controllerParameters;
+// var iPhoneDesign;
+
+// MochiKit.Signal.connect(document.body, 'onkeydown', _pm_logEvent);
+// MochiKit.Signal.connect(document.body, 'onkeypress', _pm_logEvent);
+// MochiKit.Signal.connect(document.body, 'onclick', _pm_logEvent);
+
+ controllerParameters = {};
+
+ MochiKit.DOM.removeElement('javaScriptAlert');
+ Clipperz.PM.Strings.Languages.initSetup();
+
+ if (window.location.search.indexOf('registration') != -1) {
+ shouldShowRegistrationForm = true;
+ } else {
+ shouldShowRegistrationForm = false;
+ }
+
+ if (window.location.search.indexOf('autocomplete') != -1) {
+ controllerParameters['autocomplete'] = 'on'
+ }
+
+// if ((window.location.search.indexOf('iPhone') != -1) || (navigator.userAgent.match('iPhone'))) {
+// iPhoneDesign = true;
+// } else {
+// iPhoneDesign = false;
+// }
+
+ if (window.location.search.indexOf('compact') != -1) {
+ useCompactDesign = true;
+ } else {
+ useCompactDesign = false;
+ }
+
+ if (useCompactDesign == true) {
+ Clipperz.PM.RunTime.mainController = new Clipperz.PM.UI.Compact.Controllers.MainController(controllerParameters);
+// } else if (iPhoneDesign == true) {
+// Clipperz.PM.RunTime.mainController = new Clipperz.PM.UI.iPhone.Controllers.MainController();
+ } else {
+ Clipperz.PM.RunTime.mainController = new Clipperz.PM.UI.Web.Controllers.MainController(controllerParameters);
+ }
+
+ Clipperz.PM.RunTime.mainController.run(shouldShowRegistrationForm);
+
+//Clipperz.log("HASH: " + window.location.hash);
+if (window.location.hash != "") {
+ window.location.hash = ""
+}
+//Clipperz.log("HASH cleaned");
+// #credentials=base64encoded({username:'joe', passphrase:'clipperz'})
+// MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'doLogin', {username:'joe', passphrase:'clipperz'});
+}
+
+MochiKit.DOM.addLoadEvent(run);
diff --git a/frontend/gamma/js/main_iPhone.js b/frontend/gamma/js/main_iPhone.js
new file mode 100644
index 0000000..f13e95c
--- a/dev/null
+++ b/frontend/gamma/js/main_iPhone.js
@@ -0,0 +1,60 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+function _pm_logEvent(anEvent) {
+// console.log("####", anEvent);
+
+ anEvent.preventDefault();
+}
+
+function handleGenericDeferredError(anError) {
+ var result;
+
+ if (anError instanceof MochiKit.Async.CancelledError) {
+ result = anError;
+ } else {
+MochiKit.Logging.logError("## MainController - GENERIC ERROR" + "\n" + "==>> " + anError + " <<==\n" + anError.stack);
+ result = new MochiKit.Async.CancelledError(anError);
+ }
+
+ return result;
+}
+
+
+Clipperz.PM.RunTime = {};
+
+
+function run() {
+ MochiKit.DOM.removeElement('javaScriptAlert');
+ Clipperz.PM.Strings.Languages.initSetup();
+
+ Clipperz.PM.RunTime.mainController = new Clipperz.PM.UI.iPhone.Controllers.MainController();
+ Clipperz.PM.RunTime.mainController.run(false);
+}
+
+MochiKit.DOM.addLoadEvent(run);
diff --git a/frontend/gamma/properties/creditsAndCopyrights.txt b/frontend/gamma/properties/creditsAndCopyrights.txt
new file mode 100644
index 0000000..598440d
--- a/dev/null
+++ b/frontend/gamma/properties/creditsAndCopyrights.txt
@@ -0,0 +1,336 @@
+@clipperz.license@
+
+===============================================================================
+
+ This application is build using also the following libraries
+
+# MochiKit (http://www.mochikit.com)
+ - repository: @mochikit.repository@ (revision: @mochikit.version@)
+
+ * Software licence: http://svn.mochikit.com/mochikit/trunk/licence.txt
+
+ | MochiKit is dual-licensed software. It is available under the terms of the
+ | MIT License, or the Academic Free License version 2.1. The full text of
+ | each license is included below.
+ |
+ | MIT License
+ | ===========
+ |
+ | Copyright (c) 2005 Bob Ippolito. All rights reserved.
+ |
+ | Permission is hereby granted, free of charge, to any person obtaining a copy of this
+ | software and associated documentation files (the "Software"), to deal in the Software
+ | without restriction, including without limitation the rights to use, copy, modify,
+ | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
+ | permit persons to whom the Software is furnished to do so, subject to the following
+ | conditions:
+ |
+ | The above copyright notice and this permission notice shall be included in all copies
+ | or substantial portions of the Software.
+ |
+ | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+ | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
+ | FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ | DEALINGS IN THE SOFTWARE.
+ |
+ |
+ | Academic Free License v. 2.1
+ | ============================
+ |
+ | Copyright (c) 2005 Bob Ippolito. All rights reserved.
+ |
+ | This Academic Free License (the "License") applies to any original work of authorship (the
+ | "Original Work") whose owner (the "Licensor") has placed the following notice immediately
+ | following the copyright notice for the Original Work:
+ |
+ | Licensed under the Academic Free License version 2.1
+ |
+ | 1) Grant of Copyright License. Licensor hereby grants You a world-wide, royalty-free,
+ | non-exclusive, perpetual, sublicenseable license to do the following:
+ |
+ | a) to reproduce the Original Work in copies;
+ | b) to prepare derivative works ("Derivative Works") based upon the Original Work;
+ | c) to distribute copies of the Original Work and Derivative Works to the public;
+ | d) to perform the Original Work publicly; and
+ | e) to display the Original Work publicly.
+ |
+ | 2) Grant of Patent License. Licensor hereby grants You a world-wide, royalty-free,
+ | non-exclusive, perpetual, sublicenseable license, under patent claims owned or controlled
+ | by the Licensor that are embodied in the Original Work as furnished by the Licensor, to
+ | make, use, sell and offer for sale the Original Work and Derivative Works.
+ |
+ | 3) Grant of Source Code License. The term "Source Code" means the preferred form of the
+ | Original Work for making modifications to it and all available documentation describing
+ | how to modify the Original Work. Licensor hereby agrees to provide a machine-readable copy
+ | of the Source Code of the Original Work along with each copy of the Original Work that
+ | Licensor distributes. Licensor reserves the right to satisfy this obligation by placing
+ | a machine-readable copy of the Source Code in an information repository reasonably
+ | calculated to permit inexpensive and convenient access by You for as long as Licensor
+ | continues to distribute the Original Work, and by publishing the address of that information
+ | repository in a notice immediately following the copyright notice that applies to the Original
+ | Work.
+ |
+ | 4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any
+ | contributors to the Original Work, nor any of their trademarks or service marks, may be used
+ | to endorse or promote products derived from this Original Work without express prior written
+ | permission of the Licensor. Nothing in this License shall be deemed to grant any rights to
+ | trademarks, copyrights, patents, trade secrets or any other intellectual property of Licensor
+ | except as expressly stated herein. No patent license is granted to make, use, sell or offer
+ | to sell embodiments of any patent claims other than the licensed claims defined in Section 2.
+ | No right is granted to the trademarks of Licensor even if such marks are included in the Original
+ | Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under
+ | different terms from this License any Original Work that Licensor otherwise would have a right
+ | to license.
+ |
+ | 5) This section intentionally omitted.
+ |
+ | 6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You
+ | create, all copyright, patent or trademark notices from the Source Code of the Original Work,
+ | as well as any notices of licensing and any descriptive text identified therein as an "Attribution
+ | Notice." You must cause the Source Code for any Derivative Works that You create to carry a
+ | prominent Attribution Notice reasonably calculated to inform recipients that You have modified the
+ | Original Work.
+ |
+ | 7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and
+ | to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or
+ | are sublicensed to You under the terms of this License with the permission of the contributor(s)
+ | of those copyrights and patent rights. Except as expressly stated in the immediately proceeding
+ | sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY,
+ | either express or implied, including, without limitation, the warranties of NON-INFRINGEMENT,
+ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL
+ | WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license
+ | to Original Work is granted hereunder except under this disclaimer.
+ |
+ | 8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including
+ | negligence), contract, or otherwise, shall the Licensor be liable to any person for any direct, indirect,
+ | special, incidental, or consequential damages of any character arising as a result of this License or the
+ | use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage,
+ | computer failure or malfunction, or any and all other commercial damages or losses. This limitation of
+ | liability shall not apply to liability for death or personal injury resulting from Licensor's negligence
+ | to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or
+ | limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You.
+ |
+ | 9) Acceptance and Termination. If You distribute copies of the Original Work or a Derivative Work, You must
+ | make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of
+ | this License. Nothing else but this License (or another written agreement between Licensor and You) grants
+ | You permission to create Derivative Works based upon the Original Work or to exercise any of the rights
+ | granted in Section 1 herein, and any attempt to do so except under the terms of this License (or another
+ | written agreement between Licensor and You) is expressly prohibited by U.S. copyright law, the equivalent
+ | laws of other countries, and by international treaty. Therefore, by exercising any of the rights granted
+ | to You in Section 1 herein, You indicate Your acceptance of this License and all of its terms and conditions.
+ |
+ | 10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise
+ | any of the rights granted to You by this License as of the date You commence an action, including a cross-claim
+ | or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This
+ | termination provision shall not apply for an action alleging patent infringement by combinations of the Original
+ | Work with other software or hardware.
+ |
+ | 11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in
+ | the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business,
+ | and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United
+ | Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the
+ | Original Work outside the scope of this License or after its termination shall be subject to the requirements
+ | and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et seq., the equivalent laws of other countries,
+ | and international treaty. This section shall survive the termination of this License.
+ |
+ | 12) Attorneys Fees. In any action to enforce the terms of this License or seeking damages
+ | relating thereto, the prevailing party shall be entitled to recover its costs and expenses,
+ | including, without limitation, reasonable attorneys' fees and costs incurred in connection
+ | with such action, including any appeal of such action. This section shall survive the
+ | termination of this License.
+ |
+ | 13) Miscellaneous. This License represents the complete agreement concerning the subject
+ | matter hereof. If any provision of this License is held to be unenforceable, such provision
+ | shall be reformed only to the extent necessary to make it enforceable.
+ |
+ | 14) Definition of "You" in This License. "You" throughout this License, whether in upper
+ | or lower case, means an individual or a legal entity exercising rights under, and complying
+ | with all of the terms of, this License. For legal entities, "You" includes any entity that
+ | controls, is controlled by, or is under common control with you. For purposes of this
+ | definition, "control" means (i) the power, direct or indirect, to cause the direction or
+ | management of such entity, whether by contract or otherwise, or (ii) ownership of fifty
+ | percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+ |
+ | 15) Right to Use. You may use the Original Work in all ways not otherwise restricted or
+ | conditioned by this License or by law, and Licensor promises not to interfere with or be
+ | responsible for such uses by You.
+ |
+ | This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved. Permission
+ | is hereby granted to copy and distribute this license without modification. This license
+ | may not be modified without the express written permission of its copyright owner.
+
+
+# Yahoo! UI Library (http://developer.yahoo.com/yui/)
+ - package version: 0.12
+
+ Copyright © 2005-2006 Yahoo! Inc. All rights reserved
+ * Copyright notes: http://docs.yahoo.com/info/copyright/copyright.html
+ * Software licence: http://developer.yahoo.com/yui/license.txt
+
+ | Software License Agreement (BSD License)
+ |
+ | Copyright (c) 2006, Yahoo! Inc.
+ | All rights reserved.
+ |
+ | Redistribution and use of this software in source and binary forms, with or without modification, are
+ | permitted provided that the following conditions are met:
+ |
+ | * Redistributions of source code must retain the above
+ | copyright notice, this list of conditions and the
+ | following disclaimer.
+ |
+ | * Redistributions in binary form must reproduce the above
+ | copyright notice, this list of conditions and the
+ | following disclaimer in the documentation and/or other
+ | materials provided with the distribution.
+ |
+ | * Neither the name of Yahoo! Inc. nor the names of its
+ | contributors may be used to endorse or promote products
+ | derived from this software without specific prior
+ | written permission of Yahoo! Inc.
+ |
+ | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+# YUI-ext (http://www.yui-ext.com)
+ - repository: http://yui-ext.googlecode.com/svn/trunk/ (revision: 120)
+
+ * Software licence: http://yui-ext.googlecode.com/svn/trunk/src/licence.txt
+
+ | yui-ext
+ | Copyright (c) 2006, Jack Slocum
+ | All rights reserved.
+ |
+ | Redistribution and use in source and binary forms, with or without modification,
+ | are permitted provided that the following conditions are met:
+ |
+ | * Redistributions of source code must retain the above copyright notice,
+ | this list of conditions and the following disclaimer.
+ | * Redistributions in binary form must reproduce the above copyright notice,
+ | this list of conditions and the following disclaimer in the documentation
+ | and/or other materials provided with the distribution.
+ | * Neither the name yui-ext nor the names of its contributors
+ | may be used to endorse or promote products derived from this software
+ | without specific prior written permission.
+ |
+ | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ | IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ | EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+# iUI: iPhone User Interface Framework (http://code.google.com/p/iui/)
+ - package version: 282
+
+ Copyright (c) 2007-2009, iUI Project Members
+
+ | All rights reserved.
+ |
+ | Redistribution and use in source and binary forms, with or without modification,
+ | are permitted provided that the following conditions are met:
+ |
+ | * Redistributions of source code must retain the above copyright notice, this
+ | list of conditions and the following disclaimer.
+ | * Redistributions in binary form must reproduce the above copyright notice,
+ | this list of conditions and the following disclaimer in the documentation
+ | and/or other materials provided with the distribution.
+ | * Neither the name of the iUI Project nor the names of its contributors may
+ | be used to endorse or promote products derived from this software without
+ | specific prior written permission.
+ |
+ | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+# Big Integer Library v. 5.0
+ - code downloaded on March 5, 2007 from http://www.leemon.com/crypto/BigInt.js
+
+ | Big Integer Library v. 5.0
+ | Created 2000, last modified 2006
+ | Leemon Baird
+ | www.leemon.com
+ |
+ | This file is public domain. You can use it for any purpose without restriction.
+ | I do not guarantee that it is correct, so use it at your own risk. If you use
+ | it for something interesting, I'd appreciate hearing about it. If you find
+ | any bugs or make any improvements, I'd appreciate hearing about those too.
+ | It would also be nice if my name and address were left in the comments.
+ | But none of that is required.
+
+
+
+# JSON library
+ - code downloaded on October 13, 2008 from http://www.JSON.org/json2.js
+
+ | http://www.JSON.org/json2.js
+ | 2008-09-01
+ |
+ | Public Domain.
+ |
+ | NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+ |
+ | See http://www.JSON.org/js.html
+
+
+
+# Other code snippets used in the first demo of the program, and still present just to be able to
+ read record previously written using these same functions:
+
+ - Code downloaded on March 30, 2006 from http://anmar.eu.org/projects/jssha2/files/jssha2-0.3.zip
+ File used: jsSha2/sha256.js
+
+ | A JavaScript implementation of the Secure Hash Algorithm, SHA-256
+ | Version 0.3 Copyright Angel Marin 2003-2004 - http://anmar.eu.org/
+ | Distributed under the BSD License
+ | Some bits taken from Paul Johnston's SHA-1 implementation
+
+
+ - Code downloaded on March 30, 2006 from http://www.fourmilab.ch/javascrypt/javascrypt.zip
+ Files used: entropy.js, aesprng.js, md5.js, aes.js, utf-8.js
+
+
+ - Code downloaded on April 26, 2006 from http://pajhome.org.uk/crypt/md5/md5.js
+
+ | A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
+ | Digest Algorithm, as defined in RFC 1321.
+ | Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
+ | Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ | Distributed under the BSD License
+ | See http://pajhome.org.uk/crypt/md5 for more info.
+
+
+
+# General notes
+ The code in this page has been processed with a JavaScript compressor and is thus
+ difficult to read.
+ To get the exact version of the code used to build this application you
+ can take a look here:
+ - http://www.clipperz.com/security_privacy/security_code_review
+
diff --git a/frontend/gamma/properties/gamma.properties.json b/frontend/gamma/properties/gamma.properties.json
new file mode 100644
index 0000000..57f26f1
--- a/dev/null
+++ b/frontend/gamma/properties/gamma.properties.json
@@ -0,0 +1,189 @@
+{
+ "copyright.values": {
+ "mochikit.repository": "http://svn.mochikit.com/mochikit/trunk/",
+ "mochikit.version": "1506"
+ },
+ "js": [
+ "MochiKit/Base.js",
+ "MochiKit/Iter.js",
+ "MochiKit/Logging.js",
+ "-- MochiKit/DateTime.js",
+ "MochiKit/Format.js",
+ "MochiKit/Async.js",
+ "MochiKit/DOM.js",
+ "MochiKit/Style.js",
+ "MochiKit/LoggingPane.js",
+ "MochiKit/Color.js",
+ "MochiKit/Signal.js",
+ "MochiKit/Position.js",
+ "MochiKit/Selector.js",
+ "MochiKit/Visual.js",
+
+ "JSON/json2.js",
+
+ "Clipperz/YUI/Utils.js",
+ "Clipperz/YUI/DomHelper.js",
+
+ "Clipperz/ByteArray.js",
+ "Clipperz/Base.js",
+ "Clipperz/Async.js",
+ "Clipperz/CSVProcessor.js",
+ "Clipperz/KeePassExportProcessor.js",
+ "Clipperz/Date.js",
+ "Clipperz/DOM.js",
+ "Clipperz/Logging.js",
+ "Clipperz/Signal.js",
+ "Clipperz/Style.js",
+ "Clipperz/Visual.js",
+ "Clipperz/Set.js",
+ "-- Clipperz/Profile.js",
+ "Clipperz/KeyValueObjectStore.js",
+
+ "Clipperz/Crypto/SHA.js",
+ "Clipperz/Crypto/AES.js",
+ "Clipperz/Crypto/PRNG.js",
+ "Clipperz/Crypto/BigInt.js",
+ "Clipperz/Crypto/Base.js",
+ "Clipperz/Crypto/SRP.js",
+ "Clipperz/Crypto/RSA.js",
+
+ "Clipperz/PM/Strings/Strings_defaults.js",
+ "Clipperz/PM/Strings/Strings_en-US.js",
+ "-- # Clipperz/PM/Strings/Strings_en-GB.js",
+ "-- # Clipperz/PM/Strings/Strings_en-CA.js",
+ "-- Clipperz/PM/Strings/Strings_it-IT.js",
+ "-- Clipperz/PM/Strings/Strings_pt-BR.js",
+ "-- # Clipperz/PM/Strings/Strings_pt-PT.js",
+ "-- Clipperz/PM/Strings/Strings_ja-JP.js",
+ "-- Clipperz/PM/Strings/Strings_zh-CN.js",
+ "-- Clipperz/PM/Strings/Strings_es-ES.js",
+ "-- Clipperz/PM/Strings/Strings_fr-FR.js",
+ "-- # Clipperz/PM/Strings/Strings_de-DE.js",
+ "-- # Clipperz/PM/Strings/Strings_el-GR.js",
+ "-- # Clipperz/PM/Strings/Strings_ru-RU.js",
+ "-- # Clipperz/PM/Strings/Strings_he-IL.js",
+ "Clipperz/PM/Strings.js",
+ "-- Clipperz/PM/Strings/MessagePanelConfigurations.js",
+
+ "Clipperz/PM/Date.js",
+
+ "Clipperz/PM/Toll.js",
+ "Clipperz/PM/Proxy.js",
+ "Clipperz/PM/Proxy/Proxy.JSON.js",
+ "Clipperz/PM/Proxy/Proxy.Offline.js",
+ "Clipperz/PM/Proxy/Proxy.Offline.DataStore.js",
+ "Clipperz/PM/Connection.js",
+ "Clipperz/PM/Crypto.js",
+ "Clipperz/PM/BookmarkletProcessor.js",
+
+ "Clipperz/PM/DataModel/EncryptedRemoteObject.js",
+ "Clipperz/PM/DataModel/User.js",
+ "Clipperz/PM/DataModel/User.Header.Legacy.js",
+ "Clipperz/PM/DataModel/User.Header.RecordIndex.js",
+ "Clipperz/PM/DataModel/User.Header.Preferences.js",
+ "Clipperz/PM/DataModel/User.Header.OneTimePasswords.js",
+ "Clipperz/PM/DataModel/Record.js",
+ "Clipperz/PM/DataModel/Record.Version.js",
+ "Clipperz/PM/DataModel/Record.Version.Field.js",
+ "Clipperz/PM/DataModel/DirectLogin.js",
+ "Clipperz/PM/DataModel/DirectLoginInput.js",
+ "Clipperz/PM/DataModel/DirectLoginBinding.js",
+ "Clipperz/PM/DataModel/DirectLoginFormValue.js",
+ "Clipperz/PM/DataModel/OneTimePassword.js",
+
+ "Clipperz/PM/UI/Canvas/Marks/exclamationMark.js",
+ "Clipperz/PM/UI/Canvas/Marks/questionMark.js",
+ "Clipperz/PM/UI/Canvas/Marks/info.js",
+
+ "Clipperz/PM/UI/Canvas/Features/store.js",
+ "Clipperz/PM/UI/Canvas/Features/protect.js",
+ "Clipperz/PM/UI/Canvas/Features/directLogin.js",
+ "Clipperz/PM/UI/Canvas/Features/share.js",
+
+ "Clipperz/PM/UI/Canvas/Star/normal.js",
+
+ "Clipperz/PM/UI/Canvas/CoverActions/look.js",
+ "Clipperz/PM/UI/Canvas/CoverActions/download.js",
+
+ "Clipperz/PM/UI/Canvas/Tips/open.js",
+ "Clipperz/PM/UI/Canvas/Tips/close.js",
+
+ "Clipperz/PM/UI/Canvas/RegisterButton/normal.js",
+
+ "Clipperz/PM/UI/Canvas/Logo/normal.js",
+
+ "Clipperz/PM/UI/Canvas/GraphicFunctions.js",
+
+ "Clipperz/PM/UI/Common/Components/BaseComponent.js",
+ "Clipperz/PM/UI/Common/Components/Button.js",
+ "Clipperz/PM/UI/Common/Components/ComponentSlot.js",
+ "Clipperz/PM/UI/Common/Components/FaviconComponent.js",
+ "Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js",
+ "Clipperz/PM/UI/Common/Components/ProgressBar.js",
+ "Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js",
+ "Clipperz/PM/UI/Common/Components/MessagePanelWithProgressBar.js",
+ "Clipperz/PM/UI/Common/Components/TabPanelComponent.js",
+ "Clipperz/PM/UI/Common/Components/Tooltip.js",
+ "Clipperz/PM/UI/Common/Components/TranslatorWidget.js",
+
+ "Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js",
+ "Clipperz/PM/UI/Common/Controllers/ProgressBarController.js",
+ "Clipperz/PM/UI/Common/Controllers/TabPanelController.js",
+ "Clipperz/PM/UI/Common/Controllers/WizardController.js",
+
+ "Clipperz/PM/UI/Web/Components/Page.js",
+ "Clipperz/PM/UI/Web/Components/PageHeader.js",
+ "Clipperz/PM/UI/Web/Components/PageFooter.js",
+ "Clipperz/PM/UI/Web/Components/LoginPage.js",
+ "Clipperz/PM/UI/Web/Components/LoginForm.js",
+ "Clipperz/PM/UI/Web/Components/LoginProgress.js",
+ "Clipperz/PM/UI/Web/Components/AppPage.js",
+ "Clipperz/PM/UI/Web/Components/UserInfoBox.js",
+ "Clipperz/PM/UI/Web/Components/TabSidePanel.js",
+ "Clipperz/PM/UI/Web/Components/GridComponent.js",
+
+ "Clipperz/PM/UI/Web/Components/ColumnManager.js",
+ "Clipperz/PM/UI/Web/Components/TextColumnManager.js",
+ "Clipperz/PM/UI/Web/Components/FaviconColumnManager.js",
+ "Clipperz/PM/UI/Web/Components/ImageColumnManager.js",
+ "Clipperz/PM/UI/Web/Components/DateColumnManager.js",
+ "Clipperz/PM/UI/Web/Components/LinkColumnManager.js",
+ "Clipperz/PM/UI/Web/Components/DirectLoginColumnManager.js",
+ "Clipperz/PM/UI/Web/Components/DirectLoginsColumnManager.js",
+ "Clipperz/PM/UI/Web/Components/DeleteObjectColumnManager.js",
+ "Clipperz/PM/UI/Web/Components/CreateNewCardSplashComponent.js",
+
+ "Clipperz/PM/UI/Web/Components/AccountPanel.js",
+ "Clipperz/PM/UI/Web/Components/DataPanel.js",
+ "Clipperz/PM/UI/Web/Components/ToolsPanel.js",
+ "Clipperz/PM/UI/Web/Components/RulerComponent.js",
+ "Clipperz/PM/UI/Web/Components/CardDialogComponent.js",
+ "Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js",
+ "Clipperz/PM/UI/Web/Components/CardDialogRecordDirectLoginComponent.js",
+ "Clipperz/PM/UI/Web/Components/DirectLoginEditingComponent.js",
+ "Clipperz/PM/UI/Web/Components/DirectLoginEditingBindingComponent.js",
+ "Clipperz/PM/UI/Web/Components/DirectLoginEditingFormValueComponent.js",
+ "Clipperz/PM/UI/Web/Components/BookmarkletComponent.js",
+ "Clipperz/PM/UI/Web/Components/UnlockPasswordComponent.js",
+ "Clipperz/PM/UI/Web/Components/NewUserCreationComponent.js",
+ "Clipperz/PM/UI/Web/Components/PasswordTooltip.js",
+
+ "Clipperz/PM/UI/Web/Controllers/MainController.js",
+ "Clipperz/PM/UI/Web/Controllers/LoginController.js",
+ "Clipperz/PM/UI/Web/Controllers/AppController.js",
+ "Clipperz/PM/UI/Web/Controllers/FilterController.js",
+ "Clipperz/PM/UI/Web/Controllers/GridController.js",
+ "Clipperz/PM/UI/Web/Controllers/CardsController.js",
+ "Clipperz/PM/UI/Web/Controllers/DirectLoginsController.js",
+ "Clipperz/PM/UI/Web/Controllers/CardDialogController.js",
+ "Clipperz/PM/UI/Web/Controllers/DirectLoginWizardController.js",
+ "Clipperz/PM/UI/Web/Controllers/NewUserWizardController.js",
+
+ "main.js"
+ ],
+
+ "css": [
+ "clipperz/clipperz.css",
+ "clipperz/compact.css"
+ ]
+} \ No newline at end of file
diff --git a/frontend/gamma/properties/mobile.properties.json b/frontend/gamma/properties/mobile.properties.json
new file mode 100644
index 0000000..e26b95f
--- a/dev/null
+++ b/frontend/gamma/properties/mobile.properties.json
@@ -0,0 +1,119 @@
+{
+ "copyright.values": {
+ "mochikit.repository": "http://svn.mochikit.com/mochikit/trunk/",
+ "mochikit.version": "1506"
+ },
+ "js": [
+ "MochiKit/Base.js",
+ "MochiKit/Iter.js",
+ "MochiKit/Logging.js",
+ "-- MochiKit/DateTime.js",
+ "MochiKit/Format.js",
+ "MochiKit/Async.js",
+ "MochiKit/DOM.js",
+ "MochiKit/Style.js",
+ "MochiKit/LoggingPane.js",
+ "MochiKit/Color.js",
+ "MochiKit/Signal.js",
+ "MochiKit/Position.js",
+ "MochiKit/Selector.js",
+ "MochiKit/Visual.js",
+
+ "JSON/json2.js",
+
+ "Clipperz/YUI/Utils.js",
+ "Clipperz/YUI/DomHelper.js",
+
+ "Clipperz/ByteArray.js",
+ "Clipperz/Base.js",
+ "Clipperz/Async.js",
+ "-- Clipperz/CSVProcessor.js",
+ "-- Clipperz/KeePassExportProcessor.js",
+ "Clipperz/Date.js",
+ "Clipperz/DOM.js",
+ "Clipperz/Logging.js",
+ "Clipperz/Signal.js",
+ "Clipperz/Style.js",
+ "Clipperz/Visual.js",
+ "Clipperz/Set.js",
+ "Clipperz/KeyValueObjectStore.js",
+
+ "Clipperz/Crypto/SHA.js",
+ "Clipperz/Crypto/AES.js",
+ "Clipperz/Crypto/PRNG.js",
+ "Clipperz/Crypto/BigInt.js",
+ "Clipperz/Crypto/Base.js",
+ "Clipperz/Crypto/SRP.js",
+ "Clipperz/Crypto/RSA.js",
+
+ "Clipperz/PM/Strings/Strings_defaults.js",
+ "Clipperz/PM/Strings/Strings_en-US.js",
+ "-- # Clipperz/PM/Strings/Strings_en-GB.js",
+ "-- # Clipperz/PM/Strings/Strings_en-CA.js",
+ "-- Clipperz/PM/Strings/Strings_it-IT.js",
+ "-- Clipperz/PM/Strings/Strings_pt-BR.js",
+ "-- # Clipperz/PM/Strings/Strings_pt-PT.js",
+ "-- Clipperz/PM/Strings/Strings_ja-JP.js",
+ "-- Clipperz/PM/Strings/Strings_zh-CN.js",
+ "-- Clipperz/PM/Strings/Strings_es-ES.js",
+ "-- Clipperz/PM/Strings/Strings_fr-FR.js",
+ "-- # Clipperz/PM/Strings/Strings_de-DE.js",
+ "-- # Clipperz/PM/Strings/Strings_el-GR.js",
+ "-- # Clipperz/PM/Strings/Strings_ru-RU.js",
+ "-- # Clipperz/PM/Strings/Strings_he-IL.js",
+ "Clipperz/PM/Strings.js",
+ "-- Clipperz/PM/Strings/MessagePanelConfigurations.js",
+
+ "Clipperz/PM/Date.js",
+
+ "Clipperz/PM/Toll.js",
+ "Clipperz/PM/Proxy.js",
+ "Clipperz/PM/Proxy/Proxy.JSON.js",
+ "Clipperz/PM/Proxy/Proxy.Offline.js",
+ "Clipperz/PM/Connection.js",
+ "Clipperz/PM/Crypto.js",
+ "-- Clipperz/PM/BookmarkletProcessor.js",
+
+ "Clipperz/PM/DataModel/EncryptedRemoteObject.js",
+ "Clipperz/PM/DataModel/User.js",
+ "Clipperz/PM/DataModel/User.Header.Legacy.js",
+ "Clipperz/PM/DataModel/User.Header.RecordIndex.js",
+ "Clipperz/PM/DataModel/User.Header.Preferences.js",
+ "Clipperz/PM/DataModel/User.Header.OneTimePasswords.js",
+ "Clipperz/PM/DataModel/Record.js",
+ "Clipperz/PM/DataModel/Record.Version.js",
+ "Clipperz/PM/DataModel/Record.Version.Field.js",
+ "Clipperz/PM/DataModel/DirectLogin.js",
+ "Clipperz/PM/DataModel/DirectLoginInput.js",
+ "Clipperz/PM/DataModel/DirectLoginBinding.js",
+ "Clipperz/PM/DataModel/DirectLoginFormValue.js",
+ "Clipperz/PM/DataModel/OneTimePassword.js",
+
+ "Clipperz/PM/UI/Common/Components/BaseComponent.js",
+ "-- Clipperz/PM/UI/Common/Components/Button.js",
+ "Clipperz/PM/UI/Common/Components/ComponentSlot.js",
+ "-- Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js",
+ "Clipperz/PM/UI/Common/Components/ProgressBar.js",
+ "-- Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js",
+ "-- Clipperz/PM/UI/Common/Components/MessagePanelWithProgressBar.js",
+ "-- Clipperz/PM/UI/Common/Components/TabPanelComponent.js",
+ "-- Clipperz/PM/UI/Common/Components/Tooltip.js",
+ "-- Clipperz/PM/UI/Common/Components/TranslatorWidget.js",
+
+ "Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js",
+ "Clipperz/PM/UI/Common/Controllers/ProgressBarController.js",
+ "-- Clipperz/PM/UI/Common/Controllers/TabPanelController.js",
+
+ "Clipperz/PM/UI/iPhone/Components/LoginForm.js",
+ "Clipperz/PM/UI/iPhone/Components/CardList.js",
+ "Clipperz/PM/UI/iPhone/Components/CardDetail.js",
+
+ "Clipperz/PM/UI/iPhone/Controllers/MainController.js",
+
+ "main_iPhone.js"
+ ],
+
+ "css": [
+ "clipperz/iPhone.css"
+ ]
+} \ No newline at end of file
diff --git a/frontend/gamma/tests/SimpleTest/SimpleTest.Async.js b/frontend/gamma/tests/SimpleTest/SimpleTest.Async.js
new file mode 100644
index 0000000..040cdbf
--- a/dev/null
+++ b/frontend/gamma/tests/SimpleTest/SimpleTest.Async.js
@@ -0,0 +1,169 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+MochiKit.Base.update(Clipperz.Async.Deferred.prototype, {
+/*
+ '_addTest': function(anExpectedValue, aDescription, isDeep, aResult) {
+ if (isDeep) {
+ SimpleTest.isDeeply(aResult, anExpectedValue, aDescription);
+ } else {
+ SimpleTest.is(aResult, anExpectedValue, aDescription);
+ }
+
+ return aResult;
+ },
+*/
+ 'addTest': function (anExpectedValue, aDescription, isDeep) {
+// this.addMethod(this, '_addTest', anExpectedValue, aDescription, isDeep);
+// this.addCallback(Clipperz.Async.test, anExpectedValue, aDescription, isDeep);
+
+ if (isDeep) {
+// SimpleTest.isDeeply(aResult, anExpectedValue, aDescription);
+ this.addCallback(Clipperz.Async.Test.isDeeply(anExpectedValue, aDescription));
+ } else {
+// SimpleTest.is(aResult, anExpectedValue, aDescription);
+ this.addCallback(Clipperz.Async.Test.is(anExpectedValue, aDescription));
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'shouldSucceed': function (aDescription) {
+ this.addCallbackPass(SimpleTest.ok, true, aDescription);
+ this.addErrbackPass (SimpleTest.ok, false, aDescription);
+ this.addBoth(MochiKit.Async.succeed, null);
+ },
+
+ 'shouldFail': function (aDescription) {
+ this.addCallbackPass(SimpleTest.ok, false, aDescription);
+ this.addErrbackPass (SimpleTest.ok, true, aDescription);
+ this.addBoth(MochiKit.Async.succeed, null);
+ },
+
+ //-------------------------------------------------------------------------
+
+});
+
+
+Clipperz.Async.Test = {};
+MochiKit.Base.update(Clipperz.Async.Test, {
+
+ 'is': function (anExpectedResult, aDescription) {
+ return MochiKit.Base.partial(function (anExpectedResult, aDescription, aResult) {
+ SimpleTest.is(aResult, anExpectedResult, aDescription);
+
+ return aResult;
+ }, anExpectedResult, aDescription);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'ok': function (aDescription) {
+ return MochiKit.Base.partial(function (aDescription, aResult) {
+ SimpleTest.ok(aResult, aDescription);
+
+ return aResult;
+ }, aDescription);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'fail': function(aDescription) {
+ return MochiKit.Base.partial(function (aDescription, aResult) {
+ SimpleTest.ok(!aResult, aDescription);
+
+ return aResult;
+ }, aDescription);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isDeeply': function (anExpectedResult, aDescription) {
+ return MochiKit.Base.partial(function (anExpectedResult, aDescription, aResult) {
+ SimpleTest.isDeeply(aResult, anExpectedResult, aDescription);
+
+ return aResult;
+ }, anExpectedResult, aDescription);
+ },
+
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+});
+
+
+SimpleTest.runDeferredTests = function (aName, aTestSet, aTestArguments) {
+ try {
+ var deferredTests;
+ var aTestName;
+ var title;
+
+ deferredTests = new Clipperz.Async.Deferred(aName + " <deferred test set>", aTestArguments);
+
+ title = aName;
+
+ aTestName = window.location.href.match(/#.*/);
+ if (aTestName && (aTestName != '#')) {
+ aTestName = aTestName[0].slice(1);
+ if (aTestName in aTestSet) {
+ //Clipperz.log("single test execution, via fragment identifier", aTestName);
+ title += ' [' + aTestName + ']';
+ deferredTests.addCallback(aTestSet[aTestName], aTestArguments);
+ deferredTests.addErrback(SimpleTest.ok, false, aTestName);
+ } else {
+ title = 'WRONG TEST NAME'
+ deferredTests.addBoth(is, aTestName, null, "Wrong test name selected to run");
+ }
+ } else {
+ for (aTestName in aTestSet) {
+ deferredTests.addCallback(aTestSet[aTestName], aTestArguments);
+ deferredTests.addErrback(SimpleTest.ok, false, aTestName);
+ deferredTests.addBoth(MochiKit.Async.wait, 0.5);
+ }
+ deferredTests.addBoth(is, true, true, "FINISH: completed the full stack of tests");
+ }
+
+ MochiKit.DOM.currentDocument().title = title;
+
+ deferredTests.addBoth(SimpleTest.finish);
+ deferredTests.callback();
+
+ SimpleTest.waitForExplicitFinish();
+ } catch (err) {
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+ }
+}
diff --git a/frontend/gamma/tests/SimpleTest/SimpleTest.js b/frontend/gamma/tests/SimpleTest/SimpleTest.js
new file mode 100644
index 0000000..418954f
--- a/dev/null
+++ b/frontend/gamma/tests/SimpleTest/SimpleTest.js
@@ -0,0 +1,424 @@
+/**
+ * SimpleTest, a partial Test.Simple/Test.More API compatible test library.
+ *
+ * Why?
+ *
+ * Test.Simple doesn't work on IE < 6.
+ * TODO:
+ * * Support the Test.Simple API used by MochiKit, to be able to test MochiKit
+ * itself against IE 5.5
+ *
+**/
+
+if (typeof(SimpleTest) == "undefined") {
+ var SimpleTest = {};
+}
+
+// Check to see if the TestRunner is present and has logging
+if (typeof(parent) != "undefined" && parent.TestRunner) {
+ SimpleTest._logEnabled = parent.TestRunner.logEnabled;
+}
+
+SimpleTest._tests = [];
+SimpleTest._stopOnLoad = true;
+SimpleTest._scopeCopy = {};
+
+/**
+ * Saves a copy of the specified scope variables.
+ */
+SimpleTest.saveScope = function (scope) {
+ SimpleTest._scopeCopy = {};
+ for (var k in scope) {
+ SimpleTest._scopeCopy[k] = scope[k];
+ }
+}
+
+/**
+ * Verifies the specified scope against the stored copy and reports
+ * any differences as test failures.
+ */
+SimpleTest.verifyScope = function (scope) {
+ var filter = ['test', '_firebug','_FirebugConsole','XMLHttpRequest','Audio',
+ 'XSLTProcessor','Option','Image','scrollMaxX','scrollMaxY',
+ 'clipboardData'];
+ for (var k in scope) {
+ if (MochiKit.Base.findValue(filter, k) < 0) {
+ var v = scope[k];
+ var old = SimpleTest._scopeCopy[k];
+ if (v !== old && typeof(old) === "undefined") {
+ SimpleTest.ok(false, "scope modified, variable " + k + " was added");
+ } else if (v !== old) {
+ SimpleTest.ok(false, "scope modified, variable " + k + " changed from: " + old + ", to: " + v);
+ }
+ }
+ }
+ for (var k in SimpleTest._scopeCopy) {
+ if (!(k in scope)) {
+ SimpleTest.ok(false, "scope modified, variable " + k + " has been removed");
+ }
+ }
+}
+
+/**
+ * Something like assert.
+ */
+SimpleTest.ok = function (condition, name, diag) {
+ var test = {'result': !!condition, 'name': name, 'diag': diag || ""};
+ if (SimpleTest._logEnabled) {
+ var msg = test.result ? "PASS" : "FAIL";
+ msg += " | " + test.name;
+ if (test.result) {
+ parent.TestRunner.logger.log(msg);
+ } else {
+ msg += " | " + test.diag;
+ parent.TestRunner.logger.error(msg);
+ }
+ }
+ SimpleTest._tests.push(test);
+};
+
+/**
+ * Roughly equivalent to ok(a==b, name)
+ */
+SimpleTest.is = function (a, b, name) {
+ var repr = MochiKit.Base.repr;
+ SimpleTest.ok(a == b, name, "got " + repr(a) + ", expected " + repr(b));
+};
+
+/**
+ * Roughly equivalent to ok(compare(a,b)==0, name)
+ */
+SimpleTest.eq = function (a, b, name) {
+ var base = MochiKit.Base;
+ var repr = base.repr;
+ try {
+ SimpleTest.ok(base.compare(a, b) == 0, name, "got " + repr(a) + ", expected " + repr(b));
+ } catch (e) {
+ SimpleTest.ok(false, name, "exception in compare: " + repr(e));
+ }
+};
+
+
+/**
+ * Makes a test report, returns it as a DIV element.
+**/
+SimpleTest.report = function () {
+ var DIV = MochiKit.DOM.DIV;
+ var passed = 0;
+ var failed = 0;
+ var results = MochiKit.Base.map(
+ function (test) {
+ var cls, msg;
+ if (test.result) {
+ passed++;
+ cls = "test_ok";
+ msg = "ok - " + test.name;
+ } else {
+ failed++;
+ cls = "test_not_ok";
+ msg = "not ok - " + test.name;
+ if (test.diag != null && test.diag != "") {
+ msg += ": " + test.diag;
+ }
+ }
+ return DIV({"class": cls}, msg);
+ },
+ SimpleTest._tests
+ );
+ var summary_class = ((failed == 0) ? 'all_pass' : 'some_fail');
+ return DIV({'class': 'tests_report'},
+ DIV({'class': 'tests_summary ' + summary_class},
+ DIV({'class': 'tests_passed'}, "Passed: " + passed),
+ DIV({'class': 'tests_failed'}, "Failed: " + failed)),
+ results
+ );
+};
+
+/**
+ * Toggle element visibility
+**/
+SimpleTest.toggle = function(el) {
+ if (MochiKit.Style.getStyle(el, 'display') == 'block') {
+ el.style.display = 'none';
+ } else {
+ el.style.display = 'block';
+ }
+};
+
+/**
+ * Toggle visibility for divs with a specific class.
+**/
+SimpleTest.toggleByClass = function (cls) {
+ var elems = MochiKit.DOM.getElementsByTagAndClassName('div', cls);
+ MochiKit.Base.map(SimpleTest.toggle, elems);
+ return false;
+};
+
+/**
+ * Shows the report in the browser
+**/
+
+SimpleTest.showReport = function() {
+ var base = MochiKit.Base;
+ var dom = MochiKit.DOM;
+ var togglePassed = dom.A({'href': '#'}, "Toggle passed tests");
+ var toggleFailed = dom.A({'href': '#'}, "Toggle failed tests");
+ togglePassed.onclick = base.partial(SimpleTest.toggleByClass, 'test_ok');
+ toggleFailed.onclick = base.partial(SimpleTest.toggleByClass, 'test_not_ok');
+ var body = document.getElementsByTagName("body")[0];
+ var firstChild = body.childNodes[0];
+ var addNode;
+ if (firstChild) {
+ addNode = function (el) {
+ body.insertBefore(el, firstChild);
+ };
+ } else {
+ addNode = function (el) {
+ body.appendChild(el)
+ };
+ }
+ addNode(togglePassed);
+ addNode(dom.SPAN(null, " "));
+ addNode(toggleFailed);
+ addNode(SimpleTest.report());
+};
+
+/**
+ * Tells SimpleTest to don't finish the test when the document is loaded,
+ * useful for asynchronous tests.
+ *
+ * When SimpleTest.waitForExplicitFinish is called,
+ * explicit SimpleTest.finish() is required.
+**/
+SimpleTest.waitForExplicitFinish = function () {
+ SimpleTest._stopOnLoad = false;
+};
+
+/**
+ * Talks to the TestRunner if being ran on a iframe and the parent has a
+ * TestRunner object.
+**/
+SimpleTest.talkToRunner = function () {
+ if (typeof(parent) != "undefined" && parent.TestRunner) {
+ parent.TestRunner.testFinished(document);
+ }
+};
+
+/**
+ * Finishes the tests. This is automatically called, except when
+ * SimpleTest.waitForExplicitFinish() has been invoked.
+**/
+SimpleTest.finish = function () {
+ SimpleTest.showReport();
+ SimpleTest.talkToRunner();
+};
+
+
+MochiKit.DOM.addLoadEvent(function() {
+ if (SimpleTest._stopOnLoad) {
+ SimpleTest.finish();
+ }
+});
+
+// --------------- Test.Builder/Test.More isDeeply() -----------------
+
+
+SimpleTest.DNE = {dne: 'Does not exist'};
+SimpleTest.LF = "\r\n";
+SimpleTest._isRef = function (object) {
+ var type = typeof(object);
+ return type == 'object' || type == 'function';
+};
+
+
+SimpleTest._deepCheck = function (e1, e2, stack, seen) {
+ var ok = false;
+ // Either they're both references or both not.
+ var sameRef = !(!SimpleTest._isRef(e1) ^ !SimpleTest._isRef(e2));
+ if (e1 == null && e2 == null) {
+ ok = true;
+ } else if (e1 != null ^ e2 != null) {
+ ok = false;
+ } else if (e1 == SimpleTest.DNE ^ e2 == SimpleTest.DNE) {
+ ok = false;
+ } else if (sameRef && e1 == e2) {
+ // Handles primitives and any variables that reference the same
+ // object, including functions.
+ ok = true;
+ } else if (SimpleTest.isa(e1, 'Array') && SimpleTest.isa(e2, 'Array')) {
+ ok = SimpleTest._eqArray(e1, e2, stack, seen);
+ } else if (typeof e1 == "object" && typeof e2 == "object") {
+ ok = SimpleTest._eqAssoc(e1, e2, stack, seen);
+ } else {
+ // If we get here, they're not the same (function references must
+ // always simply rererence the same function).
+ stack.push({ vals: [e1, e2] });
+ ok = false;
+ }
+ return ok;
+};
+
+SimpleTest._eqArray = function (a1, a2, stack, seen) {
+ // Return if they're the same object.
+ if (a1 == a2) return true;
+
+ // JavaScript objects have no unique identifiers, so we have to store
+ // references to them all in an array, and then compare the references
+ // directly. It's slow, but probably won't be much of an issue in
+ // practice. Start by making a local copy of the array to as to avoid
+ // confusing a reference seen more than once (such as [a, a]) for a
+ // circular reference.
+ for (var j = 0; j < seen.length; j++) {
+ if (seen[j][0] == a1) {
+ return seen[j][1] == a2;
+ }
+ }
+
+ // If we get here, we haven't seen a1 before, so store it with reference
+ // to a2.
+ seen.push([ a1, a2 ]);
+
+ var ok = true;
+ // Only examines enumerable attributes. Only works for numeric arrays!
+ // Associative arrays return 0. So call _eqAssoc() for them, instead.
+ var max = a1.length > a2.length ? a1.length : a2.length;
+ if (max == 0) return SimpleTest._eqAssoc(a1, a2, stack, seen);
+ for (var i = 0; i < max; i++) {
+ var e1 = i > a1.length - 1 ? SimpleTest.DNE : a1[i];
+ var e2 = i > a2.length - 1 ? SimpleTest.DNE : a2[i];
+ stack.push({ type: 'Array', idx: i, vals: [e1, e2] });
+ if (ok = SimpleTest._deepCheck(e1, e2, stack, seen)) {
+ stack.pop();
+ } else {
+ break;
+ }
+ }
+ return ok;
+};
+
+SimpleTest._eqAssoc = function (o1, o2, stack, seen) {
+ // Return if they're the same object.
+ if (o1 == o2) return true;
+
+ // JavaScript objects have no unique identifiers, so we have to store
+ // references to them all in an array, and then compare the references
+ // directly. It's slow, but probably won't be much of an issue in
+ // practice. Start by making a local copy of the array to as to avoid
+ // confusing a reference seen more than once (such as [a, a]) for a
+ // circular reference.
+ seen = seen.slice(0);
+ for (var j = 0; j < seen.length; j++) {
+ if (seen[j][0] == o1) {
+ return seen[j][1] == o2;
+ }
+ }
+
+ // If we get here, we haven't seen o1 before, so store it with reference
+ // to o2.
+ seen.push([ o1, o2 ]);
+
+ // They should be of the same class.
+
+ var ok = true;
+ // Only examines enumerable attributes.
+ var o1Size = 0; for (var i in o1) o1Size++;
+ var o2Size = 0; for (var i in o2) o2Size++;
+ var bigger = o1Size > o2Size ? o1 : o2;
+ for (var i in bigger) {
+ var e1 = o1[i] == undefined ? SimpleTest.DNE : o1[i];
+ var e2 = o2[i] == undefined ? SimpleTest.DNE : o2[i];
+ stack.push({ type: 'Object', idx: i, vals: [e1, e2] });
+ if (ok = SimpleTest._deepCheck(e1, e2, stack, seen)) {
+ stack.pop();
+ } else {
+ break;
+ }
+ }
+ return ok;
+};
+
+SimpleTest._formatStack = function (stack) {
+ var variable = '$Foo';
+ for (var i = 0; i < stack.length; i++) {
+ var entry = stack[i];
+ var type = entry['type'];
+ var idx = entry['idx'];
+ if (idx != null) {
+ if (/^\d+$/.test(idx)) {
+ // Numeric array index.
+ variable += '[' + idx + ']';
+ } else {
+ // Associative array index.
+ idx = idx.replace("'", "\\'");
+ variable += "['" + idx + "']";
+ }
+ }
+ }
+
+ var vals = stack[stack.length-1]['vals'].slice(0, 2);
+ var vars = [
+ variable.replace('$Foo', 'got'),
+ variable.replace('$Foo', 'expected')
+ ];
+
+ var out = "Structures begin differing at:" + SimpleTest.LF;
+ for (var i = 0; i < vals.length; i++) {
+ var val = vals[i];
+ if (val == null) {
+ val = 'undefined';
+ } else {
+ val == SimpleTest.DNE ? "Does not exist" : "'" + val + "'";
+ }
+ }
+
+ out += vars[0] + ' = ' + vals[0] + SimpleTest.LF;
+ out += vars[1] + ' = ' + vals[1] + SimpleTest.LF;
+
+ return ' ' + out;
+};
+
+
+SimpleTest.isDeeply = function (it, as, name) {
+ var ok;
+ // ^ is the XOR operator.
+ if (SimpleTest._isRef(it) ^ SimpleTest._isRef(as)) {
+ // One's a reference, one isn't.
+ ok = false;
+ } else if (!SimpleTest._isRef(it) && !SimpleTest._isRef(as)) {
+ // Neither is an object.
+ ok = SimpleTest.is(it, as, name);
+ } else {
+ // We have two objects. Do a deep comparison.
+ var stack = [], seen = [];
+ if ( SimpleTest._deepCheck(it, as, stack, seen)) {
+ ok = SimpleTest.ok(true, name);
+ } else {
+ ok = SimpleTest.ok(false, name, SimpleTest._formatStack(stack));
+ }
+ }
+ return ok;
+};
+
+SimpleTest.typeOf = function (object) {
+ var c = Object.prototype.toString.apply(object);
+ var name = c.substring(8, c.length - 1);
+ if (name != 'Object') return name;
+ // It may be a non-core class. Try to extract the class name from
+ // the constructor function. This may not work in all implementations.
+ if (/function ([^(\s]+)/.test(Function.toString.call(object.constructor))) {
+ return RegExp.$1;
+ }
+ // No idea. :-(
+ return name;
+};
+
+SimpleTest.isa = function (object, clas) {
+ return SimpleTest.typeOf(object) == clas;
+};
+
+
+
+// Global symbols:
+var ok = SimpleTest.ok;
+var is = SimpleTest.is;
+var isDeeply = SimpleTest.isDeeply;
diff --git a/frontend/gamma/tests/SimpleTest/TestRunner.js b/frontend/gamma/tests/SimpleTest/TestRunner.js
new file mode 100644
index 0000000..81a36cf
--- a/dev/null
+++ b/frontend/gamma/tests/SimpleTest/TestRunner.js
@@ -0,0 +1,233 @@
+/**
+ * TestRunner: A test runner for SimpleTest
+ * TODO:
+ *
+ * * Avoid moving iframes: That causes reloads on mozilla and opera.
+ *
+ *
+**/
+var TestRunner = {};
+TestRunner.logEnabled = false;
+TestRunner._iframes = {};
+TestRunner._iframeDocuments = {};
+TestRunner._iframeRows = {};
+TestRunner._currentTest = 0;
+TestRunner._urls = [];
+TestRunner._testsDiv = DIV();
+TestRunner._progressDiv = DIV();
+TestRunner._summaryDiv = DIV(null,
+ H1(null, "Tests Summary"),
+ TABLE(null,
+ THEAD(null,
+ TR(null,
+ TH(null, "Test"),
+ TH(null, "Passed"),
+ TH(null, "Failed")
+ )
+ ),
+ TFOOT(/*null, TR(null, TH(null, "-"), TH(null, "--"), TH(null, "---"))*/),
+ TBODY()
+ )
+);
+
+/**
+ * This function is called after generating the summary.
+**/
+TestRunner.onComplete = null;
+
+/**
+ * If logEnabled is true, this is the logger that will be used.
+**/
+TestRunner.logger = MochiKit.Logging.logger;
+
+/**
+ * Toggle element visibility
+**/
+TestRunner._toggle = function(el) {
+ if (el.className == "noshow") {
+ el.className = "";
+ el.style.cssText = "";
+ } else {
+ el.className = "noshow";
+ el.style.cssText = "width:0px; height:0px; border:0px;";
+ }
+};
+
+
+/**
+ * Creates the iframe that contains a test
+**/
+TestRunner._makeIframe = function (url) {
+ var iframe = document.createElement('iframe');
+ iframe.src = url;
+ iframe.name = url;
+ iframe.width = "500";
+ var tbody = TestRunner._summaryDiv.getElementsByTagName("tbody")[0];
+ var tr = TR(null, TD({'colspan': '3'}, iframe));
+ iframe._row = tr;
+ tbody.appendChild(tr);
+ return iframe;
+};
+
+/**
+ * TestRunner entry point.
+ *
+ * The arguments are the URLs of the test to be ran.
+ *
+**/
+TestRunner.runTests = function (/*url...*/) {
+ if (TestRunner.logEnabled)
+ TestRunner.logger.log("SimpleTest START");
+
+ var body = document.getElementsByTagName("body")[0];
+ appendChildNodes(body,
+ TestRunner._testsDiv,
+ TestRunner._progressDiv,
+ TestRunner._summaryDiv
+ );
+ for (var i = 0; i < arguments.length; i++) {
+ TestRunner._urls.push(arguments[i]);
+ }
+
+ TestRunner.runNextTest();
+};
+
+/**
+ * Run the next test. If no test remains, calls makeSummary
+**/
+TestRunner.runNextTest = function() {
+ if (TestRunner._currentTest < TestRunner._urls.length) {
+ var url = TestRunner._urls[TestRunner._currentTest];
+ var progress = SPAN(null,
+ "Running ", A({href:url}, url), "..."
+ );
+
+ if (TestRunner.logEnabled)
+ TestRunner.logger.log(scrapeText(progress));
+
+ TestRunner._progressDiv.appendChild(progress);
+ TestRunner._iframes[url] = TestRunner._makeIframe(url);
+ } else {
+ TestRunner.makeSummary();
+ if (TestRunner.onComplete) {
+ TestRunner.onComplete();
+ }
+ }
+};
+
+/**
+ * This stub is called by SimpleTest when a test is finished.
+**/
+TestRunner.testFinished = function (doc) {
+ appendChildNodes(TestRunner._progressDiv, SPAN(null, "Done"), BR());
+ var finishedURL = TestRunner._urls[TestRunner._currentTest];
+
+ if (TestRunner.logEnabled)
+ TestRunner.logger.debug("SimpleTest finished " + finishedURL);
+
+ TestRunner._iframeDocuments[finishedURL] = doc;
+ // TestRunner._iframes[finishedURL].style.display = "none";
+ if (finishedURL != null) {
+ TestRunner._toggle(TestRunner._iframes[finishedURL]);
+ TestRunner._currentTest++;
+ TestRunner.runNextTest();
+ }
+};
+
+/**
+ * Display the summary in the browser
+**/
+/*
+TestRunner.makeSummary = function() {
+ if (TestRunner.logEnabled)
+ TestRunner.logger.log("SimpleTest FINISHED");
+ var rows = [];
+ for (var url in TestRunner._iframeDocuments) {
+ var doc = TestRunner._iframeDocuments[url];
+ var nOK = withDocument(doc,
+ partial(getElementsByTagAndClassName, 'div', 'test_ok')
+ ).length;
+ var nNotOK = withDocument(doc,
+ partial(getElementsByTagAndClassName, 'div', 'test_not_ok')
+ ).length;
+ var toggle = partial(TestRunner._toggle, TestRunner._iframes[url]);
+ var jsurl = "TestRunner._toggle(TestRunner._iframes['" + url + "'])";
+ var row = TR(
+ {'style': {'backgroundColor': nNotOK > 0 ? "#f00":"#0f0"}},
+ TD(null, url),
+ TD(null, nOK),
+ TD(null, nNotOK)
+ );
+ row.onclick = toggle;
+ var tbody = TestRunner._summaryDiv.getElementsByTagName("tbody")[0];
+ tbody.insertBefore(row, TestRunner._iframes[url]._row)
+ }
+};
+*/
+
+TestRunner.makeSummary = function() {
+ var base = MochiKit.Base;
+ var dom = MochiKit.DOM;
+ var iter = MochiKit.Iter;
+ var total_Ok, total_not_Ok;
+
+ total_Ok = 0;
+ total_not_Ok = 0;
+
+ if (TestRunner.logEnabled)
+ TestRunner.logger.log("SimpleTest FINISHED");
+ var rows = [];
+ for (var url in TestRunner._iframeDocuments) {
+ var doc = TestRunner._iframeDocuments[url];
+ var nOK = withDocument(doc,
+ partial(getElementsByTagAndClassName, 'div', 'test_ok')
+ ).length;
+ var nNotOK = withDocument(doc,
+ partial(getElementsByTagAndClassName, 'div', 'test_not_ok')
+ ).length;
+ var toggle = partial(TestRunner._toggle, TestRunner._iframes[url]);
+ var jsurl = "TestRunner._toggle(TestRunner._iframes['" + url + "'])";
+ var row = TR(
+ {'style': {'backgroundColor': nNotOK > 0 ? "#f00":"#0f0"}},
+ TD(null, url),
+ TD(null, nOK),
+ TD(null, nNotOK)
+ );
+ row.onclick = toggle;
+ var tbody = TestRunner._summaryDiv.getElementsByTagName("tbody")[0];
+ tbody.insertBefore(row, TestRunner._iframes[url]._row);
+
+ total_Ok += nOK;
+ total_not_Ok += nNotOK;
+ }
+
+ {
+ var tfoot = TestRunner._summaryDiv.getElementsByTagName("tfoot")[0];
+ tfoot.appendChild(TR(null,
+ TH(null, ""),
+ TH({'style':"color:green;"}, total_Ok),
+ TH({'style':"color:" + ((total_not_Ok == 0) ? 'black' : 'red') + ";"}, total_not_Ok)
+ ));
+ }
+
+ var testRunnerResults;
+ var i, c;
+
+ testRunnerResults = dom.DIV({'style': 'display:none; visibility:hidden;'}, null);
+
+ c = total_Ok;
+ for (i=0; i<c; i++) {
+ dom.appendChildNodes(testRunnerResults, dom.DIV({'class': 'test_ok'}, "ok"));
+ }
+
+ c = total_not_Ok;
+ for (i=0; i<c; i++) {
+ dom.appendChildNodes(testRunnerResults, dom.DIV({'class': 'test_not_ok'}, "fail"));
+ }
+
+ document.getElementsByTagName("body")[0].appendChild(testRunnerResults);
+
+ if (typeof(parent) != "undefined" && parent.TestRunner) {
+ parent.TestRunner.testFinished(document);
+ }
+};
diff --git a/frontend/gamma/tests/SimpleTest/test.css b/frontend/gamma/tests/SimpleTest/test.css
new file mode 100644
index 0000000..38a4014
--- a/dev/null
+++ b/frontend/gamma/tests/SimpleTest/test.css
@@ -0,0 +1,28 @@
+.test_ok {
+ color: green;
+ display: none;
+}
+.test_not_ok {
+ color: red;
+ display: block;
+}
+
+.test_ok, .test_not_ok {
+ border-bottom-width: 2px;
+ border-bottom-style: solid;
+ border-bottom-color: black;
+}
+
+.all_pass {
+ background-color: lime;
+}
+
+.some_fail {
+ background-color: red;
+}
+
+.tests_report {
+ border-width: 2px;
+ border-style: solid;
+ width: 20em;
+}
diff --git a/frontend/gamma/tests/index.html b/frontend/gamma/tests/index.html
new file mode 100755
index 0000000..865f8f1
--- a/dev/null
+++ b/frontend/gamma/tests/index.html
@@ -0,0 +1,56 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <script type="text/javascript" src="../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="./SimpleTest/TestRunner.js"></script>
+</head>
+<body>
+<script type="text/javascript">
+TestRunner.runTests(
+/*
+// 'tests/Clipperz/Base.html',
+// 'tests/Clipperz/Set.html',
+ 'tests/Clipperz/index.html',
+
+// 'tests/Clipperz/Crypto/Base.html',
+// 'tests/Clipperz/Crypto/BigInt.html',
+// 'tests/Clipperz/Crypto/SRP.html'
+ 'tests/Clipperz/Crypto/index.html',
+ 'tests/Clipperz/PM/index.html',
+ 'tests/Clipperz/PM/DataModel/index.html'
+*/
+
+ 'tests/index.html'
+
+
+);
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Bookmarklet/Bookmarklet.css b/frontend/gamma/tests/tests/Bookmarklet/Bookmarklet.css
new file mode 100644
index 0000000..3847475
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Bookmarklet/Bookmarklet.css
@@ -0,0 +1,201 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+/* @override
+ http://localhost:8000/tests/js/tests/Bookmarklet/Bookmarklet.css
+ http://www.clipperz.com/files/clipperz.com/bookmarklet/0.3.0/Bookmarklet.css
+*/
+
+div#clipperzBookmarklet {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+
+ position: absolute;
+ top: 80px;
+ left: 100px;
+ width: 202px;
+ height: 202px;
+ background: url(./background.png) no-repeat;
+}
+
+div#clipperzBookmarklet div#clipperzBookmarkletClose {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+
+ position: absolute;
+ left: 168px;
+ top: 5px;
+ width: 25px;
+ height: 25px;
+ background: url(./close.png) no-repeat;
+}
+
+div#clipperzBookmarklet div#clipperzBookmarkletClose:hover {
+ background: url(./close_selected.png) no-repeat;
+ cursor: pointer;
+}
+
+div#clipperzBookmarklet div#clipperzBookmarkletResult {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+
+ position: absolute;
+ width: 145px;
+ top: 61px;
+ left: 27px;
+ height: 63px;
+ overflow: hidden;
+}
+
+div#clipperzBookmarklet div#clipperzBookmarkletResultIcon {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+
+ width: 28px;
+ height: 35px;
+ position: absolute;
+}
+
+div#clipperzBookmarklet div#clipperzBookmarkletResultIcon.ok {
+ background: transparent url(./info.png);
+}
+
+div#clipperzBookmarklet div#clipperzBookmarkletResultIcon.fail {
+ background: transparent url(./error.png);
+}
+
+div#clipperzBookmarklet div#clipperzBookmarkletResult p {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+
+ font-family: Helvetica, Arial, Geneva, sans-serif;
+ color: #898e7d;
+ font-size: 14px;
+ margin-left: 35px;
+}
+
+div#clipperzBookmarklet div#clipperzBookmarletButton {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+
+ position: absolute;
+ top: 125px;
+ left: 26px;
+ width: 148px;
+ height: 49px;
+ background: url(./copy.png) no-repeat;
+}
+
+div#clipperzBookmarklet div#clipperzBookmarletButton span {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+
+ display: block;
+ font-family: Helvetica, Arial, Geneva, sans-serif;
+ font-weight: bold;
+ font-size: 14pt;
+ padding-left: 60px;
+ padding-top: 12px;
+ color: #838975;
+}
+
+div#clipperzBookmarklet div#clipperzBookmarletButton.hover {
+ background: url(./copy_selected.png) no-repeat;
+}
+
+
+div#clipperzBookmarklet div#clipperzBookmarletAfterCopyHint.hidden {
+ display: none;
+}
+
+
+div#clipperzBookmarklet div#clipperzBookmarletAfterCopyHint {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+
+ position: absolute;
+ top: 78px;
+ left: 135px;
+ width: 171px;
+ height: 72px;
+ background: url(./hint.png) no-repeat;
+}
+
+div#clipperzBookmarklet div#clipperzBookmarletAfterCopyHint p {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-size: 100%;
+ vertical-align: baseline;
+ background: transparent;
+
+ padding: 10px;
+ font-family: Helvetica, Arial, Geneva, sans-serif;
+ color: white;
+ font-size: 13px;
+} \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Bookmarklet/Fail.html b/frontend/gamma/tests/tests/Bookmarklet/Fail.html
new file mode 100644
index 0000000..9a95bad
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Bookmarklet/Fail.html
@@ -0,0 +1,113 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Bookmarlet TEST - fail</title>
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../SimpleTest/test.css">
+
+ <!-- link rel="stylesheet" type="text/css" href="./Bookmarklet.css" -->
+ <script type='text/javascript' src='../../../js/Bookmarklet.js'></script>
+ <script type='text/javascript' src='../../../../_build/_scratch/bookmarklet_test.js'></script>
+</head>
+<body>
+
+<!-- TWITTER Login Form -->
+<!-- form id="signin" action="https://twitter.com/sessions" method="post">
+ <input id="authenticity_token" type="hidden" value="a3a9abfa089122e4b437736313e54f2a25911101" name="authenticity_token"/>
+ <fieldset class="common-form standard-form">
+ <legend>Please sign in</legend>
+ <p>
+ <label class="inside" for="username" tabindex="1">user name or email address:</label>
+ <input id="username" type="text" title="username" value="" name="session[username_or_email]"/>
+ </p>
+ <p>
+ <label class="inside" for="password" tabindex="2">password:</label>
+ <input id="password" type="password" title="password" value="" name="session[password]"/>
+ </p>
+ <p class="remember"></p>
+ <p class="submit"></p>
+ <p class="forgot"></p>
+ <p class="complete"></p>
+ </fieldset>
+</form -->
+
+<!-- ###################################################################### -->
+<!--
+<div id="clipperzBookmarklet" style="">
+ <div id="clipperzBookmarkletResult" style=""><p>The direct login configuration has been collected.</p></div>
+ <div id="clipperzBookmarletButton" style=""></div>
+ <div id="clipperzBookmarletAfterCopyHint" style=""><p>Now you can return to the Clipperz main interface and create a new card</p></div>
+</div>
+-->
+<!--
+<div id="clipperzBookmarklet">
+ <div id="clipperzBookmarkletResult"><div id="clipperzBookmarkletResultIcon"></div><p id="clipperzBookmarkletResultText"></p></div>
+ <div id="clipperzBookmarletButton"></div>
+ <div id="clipperzBookmarletAfterCopyHint"><p id="clipperzBookmarkletHintText"></p></div>
+</div>
+-->
+
+
+<!-- ###################################################################### -->
+
+<pre id="test">
+<script type="text/javascript">
+try {
+ runBookmarklet();
+// var parameters;
+// runBookmarklet();
+
+// parameters = getLoginFormConfiguration();
+
+// SimpleTest.ok(parameters != null, "The bookmarklet returns something useful");
+// SimpleTest.ok(bookmarkletClip != null, "The clipboard bridge has been created");
+// SimpleTest.ok(bookmarkletClip.ready, "The clipboard bridge has been created AND is ready");
+ SimpleTest.ok(true, "no exception raised");
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Bookmarklet/Twitter.html b/frontend/gamma/tests/tests/Bookmarklet/Twitter.html
new file mode 100644
index 0000000..c9ee827
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Bookmarklet/Twitter.html
@@ -0,0 +1,113 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Bookmarlet TEST - ok</title>
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../SimpleTest/test.css">
+
+ <!-- link rel="stylesheet" type="text/css" href="./Bookmarklet.css" -->
+ <script type='text/javascript' src='../../../js/Bookmarklet.js'></script>
+ <script type='text/javascript' src='../../../../_build/_scratch/bookmarklet_test.js'></script>
+</head>
+<body>
+
+<!-- TWITTER Login Form -->
+<form id="signin" action="https://twitter.com/sessions" method="post">
+ <input id="authenticity_token" type="hidden" value="a3a9abfa089122e4b437736313e54f2a25911101" name="authenticity_token"/>
+ <fieldset class="common-form standard-form">
+ <legend>Please sign in</legend>
+ <p>
+ <label class="inside" for="username" tabindex="1">user name or email address:</label>
+ <input id="username" type="text" title="username" value="" name="session[username_or_email]"/>
+ </p>
+ <p>
+ <label class="inside" for="password" tabindex="2">password:</label>
+ <input id="password" type="password" title="password" value="" name="session[password]"/>
+ </p>
+ <p class="remember"></p>
+ <p class="submit"></p>
+ <p class="forgot"></p>
+ <p class="complete"></p>
+ </fieldset>
+</form>
+
+<!-- ###################################################################### -->
+<!--
+<div id="clipperzBookmarklet" style="">
+ <div id="clipperzBookmarkletResult" style=""><p>The direct login configuration has been collected.</p></div>
+ <div id="clipperzBookmarletButton" style=""></div>
+ <div id="clipperzBookmarletAfterCopyHint" style=""><p>Now you can return to the Clipperz main interface and create a new card</p></div>
+</div>
+-->
+<!--
+<div id="clipperzBookmarklet">
+ <div id="clipperzBookmarkletResult"><div id="clipperzBookmarkletResultIcon"></div><p id="clipperzBookmarkletResultText"></p></div>
+ <div id="clipperzBookmarletButton"></div>
+ <div id="clipperzBookmarletAfterCopyHint"><p id="clipperzBookmarkletHintText"></p></div>
+</div>
+-->
+
+
+<!-- ###################################################################### -->
+
+<pre id="test">
+<script type="text/javascript">
+try {
+ runBookmarklet();
+// var parameters;
+// runBookmarklet();
+
+// parameters = getLoginFormConfiguration();
+
+// SimpleTest.ok(parameters != null, "The bookmarklet returns something useful");
+// SimpleTest.ok(bookmarkletClip != null, "The clipboard bridge has been created");
+// SimpleTest.ok(bookmarkletClip.ready, "The clipboard bridge has been created AND is ready");
+ SimpleTest.ok(true, "no exception raised");
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Bookmarklet/ZeroClipboard.swf b/frontend/gamma/tests/tests/Bookmarklet/ZeroClipboard.swf
new file mode 100755
index 0000000..13bf8e3
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Bookmarklet/ZeroClipboard.swf
Binary files differ
diff --git a/frontend/gamma/tests/tests/Bookmarklet/background.png b/frontend/gamma/tests/tests/Bookmarklet/background.png
new file mode 100644
index 0000000..db5cdc3
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Bookmarklet/background.png
Binary files differ
diff --git a/frontend/gamma/tests/tests/Bookmarklet/close.png b/frontend/gamma/tests/tests/Bookmarklet/close.png
new file mode 100644
index 0000000..c07f0cb
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Bookmarklet/close.png
Binary files differ
diff --git a/frontend/gamma/tests/tests/Bookmarklet/close_selected.png b/frontend/gamma/tests/tests/Bookmarklet/close_selected.png
new file mode 100644
index 0000000..0265f0d
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Bookmarklet/close_selected.png
Binary files differ
diff --git a/frontend/gamma/tests/tests/Bookmarklet/copy.png b/frontend/gamma/tests/tests/Bookmarklet/copy.png
new file mode 100644
index 0000000..299c613
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Bookmarklet/copy.png
Binary files differ
diff --git a/frontend/gamma/tests/tests/Bookmarklet/copy_selected.png b/frontend/gamma/tests/tests/Bookmarklet/copy_selected.png
new file mode 100644
index 0000000..f7015b7
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Bookmarklet/copy_selected.png
Binary files differ
diff --git a/frontend/gamma/tests/tests/Bookmarklet/error.png b/frontend/gamma/tests/tests/Bookmarklet/error.png
new file mode 100644
index 0000000..ad56403
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Bookmarklet/error.png
Binary files differ
diff --git a/frontend/gamma/tests/tests/Bookmarklet/hint.png b/frontend/gamma/tests/tests/Bookmarklet/hint.png
new file mode 100644
index 0000000..9f83114
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Bookmarklet/hint.png
Binary files differ
diff --git a/frontend/gamma/tests/tests/Bookmarklet/index.html b/frontend/gamma/tests/tests/Bookmarklet/index.html
new file mode 100644
index 0000000..729bf21
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Bookmarklet/index.html
@@ -0,0 +1,42 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Complete TEST suite</title>
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/TestRunner.js"></script>
+</head>
+<body>
+<script>
+TestRunner.runTests(
+ 'Twitter.html'
+);
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Bookmarklet/info.png b/frontend/gamma/tests/tests/Bookmarklet/info.png
new file mode 100644
index 0000000..256eb40
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Bookmarklet/info.png
Binary files differ
diff --git a/frontend/gamma/tests/tests/Clipperz/Async.html b/frontend/gamma/tests/tests/Clipperz/Async.html
new file mode 100644
index 0000000..02f4de2
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Async.html
@@ -0,0 +1,53 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.Async - test</title>
+
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Async.js'></script>
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.Async.js"></script>
+</head>
+<body>
+
+<pre id="test">
+<!--<script type="text/javascript" src="User.data.js"></script>//-->
+<script type="text/javascript" src="Async.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Async.test.js b/frontend/gamma/tests/tests/Clipperz/Async.test.js
new file mode 100644
index 0000000..fa6daca
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Async.test.js
@@ -0,0 +1,687 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+testObject = function (aLabel) {
+ this._label = aLabel;
+ this._sibling = null;
+}
+
+testObject.prototype = {
+ 'label': function () {
+ return MochiKit.Async.succeed(this._label);
+ },
+
+ 'shouldHit': function () {
+ var filterRegExp;
+
+ filterRegExp = new RegExp("hit", "i");
+
+ return Clipperz.Async.callbacks("testObject.shouldHit", [
+ MochiKit.Base.method(this, 'label'),
+ MochiKit.Base.method(filterRegExp, 'test')
+ ]);
+ },
+
+ 'sibling': function () {
+ return this._sibling;
+ },
+
+ 'setSibling': function (aSibling) {
+ this._sibling = aSibling;
+ }
+
+}
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+
+ 'succeedingForkedDeferrer_test': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred('Async.test succeedingForkedDeferred', someTestArgs);
+ deferredResult.addCallback(Clipperz.Async.forkAndJoin("Async.test succeedingForkedDeferred",
+ [
+ MochiKit.Base.partial(MochiKit.Async.succeed, 3),
+ MochiKit.Base.partial(MochiKit.Async.succeed, 2)
+ ], someTestArgs
+ ));
+ deferredResult.addCallback(function (anAsyncResult) {
+ var sum;
+
+ sum = MochiKit.Iter.reduce(MochiKit.Base.operator.add, anAsyncResult);
+ SimpleTest.is(sum, 5, "the sum of all the returned results should be 5");
+ });
+ deferredResult.addErrback(function() {
+ SimpleTest.ok(false, "forkAndJoin should succeed and execution path should NOT go through here (1)")
+ })
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'succeedingForkedAndWaitDeferrer_test': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred('succeedingForkedAndWaitDeferrer_test', someTestArgs);
+ deferredResult.addCallback(Clipperz.Async.forkAndJoin("Async.test succeedingForkedAndWaitDeferrer",
+ [
+ MochiKit.Base.partial(MochiKit.Async.callLater, 2, MochiKit.Async.succeed, 3),
+ MochiKit.Base.partial(MochiKit.Async.callLater, 1, MochiKit.Async.succeed, 2),
+ MochiKit.Base.partial(MochiKit.Async.callLater, 3, MochiKit.Async.succeed, 7)
+ ], someTestArgs
+ ));
+ deferredResult.addCallback(function (anAsyncResult) {
+ var sum;
+
+ sum = MochiKit.Iter.reduce(MochiKit.Base.operator.add, anAsyncResult);
+ SimpleTest.is(sum, 12, "the sum of all the returned results should be 12");
+ });
+ deferredResult.addErrback(function() {
+ SimpleTest.ok(false, "forkAndJoin should succeed and execution path should NOT go through here (2)")
+ })
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'failingForkedDeferrer_test': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred('Async.test failingForkedDeferred', someTestArgs);
+ deferredResult.addCallback(Clipperz.Async.forkAndJoin("Async.test failingForkedDeferred",
+ [
+ MochiKit.Async.succeed,
+ MochiKit.Async.fail
+ ], someTestArgs
+ ));
+ deferredResult.addCallback(function () {
+ SimpleTest.ok(false, "forkAndJoin should fail, and execution path should NOT go through here");
+ });
+ deferredResult.addErrback(function() {
+ SimpleTest.ok(true, "forkAndJoin should fail and execution path should go through here")
+ })
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'succeedingCollectResultsDeferrer_test': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred('Async.test succeedingCollectResultsDeferrer', someTestArgs);
+ deferredResult.addCallback(Clipperz.Async.collectResults('Async.test succeedingCollectResultsDeferrer', {
+ 'first': MochiKit.Base.partial(MochiKit.Async.callLater, 2, MochiKit.Async.succeed, 3),
+ 'second': MochiKit.Base.partial(MochiKit.Async.callLater, 1, MochiKit.Async.succeed, 2),
+ 'third': MochiKit.Base.partial(MochiKit.Async.callLater, 3, MochiKit.Async.succeed, 7)
+ }, someTestArgs));
+ deferredResult.addCallback(function (anAsyncResult) {
+ var sum;
+
+ sum = MochiKit.Iter.reduce(MochiKit.Base.operator.add, MochiKit.Base.values(anAsyncResult));
+ SimpleTest.is(sum, 12, "the sum of all the returned results should be 12");
+ SimpleTest.is(anAsyncResult['first'], 3, "the result of the 'first' item is 3");
+ SimpleTest.is(anAsyncResult['second'], 2, "the result of the 'second' item is 2");
+ SimpleTest.is(anAsyncResult['third'], 7, "the result of the 'third' item is 7");
+ SimpleTest.is(MochiKit.Base.keys(anAsyncResult).length, 3, "the result has exactly 3 values");
+ });
+ deferredResult.addErrback(function() {
+ SimpleTest.ok(false, "collectResults should succeed and execution path should NOT go through here");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'collectResultsWithParameter_test': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred('collectResultsWithParameter_test', someTestArgs);
+ deferredResult.collectResults({
+ 'add_3': MochiKit.Base.partial(MochiKit.Base.operator.add, 3),
+ 'sub_8': MochiKit.Base.partial(MochiKit.Base.operator.sub, 8),
+ 'mul_4': MochiKit.Base.partial(MochiKit.Base.operator.mul, 4)
+ });
+ deferredResult.addCallback(function (anAsyncResult) {
+ SimpleTest.is(anAsyncResult['add_3'], 8, "adding 3 to the passed value (5) returns 8");
+ SimpleTest.is(anAsyncResult['sub_8'], 3, "subtracting the passed value (5) to 8 returns 3");
+ SimpleTest.is(anAsyncResult['mul_4'], 20, "multiplying the passed value (5) by 4 returns 20");
+ SimpleTest.is(MochiKit.Base.keys(anAsyncResult).length, 3, "the result has exactly 3 values");
+ });
+ deferredResult.callback(5);
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'succeedingCollectResultsDeferrer_alternative_syntax_test': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred('succeedingCollectResultsDeferrer_alternative_syntax_test', someTestArgs);
+ deferredResult.collectResults({
+ 'first': MochiKit.Base.partial(MochiKit.Async.callLater, 2, MochiKit.Async.succeed, 3),
+ 'second': MochiKit.Base.partial(MochiKit.Async.callLater, 1, MochiKit.Async.succeed, 2),
+ 'third': MochiKit.Base.partial(MochiKit.Async.callLater, 3, MochiKit.Async.succeed, 7)
+ });
+ deferredResult.addCallback(function (anAsyncResult) {
+ var sum;
+
+ sum = MochiKit.Iter.reduce(MochiKit.Base.operator.add, MochiKit.Base.values(anAsyncResult));
+ SimpleTest.is(sum, 12, "the sum of all the returned results should be 12");
+ SimpleTest.is(anAsyncResult['first'], 3, "the result of the 'first' item is 3");
+ SimpleTest.is(anAsyncResult['second'], 2, "the result of the 'second' item is 2");
+ SimpleTest.is(anAsyncResult['third'], 7, "the result of the 'third' item is 7");
+ SimpleTest.is(MochiKit.Base.keys(anAsyncResult).length, 3, "the result has exactly 3 values");
+ });
+ deferredResult.addErrback(function() {
+ SimpleTest.ok(false, "collectResults should succeed and execution path should NOT go through here");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'failingCollectResultsDeferrer_test': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred('Async.test failingCollectResultsDeferrer', someTestArgs);
+ deferredResult.addCallback(Clipperz.Async.collectResults('Async.test failingCollectResultsDeferrer', {
+ 'succeed': MochiKit.Base.partial(MochiKit.Async.succeed, 3),
+ 'fail': MochiKit.Base.partial(MochiKit.Async.fail, 2)
+ }, someTestArgs));
+ deferredResult.addCallback(function() {
+ SimpleTest.ok(false, "collectResults should fail and execution path should NOT go through here");
+ });
+ deferredResult.addErrback(function (anAsyncResult) {
+ var result;
+
+ result = anAsyncResult['message'];
+ SimpleTest.is(MochiKit.Base.keys(result).length, 2, "the result has exactly 2 values");
+//console.log("anAsyncResult", anAsyncResult);
+ SimpleTest.ok(!(result['succeed'] instanceof Error), "the successful value is actually successful");
+ SimpleTest.ok(result['fail'] instanceof Error, "the failed value is actually failed");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'collectResults_withSimpleArrayListOfCalls_test': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred('collectResults_withSimpleArrayListOfCalls_test', someTestArgs);
+ deferredResult.addCallback(Clipperz.Async.collectResults('collectResults_withSimpleArrayListOfCalls_test - collectResults', {
+ 'path1': [
+ MochiKit.Base.partial(MochiKit.Async.succeed, 3)
+ ],
+ 'path2': MochiKit.Base.partial(MochiKit.Async.succeed, 2)
+ }, someTestArgs));
+ deferredResult.addCallback(function (anAsyncResult) {
+ SimpleTest.is(anAsyncResult['path1'], 3, "the result of the first path is 3");
+ SimpleTest.is(anAsyncResult['path2'], 2, "the result of the second path is 2");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'collectResults_withArrayListOfCalls_test': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred('collectResults_withArrayListOfCalls_test', someTestArgs);
+ deferredResult.addCallback(Clipperz.Async.collectResults('collectResults_withArrayListOfCalls_test - collectResults', {
+ 'path1': [
+ MochiKit.Base.partial(MochiKit.Async.succeed, {key1:'value1', key2:'value2'}),
+ Clipperz.Base.serializeJSON
+ ],
+ 'path2': [
+ MochiKit.Base.partial(MochiKit.Async.succeed, {key3:'value3', key4:'value4'}),
+ Clipperz.Base.serializeJSON
+ ]
+ }, someTestArgs));
+ deferredResult.addCallback(function (anAsyncResult) {
+ SimpleTest.is(anAsyncResult['path1'], "{\"key1\":\"value1\",\"key2\":\"value2\"}", "the result of the first path is correct");
+ SimpleTest.is(anAsyncResult['path2'], "{\"key3\":\"value3\",\"key4\":\"value4\"}", "the result of the second path is correct");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredSort_test': function (someTestArgs) {
+ var deferredResult;
+ var testArray;
+
+ testArray = [
+ {key:'key2', label:function () { return MochiKit.Async.succeed('label2')} },
+ {key:'key3', label:function () { return MochiKit.Async.succeed('label3')} },
+ {key:'key7', label:function () { return MochiKit.Async.succeed('label7')} },
+ {key:'key1', label:function () { return MochiKit.Async.succeed('label1')} },
+ {key:'key5', label:function () { return MochiKit.Async.succeed('label5')} },
+ {key:'key4', label:function () { return MochiKit.Async.succeed('label4')} },
+ {key:'key9', label:function () { return MochiKit.Async.succeed('label9')} },
+ {key:'key8', label:function () { return MochiKit.Async.succeed('label8')} },
+ {key:'key6', label:function () { return MochiKit.Async.succeed('label6')} }
+ ]
+
+ deferredResult = new Clipperz.Async.Deferred('deferredSort_test', someTestArgs);
+ deferredResult.addCallback(Clipperz.Async.deferredSort, function (aObject, bObject) {
+ var result;
+
+ result = Clipperz.Async.deferredCompare(MochiKit.Base.compare, aObject.label(), bObject.label());
+
+ return result;
+ });
+ deferredResult.addCallback(function (aSortedArray) {
+ SimpleTest.is(aSortedArray.length, testArray.length, "The sorted array should have the same number of objects as the original one");
+ SimpleTest.is(aSortedArray[0]['key'], 'key1', "[0] -> key1");
+ SimpleTest.is(aSortedArray[1]['key'], 'key2', "[1] -> key2");
+ SimpleTest.is(aSortedArray[2]['key'], 'key3', "[2] -> key3");
+ SimpleTest.is(aSortedArray[3]['key'], 'key4', "[3] -> key4");
+ SimpleTest.is(aSortedArray[4]['key'], 'key5', "[4] -> key5");
+ SimpleTest.is(aSortedArray[5]['key'], 'key6', "[5] -> key6");
+ SimpleTest.is(aSortedArray[6]['key'], 'key7', "[6] -> key7");
+ SimpleTest.is(aSortedArray[7]['key'], 'key8', "[7] -> key8");
+ SimpleTest.is(aSortedArray[8]['key'], 'key9', "[8] -> key9");
+ });
+ deferredResult.callback(testArray);
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'callbacks_test': function (someTestArgs) {
+ return Clipperz.Async.callbacks("callbacks_test", [
+ MochiKit.Base.partial(MochiKit.Base.operator.add, 5),
+ Clipperz.Async.Test.is(15, "Clipperz.Async.callbacks seems to work")
+ ], someTestArgs, 10);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredAcquireLockTest': function (someTestArgs) {
+ var deferredLock;
+ var deferredResult;
+ var anotherDeferred;
+ var deferredResults;
+
+ deferredLock = new MochiKit.Async.DeferredLock();
+ deferredResult = new Clipperz.Async.Deferred("acquireLockTest", {trace:false});
+ deferredResult.acquireLock(deferredLock);
+ deferredResult.addCallback(function () {
+ SimpleTest.is(true, deferredLock.locked, 'DeferredLock is locked after Clipperz.Async.Deferred.acquireLock');
+ });
+
+ anotherDeferred = new Clipperz.Async.Deferred("acquireLockLockedTest", {trace:false});
+ anotherDeferred.acquireLock(deferredLock);
+ anotherDeferred.addCallback(function () {
+ SimpleTest.ok(false, 'Did not wait on a locked DeferredLock')
+ });
+ anotherDeferred.addErrback(function (anError) {
+ SimpleTest.ok(true, 'Did wait on a locked DeferredLock');
+ });
+
+ deferredResults = new MochiKit.Async.DeferredList([deferredResult, anotherDeferred], false, false, false);
+ MochiKit.Async.callLater(1, function () {
+ anotherDeferred.cancel();
+ });
+
+ deferredResult.callback();
+ anotherDeferred.callback();
+ return deferredResults;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredLockAcquireTest': function (someTestArgs) {
+ var deferredLock;
+ var defferedResult;
+ var anotherDeferred;
+ var deferredResults;
+
+ deferredLock = new MochiKit.Async.DeferredLock();
+ deferredResult = new Clipperz.Async.Deferred("acquireLockTest", {trace:false});
+ deferredResult.addMethod(deferredLock, 'acquire');
+ deferredResult.addCallback(function () {
+ SimpleTest.is(true, deferredLock.locked, 'DeferredLock is locked after Clipperz.Async.Deferred.acquireLock');
+ });
+
+ anotherDeferred = new Clipperz.Async.Deferred("acquireLockLockedTest", {trace:false});
+ anotherDeferred.addMethod(deferredLock, 'acquire');
+ anotherDeferred.addCallback(function () {
+ SimpleTest.ok(false, 'Did not wait on a locked DeferredLock')
+ });
+ anotherDeferred.addErrback(function (anError) {
+ SimpleTest.ok(true, 'Did wait on a locked DeferredLock');
+ });
+
+
+ deferredResults = new MochiKit.Async.DeferredList([deferredResult, anotherDeferred], false, false, false);
+ MochiKit.Async.callLater(1, function () {
+ anotherDeferred.cancel();
+ });
+
+ deferredResult.callback();
+ anotherDeferred.callback()
+
+ return deferredResults;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredFilter_test': function (someTestArgs) {
+ var deferredResult;
+ var testObjects;
+ var filterRegExp;
+ var deferredFilterFunction;
+
+ testObjects = [
+ {key: '1', label: MochiKit.Base.partial(MochiKit.Async.succeed, 'skip 1') },
+ {key: '2', label: MochiKit.Base.partial(MochiKit.Async.succeed, 'hit 2') },
+ {key: '3', label: MochiKit.Base.partial(MochiKit.Async.succeed, 'skip 3') },
+ {key: '4', label: MochiKit.Base.partial(MochiKit.Async.succeed, 'hit 4') },
+ {key: '5', label: MochiKit.Base.partial(MochiKit.Async.succeed, 'skip 5') },
+ {key: '6', label: MochiKit.Base.partial(MochiKit.Async.succeed, 'skip 6') },
+ {key: '7', label: MochiKit.Base.partial(MochiKit.Async.succeed, 'hit 7') },
+ {key: '8', label: MochiKit.Base.partial(MochiKit.Async.succeed, 'skip 8') },
+ {key: '9', label: MochiKit.Base.partial(MochiKit.Async.succeed, 'skip 9') },
+ {key:'10', label: MochiKit.Base.partial(MochiKit.Async.succeed, 'hit 10') }
+ ]
+
+ filterRegExp = new RegExp("hit", "i");
+
+ deferredFilterFunction = function (aRegExp, anObject) {
+ return Clipperz.Async.callbacks("deferredFilterFunction", [
+ MochiKit.Base.method(anObject, 'label'),
+ MochiKit.Base.method(aRegExp, 'test'),
+ function (doesItMatch) {
+ var result;
+
+ if (doesItMatch) {
+ result = MochiKit.Async.succeed('match');
+ } else {
+ result = MochiKit.Async.fail('miss');
+ }
+
+ return result;
+ }
+ ], someTestArgs);
+ };
+
+ deferredResult = new Clipperz.Async.Deferred("deferredFilter_test", someTestArgs);
+ deferredResult.addCallback(Clipperz.Async.deferredFilter, MochiKit.Base.partial(deferredFilterFunction, filterRegExp), testObjects);
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.is(aResult.length, 4, "There are 4 items matching the 'hit' regexp");
+ SimpleTest.is(aResult[0]['key'], '2', "The first item to match is the one with key:2");
+ SimpleTest.is(aResult[1]['key'], '4', "The first item to match is the one with key:4");
+ SimpleTest.is(aResult[2]['key'], '7', "The first item to match is the one with key:7");
+ SimpleTest.is(aResult[3]['key'], '10', "The first item to match is the one with key:10");
+ })
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredFilter_methodcaller_test': function (someTestArgs) {
+ var deferredResult;
+ var testObjects;
+ var filterRegExp;
+ var deferredFilterFunction;
+
+ testObjects = [
+ new testObject('skip 1'),
+ new testObject('hit 2'),
+ new testObject('skip 3'),
+ new testObject('hit 4'),
+ new testObject('skip 5'),
+ new testObject('skip 6'),
+ new testObject('hit 7'),
+ new testObject('skip 8'),
+ new testObject('skip 9'),
+ new testObject('hit 10')
+ ];
+
+ deferredResult = new Clipperz.Async.Deferred("deferredFilter_methodcaller_test", someTestArgs);
+// deferredResult.addCallback(function () { return testObjects[0]; });
+ deferredResult.addCallback(MochiKit.Async.succeed, testObjects[0]);
+ deferredResult.addCallback(MochiKit.Base.methodcaller('shouldHit'));
+ deferredResult.addTest(false, "the first element shoud return 'false' to the 'shouldHit' method");
+
+ deferredResult.addCallback(MochiKit.Async.succeed, testObjects[1]);
+ deferredResult.addCallback(MochiKit.Base.methodcaller('shouldHit'));
+ deferredResult.addTest(true, "the second element shoud return 'true' to the 'shouldHit' method");
+
+ deferredResult.addCallback(MochiKit.Async.succeed, testObjects);
+ deferredResult.addCallback(Clipperz.Async.deferredFilter, MochiKit.Base.methodcaller('shouldHit'));
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.is(aResult.length, 4, "There are 4 items matching the 'hit' regexp");
+ SimpleTest.is(aResult[0]._label, 'hit 2', "The first item to match is the one with key:2");
+ SimpleTest.is(aResult[1]._label, 'hit 4', "The first item to match is the one with key:4");
+ SimpleTest.is(aResult[2]._label, 'hit 7', "The first item to match is the one with key:7");
+ SimpleTest.is(aResult[3]._label, 'hit 10', "The first item to match is the one with key:10");
+ })
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setItem_test': function (someTestArgs) {
+ var deferredResult;
+ var result;
+
+ result = {};
+ deferredResult = new Clipperz.Async.Deferred("setItem_test", someTestArgs);
+ deferredResult.addCallback(MochiKit.Async.succeed, "Value 1");
+ deferredResult.addCallback(Clipperz.Async.setItem, result, 'key1');
+ deferredResult.addCallback(MochiKit.Async.succeed, "Value 2");
+ deferredResult.addCallback(Clipperz.Async.setItem, result, 'key2');
+
+ deferredResult.addCallback(MochiKit.Base.itemgetter('key1'));
+ deferredResult.addTest("Value 1", "the value for the 'key1' does match");
+
+ deferredResult.addCallback(MochiKit.Async.succeed, result);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('key2'));
+ deferredResult.addTest("Value 2", "the value for the 'key2' does match");
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setItemOnObject_test': function (someTestArgs) {
+ var deferredResult;
+ var result;
+
+ result = {};
+
+ deferredResult = new Clipperz.Async.Deferred("setItemOnObject_test", someTestArgs);
+ deferredResult.addCallback(MochiKit.Async.succeed, result);
+ deferredResult.addCallback(Clipperz.Async.setItemOnObject, 'key1', "Value 1");
+ deferredResult.addCallback(Clipperz.Async.setItemOnObject, 'key2', "Value 2");
+
+ deferredResult.addCallback(MochiKit.Base.itemgetter('key1'));
+ deferredResult.addTest("Value 1", "the value for the 'key1' does match");
+
+ deferredResult.addCallback(MochiKit.Async.succeed, result);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('key2'));
+ deferredResult.addTest("Value 2", "the value for the 'key2' does match");
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setDeferredItemOnObject_test': function (someTestArgs) {
+ var deferredResult;
+ var result;
+
+ result = {};
+
+ deferredResult = new Clipperz.Async.Deferred("setDeferredItemOnObject_test", someTestArgs);
+ deferredResult.addCallback(MochiKit.Async.succeed, result);
+ deferredResult.addCallback(Clipperz.Async.setDeferredItemOnObject, 'key1', MochiKit.Base.partial(MochiKit.Async.succeed, "Value 1"));
+ deferredResult.addCallback(Clipperz.Async.setDeferredItemOnObject, 'key2', MochiKit.Base.partial(MochiKit.Async.succeed, "Value 2"));
+
+ deferredResult.addCallback(MochiKit.Base.itemgetter('key1'));
+ deferredResult.addTest("Value 1", "the value for the 'key1' does match");
+
+ deferredResult.addCallback(MochiKit.Async.succeed, result);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('key2'));
+ deferredResult.addTest("Value 2", "the value for the 'key2' does match");
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addIf_test': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("addIf_test", someTestArgs);
+
+ deferredResult.addCallback(MochiKit.Async.succeed, true);
+ deferredResult.addIf([
+ MochiKit.Base.partial(SimpleTest.ok, true, "when a true value is passed, the 'then' branch is executed")
+ ], [
+ MochiKit.Base.partial(SimpleTest.ok, false, "when a true value is passed, the 'else' branch should NOT be executed")
+ ]);
+
+ deferredResult.addCallback(MochiKit.Async.succeed, false);
+ deferredResult.addIf([
+ MochiKit.Base.partial(SimpleTest.ok, false, "when a false value is passed, the 'then' branch should NOT be executed")
+ ], [
+ MochiKit.Base.partial(SimpleTest.ok, true, "when a false value is passed, the 'else' branch is executed")
+ ]);
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addMethod_test': function (someTestArgs) {
+ var deferredResult;
+ var testObjectInstance;
+ var testObjectInstance_2;
+ var label;
+ var testObjectInstanceGetter;
+
+ label = "Test - Label";
+ testObjectInstance = new testObject(label);
+ testObjectInstance_2 = new testObject(label + label);
+ testObjectInstance.setSibling(testObjectInstance_2);
+
+ testObjectInstanceGetter = function () {
+ return testObjectInstance;
+ }
+
+ deferredResult = new Clipperz.Async.Deferred("addMethod_test", someTestArgs);
+ deferredResult.addMethod(testObjectInstance, 'label');
+ deferredResult.addTest(label, "the addMethod seems to work");
+
+ deferredResult.addMethod(testObjectInstanceGetter(), 'label');
+ deferredResult.addTest(label, "the addMethod seems to work");
+
+ deferredResult.addMethod(testObjectInstance.sibling(), 'label');
+ deferredResult.addTest(label+label, "the addMethod seems to work");
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'callbacksWithErrors_test': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("callbacksWithErrors_test", someTestArgs);
+ deferredResult.addCallback(MochiKit.Base.partial(Clipperz.Async.callbacks, "callbacksWithErrors_test - callbacks", [
+ function () { return 10; },
+ function (aValue) { pippo = pluto + aValue; },
+ function (aValue) { SimpleTest.ok(false, "this code should never be executed"); return aValue; }
+ ], {trace:someTestArgs}));
+ deferredResult.addCallback(SimpleTest.ok, false, "the inner code should raise an exception and exit through the error chain");
+ deferredResult.addErrback(SimpleTest.ok, true, "the inner code should raise an exception and exit through the error chain");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredVars_test': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("deferredVars_test", someTestArgs);
+ deferredResult.addCallback(MochiKit.Async.succeed, "test string");
+ deferredResult.setValue('testKey');
+ deferredResult.addCallback(MochiKit.Async.succeed, "another string");
+ deferredResult.getValue('testKey');
+ deferredResult.addTest("test string", "The right string has been fetched");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+
+
+//#############################################################################
+
+SimpleTest.runDeferredTests("Clipperz.Async", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/Base.html b/frontend/gamma/tests/tests/Clipperz/Base.html
new file mode 100644
index 0000000..6b29417
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Base.html
@@ -0,0 +1,55 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.Base - TEST</title>
+
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.Async.js"></script>
+
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript" src="Base.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Base.test.js b/frontend/gamma/tests/tests/Clipperz/Base.test.js
new file mode 100644
index 0000000..e5c7caf
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Base.test.js
@@ -0,0 +1,367 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+
+//=============================================================================
+
+testEvalJSON = function(aString, shouldFail, aDescription) {
+ var result;
+
+ if (shouldFail == true) {
+ try {
+ result = Clipperz.Base.evalJSON(aString);
+ is(true, false, aDescription + ": vulnerability not caught");
+//console.log(result);
+ } catch(exception) {
+ is(true, true, aDescription + ": vulnerability correctly caught");
+ }
+ } else {
+ try {
+ result = Clipperz.Base.evalJSON(aString);
+ is(true, true, aDescription + ": configuration correctly checked");
+ } catch(exception) {
+ is(true, false, aDescription + ": configuration wrongly caught as malicious");
+// console.log(exception);
+ }
+ }
+
+ return result;
+}
+
+//=============================================================================
+
+var tests = {
+
+ '001_test': function () {
+ var stringToSplit;
+ var splittedString;
+
+ stringToSplit = "stringToSplit";
+ splittedString = Clipperz.Base.splitStringAtFixedTokenSize(stringToSplit, 2);
+ is(splittedString.length, 7);
+ is(splittedString[0], 'st');
+ is(splittedString[1], 'ri');
+ is(splittedString[2], 'ng');
+ is(splittedString[3], 'To');
+ is(splittedString[4], 'Sp');
+ is(splittedString[5], 'li');
+ is(splittedString[6], 't', "test that should pass");
+
+ stringToSplit = "stringToSplit";
+ splittedString = Clipperz.Base.splitStringAtFixedTokenSize(stringToSplit, 20);
+ is(splittedString.length, 1);
+ is(splittedString[0], 'stringToSplit');
+
+ stringToSplit = null;
+ splittedString = Clipperz.Base.splitStringAtFixedTokenSize(stringToSplit, 20);
+ is(splittedString.length, 0);
+ },
+
+ //-------------------------------------------------------------------------
+
+ '002_test': function () {
+ var anObject;
+
+ anObject = "String";
+ is(Clipperz.Base.objectType(anObject), 'string', "test on strings (1)");
+ anObject = new String("String");
+ is(Clipperz.Base.objectType(anObject), 'string', "test on strings (2)");
+
+ anObject = 120;
+ is(Clipperz.Base.objectType(anObject), 'number', "test on numbers (1)");
+ anObject = new Number(120);
+ is(Clipperz.Base.objectType(anObject), 'number', "test on numbers (2)");
+
+ anObject = true;
+ is(Clipperz.Base.objectType(anObject), 'boolean', "test on booleans (1)");
+ anObject = new Boolean(true);
+ is(Clipperz.Base.objectType(anObject), 'boolean', "test on booleans (2)");
+
+ anObject = new Date;
+ is(Clipperz.Base.objectType(anObject), 'date', "test on dates");
+
+ anObject = new Error("test");
+ is(Clipperz.Base.objectType(anObject), 'error', "test on errors");
+
+ anObject = function() {};
+ is(Clipperz.Base.objectType(anObject), 'function', "test on functions");
+
+ anObject = new Object();
+ is(Clipperz.Base.objectType(anObject), 'object', "test on objects");
+
+
+ anObject = [1, 2, 3];
+ is(Clipperz.Base.objectType(anObject), 'array', "test on arrays");
+ },
+
+ //-------------------------------------------------------------------------
+
+ '003_test': function () {
+ var original, clone;
+
+ original = {
+ a: "a",
+ b: "b"
+ };
+
+ clone = Clipperz.Base.deepClone(original);
+ is(MochiKit.Base.compare(original, clone), 0, "simple cloning return two equal objects");
+
+ clone.c = "c";
+ is(MochiKit.Base.compare(original, clone), -1, "changing an object leave the original object unchanged");
+
+ original = {
+ a: "a",
+ b: "b",
+ nested: {
+ a1: "a1",
+ b1: "b1"
+ }
+ };
+
+ clone = Clipperz.Base.deepClone(original);
+ is(MochiKit.Base.compare(original, clone), 0, "cloning of an object with nested values return two equal objects");
+
+ clone.nested.c1 = "c1";
+ is(MochiKit.Base.compare(original, clone), -1, "changing a nested value leave the original object unchanged");
+ },
+
+ //-------------------------------------------------------------------------
+
+ '004_test': function () {
+ var jsonString;
+
+ jsonString = '{"page": {"title": "Example Attack"},"form": { "attributes": { "action": "javascript:opener.document.body.innerHTML = \'hacked!\';close();", "style": "-moz-binding:url(\'http://ha.ckers.org/xssmoz.xml#xss\')", "method": null }, "inputs": [{"type": "text", "name": "username", "value": ""}, {"type": "password", "name": "password", "value": ""}]},"version": "0.2.3" }';
+ testEvalJSON(jsonString, false, "");
+
+ // jsonString = '{"0":{"label":"<script>alert(\"Ciao Marco\")< /script>","key":"ebc9782019bf9aa757e9c4d716ab303e2050b60c4b9a06b18ab09a417e0ddf00"}, "1":{"label":"<iframe><script>alert(\\"Ciao ragazzi\\")< /script></iframe>", "key":"413cfb122a1601c50e0f9462978ba77a36fdcecb49dda7550ee129dc114ba328"}}';
+ jsonString = new Clipperz.ByteArray().appendBase64String("eyIwIjp7ImxhYmVsIjoiPHNjcmlwdD5hbGVydChcIkNpYW8gTWFyY29cIik8L3NjcmlwdD4iLCAia2V5IjoiZWJjOTc4MjAxOWJmOWFhNzU3ZTljNGQ3MTZhYjMwM2UyMDUwYjYwYzRiOWEwNmIxOGFiMDlhNDE3ZTBkZGYwMCJ9LCAiMSI6eyJsYWJlbCI6IjxpZnJhbWU+PHNjcmlwdD5hbGVydChcIkNpYW8gcmFnYXp6aVwiKTwvc2NyaXB0PjwvaWZyYW1lPiIsICJrZXkiOiI0MTNjZmIxMjJhMTYwMWM1MGUwZjk0NjI5NzhiYTc3YTM2ZmRjZWNiNDlkZGE3NTUwZWUxMjlkYzExNGJhMzI4In19").asString();
+ testEvalJSON(jsonString, false);
+
+ jsonString = 'alert("foobar");';
+ testEvalJSON(jsonString, true);
+
+ // jsonString = '<script>alert("foobar");< /script>';
+ jsonString = new Clipperz.ByteArray().appendBase64String("PHNjcmlwdD5hbGVydCgiZm9vYmFyIik7PC9zY3JpcHQ+").asString();
+ testEvalJSON(jsonString, true);
+
+ jsonString = '{"xss": alert("XSS!")}';
+ testEvalJSON(jsonString, true);
+
+ jsonString = '{"inner": {"xss": alert("XSS!")}}';
+ testEvalJSON(jsonString, true);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'Clipperz.Base.itemgetter_test': function () {
+ var anObject;
+
+ anObject = {
+ key1: 'value1',
+ key2: {
+ key2_1: 'value2_1',
+ key2_2: 'value2_2'
+ },
+ key3: {
+ key3_1: {
+ key3_1_1: 'value3_1_1',
+ key3_1_2: 'value3_1_2'
+ },
+ key3_2: {
+ key3_2_1: 'value3_2_1',
+ key3_2_2: 'value3_2_2'
+ }
+ }
+ };
+
+ SimpleTest.is(Clipperz.Base.itemgetter('key1')(anObject), "value1", "Clipperz.Base.itemgetter works as MochiKit.Base.itemgetter");
+ SimpleTest.is(Clipperz.Base.itemgetter('key2.key2_1')(anObject), "value2_1", "Clipperz.Base.itemgetter works also with keypaths");
+ SimpleTest.is(Clipperz.Base.itemgetter('key3.key3_2.key3_2_2')(anObject), "value3_2_2", "Clipperz.Base.itemgetter works also with 'long' keypaths");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'Clipperz.Base.caseInsensitiveCompare_test': function () {
+ var comparator;
+ var objects;
+
+ comparator = Clipperz.Base.caseInsensitiveCompare;
+ objects = [ 'ccc', 'aaa', 'bbb', 'eee', 'ddd'];
+ SimpleTest.isDeeply(['aaa', 'bbb', 'ccc', 'ddd', 'eee'], objects.sort(comparator), "caseInsensitiveCompare works with all lowercase values");
+
+ comparator = MochiKit.Base.compare;
+ objects = [ 'ccc', 'AAA', 'bbb', 'EEE', 'ddd'];
+ SimpleTest.isDeeply(['AAA', 'EEE', 'bbb', 'ccc', 'ddd'], objects.sort(comparator), "caseInsensitiveCompare works with all lowercase values");
+
+ comparator = Clipperz.Base.caseInsensitiveCompare;
+ objects = [ 'ccc', 'AAA', 'bbb', 'EEE', 'ddd'];
+ SimpleTest.isDeeply(['AAA', 'bbb', 'ccc', 'ddd', 'EEE'], objects.sort(comparator), "caseInsensitiveCompare works with all lowercase values");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'Clipperz.Base.reverseComparator_test': function () {
+ var comparator;
+ var objects;
+
+ comparator = MochiKit.Base.compare;
+ objects = [5, 3, 2, 4, 1];
+ SimpleTest.isDeeply([1, 2, 3, 4, 5], objects.sort(comparator), "a regular comparator works fine");
+
+ comparator = Clipperz.Base.reverseComparator(MochiKit.Base.compare);
+ objects = [5, 3, 2, 4, 1];
+ SimpleTest.isDeeply([5, 4, 3, 2 ,1], objects.sort(comparator), "a reversed comparator works fine");
+
+ comparator = MochiKit.Base.keyComparator('label');
+ objects = [ {label:"5"}, {label:"3"}, {label:"1"}, {label:"4"}, {label:"2"}];
+ SimpleTest.isDeeply([ {label:"1"}, {label:"2"}, {label:"3"}, {label:"4"}, {label:"5"}], objects.sort(comparator), "a regular keyComparator works fine");
+
+ comparator = Clipperz.Base.reverseComparator(MochiKit.Base.keyComparator('label'));
+ objects = [ {label:"5"}, {label:"3"}, {label:"1"}, {label:"4"}, {label:"2"}];
+ SimpleTest.isDeeply([ {label:"5"}, {label:"4"}, {label:"3"}, {label:"2"}, {label:"1"}], objects.sort(comparator), "a reversed keyComparator works fine");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'Clipperz.Base.map_test': function () {
+ var objects;
+ var computedObjecs;
+
+ objects = [5, 3, 2, 4, 1];
+ computedObjecs = Clipperz.Base.map(function (aValue) { return aValue * 2;}, objects);
+ SimpleTest.isDeeply(computedObjecs, [10, 6, 4, 8, 2], "the mapped values of the array do match");
+
+ objects = {
+ 'five': 5,
+ 'three': 3,
+ 'two': 2,
+ 'four': 4,
+ 'one': 1
+ };
+ computedObjecs = Clipperz.Base.map(function (aValue) { return aValue * 2;}, objects);
+ SimpleTest.isDeeply(computedObjecs, {
+ 'five': 10,
+ 'three': 6,
+ 'two': 4,
+ 'four': 8,
+ 'one': 2
+ }, "the mapped values of the object do match");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'Clipperz.Base.isUrl_test': function () {
+ var urlTestCases;
+
+ urlTestCases = [
+ {url:'http://foo.com/blah_blah', expectedResult:true},
+ {url:'http://foo.com/blah_blah', expectedResult:true},
+ {url:'http://foo.com/blah_blah/', expectedResult:true},
+ {url:'http://foo.com/blah_blah_(wikipedia)', expectedResult:true},
+ {url:'http://foo.com/blah_blah.', expectedResult:true},
+ {url:'http://foo.com/blah_blah/.', expectedResult:true},
+ {url:'http://foo.com/blah_blah,', expectedResult:true},
+ {url:'http://✪df.ws/123', expectedResult:true},
+ {url:'http://➡.ws/䨹', expectedResult:true},
+ {url:'www.➡.ws/䨹', expectedResult:true},
+ {url:'http://www.example.com/wpstyle/?p=364.', expectedResult:true},
+ {url:'www.clipperz.com', expectedResult:true},
+ {url:'http://www.clipperz.com', expectedResult:true},
+ {url:'http://clipperz.com', expectedResult:true},
+
+ {url:'clipperz.com', expectedResult:false},
+// {url:'www.clipperz', expectedResult:false},
+// {url:'www.abc', expectedResult:false},
+ {url:'joe@clipperz.com', expectedResult:false},
+ {url:'<http://foo.com/blah_blah>', expectedResult:false},
+ {url:'<http://foo.com/blah_blah/>', expectedResult:false},
+ {}
+ ];
+
+ MochiKit.Base.map(function (someValues) {
+ if (typeof(someValues['url']) != 'undefined') {
+ SimpleTest.is(Clipperz.Base.isUrl(someValues['url']), someValues['expectedResult'], "testing url '" + someValues['url'] + "' - expected result: " + someValues['expectedResult']);
+ }
+ }, urlTestCases);
+
+/*
+ // RegExp and test strings courtesy of John Gruber: http://daringfireball.net/2009/11/liberal_regex_for_matching_urls
+ SimpleTest.is(Clipperz.Base.isUrl('http://foo.com/blah_blah'), true, "url test +1");
+ SimpleTest.is(Clipperz.Base.isUrl('http://foo.com/blah_blah/'), true, "url test +2");
+ SimpleTest.is(Clipperz.Base.isUrl('http://foo.com/blah_blah_(wikipedia)'), true, "url test +3");
+ SimpleTest.is(Clipperz.Base.isUrl('http://foo.com/blah_blah.'), true, "url test +4");
+ SimpleTest.is(Clipperz.Base.isUrl('http://foo.com/blah_blah/.'), true, "url test +5");
+ SimpleTest.is(Clipperz.Base.isUrl('<http://foo.com/blah_blah>'), true, "url test +6");
+ SimpleTest.is(Clipperz.Base.isUrl('<http://foo.com/blah_blah/>'), true, "url test +7");
+ SimpleTest.is(Clipperz.Base.isUrl('http://foo.com/blah_blah,'), true, "url test +8");
+ SimpleTest.is(Clipperz.Base.isUrl('http://✪df.ws/123'), true, "url test +9");
+ SimpleTest.is(Clipperz.Base.isUrl('http://➡.ws/䨹'), true, "url test +10");
+ SimpleTest.is(Clipperz.Base.isUrl('www.➡.ws/䨹'), true, "url test +11");
+ SimpleTest.is(Clipperz.Base.isUrl('http://www.example.com/wpstyle/?p=364.'),true, "url test +12");
+ SimpleTest.is(Clipperz.Base.isUrl('www.clipperz.com'), true, "url test +13");
+ SimpleTest.is(Clipperz.Base.isUrl('http://www.clipperz.com'), true, "url test +14");
+
+// SimpleTest.is(Clipperz.Base.isUrl('http://userid@example.com'), true, "url test +13"); // FAIL
+// SimpleTest.is(Clipperz.Base.isUrl('http://userid@example.com:8080'), true, "url test +14"); // FAIL
+// SimpleTest.is(Clipperz.Base.isUrl('http://userid:password@example.com'), true, "url test +15"); // FAIL
+// SimpleTest.is(Clipperz.Base.isUrl('http://userid:password@example.com:8080'), true, "url test +16"); // FAIL
+
+
+ SimpleTest.is(Clipperz.Base.isUrl('joe@clipperz.com'), false, "url test -1");
+ SimpleTest.is(Clipperz.Base.isUrl('rdar://1234'), false, "url test -2");
+ SimpleTest.is(Clipperz.Base.isUrl('rdar:/1234'), false, "url test -3");
+ SimpleTest.is(Clipperz.Base.isUrl('http://example.com:8080 x-yojimbo-item://6303E4C1-xxxx-45A6-AB9D-3A908F59AE0E'), false, "url test -4");
+ SimpleTest.is(Clipperz.Base.isUrl('message://%3c330e7f8409726r6a4ba78dkf1fd71420c1bf6ff@mail.gmail.com%3e'), false, "url test -5");
+*/
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'Clipperz.Base.isEmail_test': function () {
+ var emailTestCases;
+
+ emailTestCases = [
+ {email:'joe@clipperz.com', expectedResult:true},
+
+ {email:'http://foo.com/blah_blah', expectedResult:false}
+ ];
+
+ MochiKit.Base.map(function (someValues) {
+ SimpleTest.is(Clipperz.Base.isEmail(someValues['email']), someValues['expectedResult'], "testing email '" + someValues['email'] + "' - expected result: " + someValues['expectedResult']);
+ }, emailTestCases);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'syntaxFix': MochiKit.Base.noop
+}
+
+//=============================================================================
+
+SimpleTest.runDeferredTests("Clipperz.Base", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/ByteArray.html b/frontend/gamma/tests/tests/Clipperz/ByteArray.html
new file mode 100644
index 0000000..c8b8ae7
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/ByteArray.html
@@ -0,0 +1,71 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.ByteArray - tests</title>
+
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <!-- script type='text/javascript' src='../../../js/Clipperz/Crypto/BigInt.js'></script -->
+
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.Async.js"></script>
+
+</head>
+<body>
+
+<pre id="test">
+<script>
+ Clipperz_IEisBroken = false;
+</script>
+ <script type="text/javascript">
+ var longAsciiText = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam ac ipsum. Morbi mauris. Aenean ac elit id metus lobortis elementum. Proin at quam ac ipsum pellentesque adipiscing. Aenean vestibulum, nisl eu suscipit iaculis, quam pede congue mi, sit amet dapibus metus neque eget dui. Suspendisse posuere diam ac sapien. Nulla lobortis dapibus leo. Quisque ornare tortor quis turpis. Aliquam erat volutpat. Ut faucibus lacinia magna. Nunc metus leo, volutpat quis, mollis ac, sagittis ut, turpis. Quisque purus. Mauris ante enim, vehicula eu, suscipit vitae, laoreet vel, nulla. Pellentesque pede leo, aliquam quis, vehicula eget, rhoncus nec, metus. Vestibulum tellus. Suspendisse blandit. Pellentesque vel tellus. Maecenas arcu. Duis eget purus. Curabitur non pede nec odio cursus luctus. In non elit. Nullam eget nunc in nisl elementum commodo. Vivamus sollicitudin pede quis dui. Morbi commodo. Praesent a risus id urna hendrerit fermentum. Nunc ultricies tristique odio. Phasellus imperdiet, sapien eget viverra blandit, tortor risus blandit nisi, et sodales libero dolor quis nisl. Morbi vel enim. Nunc in quam. Vestibulum a magna. Fusce auctor elit in augue. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris tincidunt consectetuer leo. Etiam non turpis. Vestibulum eros. Praesent venenatis adipiscing augue. Pellentesque dapibus odio ac arcu rhoncus sagittis. Nullam vitae augue. Ut magna nulla, congue eu, porta in, egestas quis, ligula. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur malesuada neque non nulla. Nulla facilisi. Fusce viverra magna ut tellus. Sed rutrum pretium sapien. Vivamus dui. Cras fringilla. Nullam lorem. Vestibulum varius, purus at imperdiet fermentum, metus diam ultricies lacus, vitae aliquam ipsum libero sit amet felis. Sed eget eros ac velit commodo sollicitudin. Morbi in metus in mi viverra lacinia. Sed ut urna. Suspendisse imperdiet tellus ac velit. Duis malesuada velit sit amet sapien. Vestibulum a sapien id libero accumsan luctus. Fusce iaculis. Donec pulvinar orci ut pede. Nam placerat sem ut sem. Ut pretium bibendum nisl. Suspendisse potenti. Phasellus mollis neque in neque. Suspendisse augue magna, eleifend et, malesuada at, viverra in, nisl. Donec vel lectus in justo ultrices tristique. Aliquam erat volutpat. Morbi suscipit, risus ac volutpat mollis, risus metus hendrerit sapien, ac scelerisque est orci eu est. Quisque sit amet velit. Sed libero diam, semper id, eleifend ac, iaculis non, nulla. Donec varius tincidunt arcu. Sed quis metus eu erat adipiscing viverra. Donec odio. Aenean sagittis nisl sed purus. Fusce vel nibh quis felis accumsan bibendum. Etiam et risus ac tortor cursus pharetra. Maecenas tellus. Pellentesque nec felis id eros vehicula commodo. Aliquam interdum sagittis odio. Maecenas at lorem eget mi aliquet sagittis. Mauris quis nibh in odio sodales lacinia. Proin augue mauris, placerat a, blandit vel, tincidunt eget, ante. Quisque turpis purus, placerat eget, tempor consectetuer, aliquet ac, enim. Etiam eleifend vestibulum mi. Vivamus gravida. Morbi dolor. In hac habitasse platea dictumst. Nulla commodo lectus faucibus lorem. Phasellus aliquet pede id metus hendrerit tempus. Fusce convallis pede ac neque tempor dignissim. Sed vitae lorem sit amet justo dapibus porta. Ut quam orci, pretium non, sagittis nec, condimentum id, dolor. Sed tempor. Nunc porta rutrum leo. Nunc id sem. Sed nibh tortor, dapibus eget, feugiat a, pretium pretium, purus. Suspendisse suscipit lobortis sem. Praesent pharetra orci. Quisque molestie tristique quam. Maecenas nunc lorem, rhoncus non, venenatis sed, sodales at, felis. Quisque semper. Quisque malesuada est quis lacus. Nullam a justo. Aliquam pellentesque, ante ut congue molestie, nisl sapien posuere nisl, eu cursus nulla ligula vel nisl. Fusce commodo lacinia magna. Aenean rutrum vestibulum lorem. Pellentesque fermentum tristique ipsum. Nulla facilisi. Donec id mi eget ipsum commodo egestas. Mauris iaculis. Nulla vulputate mi at nisl. In condimentum sodales tellus. Donec metus orci, mollis vel, accumsan ac, ornare ac, lacus. Pellentesque accumsan est et tellus. Nam mollis. Aenean accumsan eros sit amet tellus. Praesent eu libero. Sed tempus urna nec dolor. Nulla facilisi. Duis eleifend rhoncus neque. Curabitur consectetuer quam eu justo. Sed metus. Vivamus risus. Aliquam erat volutpat. Aliquam erat volutpat. Nunc semper urna. Praesent molestie libero a lacus. Nullam suscipit lobortis velit. Praesent rhoncus, felis ut interdum dapibus, ipsum lectus vestibulum nulla, in interdum risus dolor eget orci. Nullam venenatis. Suspendisse laoreet, arcu a luctus consectetuer, libero ligula condimentum quam, eget elementum mauris tortor sed enim. Pellentesque leo. Nam interdum malesuada ante. Praesent fermentum nunc et dolor. Donec auctor volutpat odio. Pellentesque volutpat egestas ipsum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ac ligula eu justo dignissim accumsan. Nullam nisi. Fusce id sem. Fusce et urna. Pellentesque commodo pharetra lorem. Donec erat. Vestibulum elit arcu, commodo et, consequat eget, posuere eget, sem. Morbi sed nulla sed neque commodo commodo. Aliquam erat volutpat. Ut id turpis a enim malesuada vestibulum. In arcu dui, dignissim vitae, blandit eu, egestas ac, arcu. In ultricies sapien vitae nisi. Proin rhoncus magna eget tortor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In dictum. Sed volutpat pharetra quam. Mauris eget eros. Fusce malesuada dolor id pede. Praesent nec justo sed nisi vehicula varius. In scelerisque convallis nulla. Pellentesque sodales massa vulputate urna. Duis metus urna, imperdiet ac, sodales vel, ullamcorper sed, pede. Vestibulum aliquam mollis metus. Praesent tempus tristique elit. Maecenas tellus tortor, pretium id, mollis id, molestie non, turpis. Vivamus nibh magna, bibendum vitae, a.";
+ var longIsoLatin1Text = "¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùù";
+ var longUtf8Text = "客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之";
+ </script>
+ <script type="text/javascript" src="ByteArray.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/ByteArray.test.js b/frontend/gamma/tests/tests/Clipperz/ByteArray.test.js
new file mode 100644
index 0000000..ef2660e
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/ByteArray.test.js
@@ -0,0 +1,893 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+
+ 'core_tests': function (someTestArgs) {
+// var deferredResult;
+
+// deferredResult = new Clipperz.Async.Deferred("core_tests", someTestArgs);
+// deferredResult.addCallback(function() {
+ var byteArray;
+
+ byteArray = new Clipperz.ByteArray();
+
+ try {
+ byteArray.checkByteValue(512);
+ is(false, true, "a value greater that a byte (0x200) should have raised an exception - NO Exception");
+ } catch(e) {
+// is( e.name,
+// "Clipperz.ByteArray.exception.InvalidValue",
+// "appending a value greater that a byte (0x200) should have raised an exception - EXCEPTION HANDLER")
+ ok( /Clipperz\.ByteArray\.exception\.InvalidValue.*/.test(e.name),
+ "appending a value greater that a byte (0x200) should have raised an exception - EXCEPTION HANDLER")
+ };
+
+// });
+// deferredResult.callback();
+
+// return deferredResult;
+
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'basic_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("simple_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray;
+ var byteArray2;
+ var byteArrayIterator;
+ var nextBlock;
+
+ byteArray = new Clipperz.ByteArray();
+ is(byteArray.length(), 0, "before adding any element the length is 0");
+ byteArray.appendByte(10);
+ is(byteArray.length(), 1, "adding a single byte the length == 1");
+ is(byteArray.byteAtIndex(0), 10, "the first element is correct");
+
+ byteArrayIterator = new Clipperz.ByteArrayIterator({byteArray:byteArray, blockSize:(8/8), finalPadding:true});
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock.constructor, Array, "ByteArrayIterator.nextBlock returns an array of byte values");
+ is(nextBlock.length, 1, "as the block size is 8bit, the returned array has only one element");
+ is(nextBlock[0], 10, "the element of the returned block is correct");
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock, null, "after the last element, the nextBlock returns null");
+
+ byteArray = new Clipperz.ByteArray();
+ byteArray.appendBytes(10, 20, 45, 38);
+ is(byteArray.length(), 4, "Appending more bytes, returns the right length");
+ is(byteArray.byteAtIndex(0), 10, "and all the elements are right [0]");
+ is(byteArray.byteAtIndex(1), 20, "and all the elements are right [1]");
+ is(byteArray.byteAtIndex(2), 45, "and all the elements are right [2]");
+ is(byteArray.byteAtIndex(3), 38, "and all the elements are right [3]");
+
+ byteArray2 = new Clipperz.ByteArray();
+ byteArray2.appendBytes([10, 20, 45, 38]);
+ is(byteArray.equals(byteArray2), true, "equals method tested with a byteArray created with the same values");
+
+ byteArray2 = new Clipperz.ByteArray();
+ byteArray2.appendBytes([20, 11, 3, 22]);
+ is(byteArray.equals(byteArray2), false, "equals method tested with a byteArray created with different values");
+
+ byteArrayIterator = new Clipperz.ByteArrayIterator({byteArray:byteArray, blockSize:(8/8), finalPadding:true});
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock.length, 1, "the size of the block returned by the byteArrayIterator match with the configured blockedSize");
+ is(nextBlock[0], 10, "the values returned by nextBlock are right [1]");
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock[0], 20, "the values returned by nextBlock are right [2]");
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock[0], 45, "the values returned by nextBlock are right [3]");
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock[0], 38, "the values returned by nextBlock are right [4]");
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock, null, "after the last block the nextBlock method returns null");
+
+ byteArrayIterator = new Clipperz.ByteArrayIterator({byteArray:byteArray, blockSize:(16/8), finalPadding:true});
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock.length, 2, "on the same data, using a different block size, returns the right length");
+ is(nextBlock[0], 10, "and also the data are fine [1][0]");
+ is(nextBlock[1], 20, "and also the data are fine [1][1]");
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock.length, 2, "also the second block size is right");
+ is(nextBlock[0], 45, "and also the data are fine [2][0]");
+ is(nextBlock[1], 38, "and also the data are fine [2][1]");
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock, null, "even with a bigger blockSize, at the end the returned value is null");
+
+ byteArray = new Clipperz.ByteArray(11,22,33,44,55,66,77,88,99);
+ is(byteArray.length(), 9, "");
+ byteArrayIterator = new Clipperz.ByteArrayIterator({byteArray:byteArray, blockSize:(16/8), finalPadding:true});
+ nextBlock = byteArrayIterator.nextBlock();
+ nextBlock = byteArrayIterator.nextBlock();
+ nextBlock = byteArrayIterator.nextBlock();
+ nextBlock = byteArrayIterator.nextBlock();
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock.length, 2, "the last block of an odd byte array has always the same size");
+ is(nextBlock[0], 99, "the last element is returned");
+ is(nextBlock[1], 0, "and a 0 is return for the extra values");
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock, null, "even with odd blockSize, after returning all the values, null is returned");
+
+ byteArrayIterator = new Clipperz.ByteArrayIterator({byteArray:byteArray, blockSize:(32/8), finalPadding:true});
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock[0], 11, "32 bit blockSize [1][0]");
+ is(nextBlock[1], 22, "32 bit blockSize [1][1]");
+ is(nextBlock[2], 33, "32 bit blockSize [1][2]");
+ is(nextBlock[3], 44, "32 bit blockSize [1][3]");
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock[0], 55, "32 bit blockSize [2][0]");
+ is(nextBlock[1], 66, "32 bit blockSize [2][1]");
+ is(nextBlock[2], 77, "32 bit blockSize [2][2]");
+ is(nextBlock[3], 88, "32 bit blockSize [2][3]");
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock.length, 4, "the last block of an odd byte array has always the same size");
+ is(nextBlock[0], 99, "the last element is returned (2)");
+ is(nextBlock[1], 0, "and a 0 is return for the extra values (2.1)");
+ is(nextBlock[2], 0, "and a 0 is return for the extra values (2.2)");
+ is(nextBlock[3], 0, "and a 0 is return for the extra values (2.3)");
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock, null, "even with odd blockSize, after returning all the values, null is returned (2)");
+
+ byteArray = new Clipperz.ByteArray([11,22,33,44,55,66,77,88,99,100, 111, 122, 133, 144, 155, 166, 177]);
+ byteArrayIterator = new Clipperz.ByteArrayIterator({byteArray:byteArray, blockSize:(128/8), finalPadding:true});
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock.length, 16, "using a blockSize of 128 bit, the nextBlock return a 16 elements array");
+
+ byteArray = new Clipperz.ByteArray();
+ try {
+ byteArray.appendByte(512);
+ is(false, true, "appending a value greater that a byte (0x200) should have raised an exception - NO Exception");
+ } catch(e) {
+// is( e.name,
+// "Clipperz.ByteArray.exception.InvalidValue",
+// "appending a value greater that a byte (0x200) should have raised an exception - EXCEPTION HANDLER")
+ ok( /Clipperz\.ByteArray\.exception\.InvalidValue.*/.test(e.name),
+ "appending a value greater that a byte (0x200) should have raised an exception - EXCEPTION HANDLER")
+ };
+
+ try {
+ byteArray.appendByte(256);
+ is(false, true, "appending a value greater that a byte (0x100) should have raised an exception - NO Exception");
+ } catch(e) {
+// is( e.name,
+// "Clipperz.ByteArray.exception.InvalidValue",
+// "appending a value greater that a byte (0x100) should have raised an exception - EXCEPTION HANDLER")
+ ok( /Clipperz\.ByteArray\.exception\.InvalidValue.*/.test(e.name),
+ "appending a value greater that a byte (0x100) should have raised an exception - EXCEPTION HANDLER")
+ };
+
+ byteArray.appendByte(255);
+ is(byteArray.length(), 1, "appending a value that feets a single byte does not raise any exception");
+
+ byteArray = new Clipperz.ByteArray(10, 20, 30, 40, 50);
+ byteArray2 = new Clipperz.ByteArray("0x0a141e2832");
+ is(byteArray.equals(byteArray2), true, "the hex constructor works fine");
+
+ byteArray2 = byteArray.clone();
+ is(byteArray.equals(byteArray2), true, "the clone method works fine");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'compare_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("compare_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray1;
+ var byteArray2;
+ var result;
+
+ byteArray1 = new Clipperz.ByteArray("0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ byteArray2 = new Clipperz.ByteArray("0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ result = byteArray1.compare(byteArray2);
+ is(result, 0, "equal compare");
+
+ byteArray1 = new Clipperz.ByteArray("0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ byteArray2 = new Clipperz.ByteArray("0x05", 16);
+ result = byteArray1.compare(byteArray2);
+ is(result, 1, "'OxXXXXXXX'.compare('0x05')");
+ result = byteArray2.compare(byteArray1);
+ is(result, -1, "'0x05'.compare('OxXXXXXXX')");
+
+ byteArray1 = new Clipperz.ByteArray("0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ byteArray2 = new Clipperz.ByteArray("0xff", 16);
+ result = byteArray1.compare(byteArray2);
+ is(result, 1, "'OxXXXXXXX'.compare('0xff')");
+ result = byteArray2.compare(byteArray1);
+ is(result, -1, "'0xff'.compare('OxXXXXXXX')");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'shiftLeft_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("shiftLeft_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'nextBlockArray_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("nextBlockArray_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray;
+ var byteArrayIterator;
+ var nextBlock;
+
+ byteArray = new Clipperz.ByteArray("0x8cf53d90077df9a043bf8d10b470b144784411c93a4d504556834dae3ea4a5bb");
+ byteArrayIterator = new Clipperz.ByteArrayIterator({byteArray:byteArray, blockSize:(128/8), finalPadding:false});
+ nextBlock = byteArrayIterator.nextBlockArray();
+ is(nextBlock.toHexString(), "0x8cf53d90077df9a043bf8d10b470b144", "nextBlockArray first iteration");
+ nextBlock = byteArrayIterator.nextBlockArray();
+ is(nextBlock.toHexString(), "0x784411c93a4d504556834dae3ea4a5bb", "nextBlockArray second iteration");
+
+ byteArray = new Clipperz.ByteArray("0x8cf53d90077df9a043bf8d10b470b144784411c93a4d504556834dae3ea4a5bb");
+ byteArrayIterator = new Clipperz.ByteArrayIterator({byteArray:byteArray, blockSize:(128/8), finalPadding:false});
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock.length, 16, "nextBlock first iteration length");
+ nextBlock = byteArrayIterator.nextBlock();
+ is(nextBlock.length, 16, "nextBlock second iteration length");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'xor_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("xor_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray;
+ var byteArray2;
+
+ byteArray = new Clipperz.ByteArray("0x55555555555555555555555555555555");
+ byteArray2 = new Clipperz.ByteArray("0x00ff000000ff000000ff000000ff0000");
+ is(byteArray.xorMergeWithBlock(byteArray2).toHexString(), "0x55aa555555aa555555aa555555aa5555", "the xorMergeWithBlock method works fine");
+
+ byteArray = new Clipperz.ByteArray("0x555555555555555555");
+ byteArray2 = new Clipperz.ByteArray("0x00ff000000ff000000ff000000ff0000");
+ is(byteArray.xorMergeWithBlock(byteArray2, 'left', 'truncate').toHexString(), "0x55aa555555aa555555", "the xorMergeWithBlock (left, truncate) method works fine");
+
+ byteArray = new Clipperz.ByteArray("0x555555555555555555");
+ byteArray2 = new Clipperz.ByteArray("0x00ff000000ff000000ff000000ff0000");
+ is(byteArray.xorMergeWithBlock(byteArray2, 'right', 'truncate').toHexString(), "0x5555aa555555aa5555", "the xorMergeWithBlock (right, truncate) method works fine");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'increment_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("increment_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray;
+ var number;
+ var i,c;
+
+ number = new Clipperz.Crypto.BigInt("55555555555555555555555555555555", 16);
+ byteArray = new Clipperz.ByteArray("0x" + number.asString(16));
+ c = 2048;
+ for (i=0; i<c; i++) {
+ byteArray.increment();
+ }
+ is(byteArray.toHexString(), "0x" + number.add(2048).asString(16), "Clipperz.ByteArray.increment works");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'split_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("split_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray;
+
+ byteArray = new Clipperz.ByteArray("0xa1b2c3d4");
+ is(byteArray.split(0, 2).toHexString(), "0xa1b2", "byteArray.split(0,2) works fine");
+ is(byteArray.split(2).toHexString(), "0xc3d4", "byteArray.split(2) works fine");
+ is(byteArray.split(1, 3).toHexString(), "0xb2c3", "byteArray.split(1,3) works fine");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'appendBlock_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("appendBlock_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray;
+ var byteArray2;
+
+ byteArray = new Clipperz.ByteArray("0xa1b2c3d4");
+ byteArray2 = new Clipperz.ByteArray("0x1a2b3c4d");
+ is(byteArray.appendBlock(byteArray2).toHexString(), "0xa1b2c3d41a2b3c4d", "the appendBlock method works fine");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'appendWords_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("appendWords_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray;
+
+ byteArray = new Clipperz.ByteArray();
+ byteArray.appendWords(0xa1b2c4d4, 0x1a2b3c4d);
+ is(byteArray.toHexString(), "0xa1b2c4d41a2b3c4d", "test appendWords");
+
+ byteArray = new Clipperz.ByteArray();
+ byteArray.appendBigEndianWords(0xa1b2c4d4, 0x1a2b3c4d);
+ is(byteArray.toHexString(), "0xd4c4b2a14d3c2b1a", "test appendBigEndianWords");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'setByteAtIndex_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("setByteAtIndex_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray;
+
+ byteArray = new Clipperz.ByteArray("0xa1b2c3d4e5f6");
+ byteArray.setByteAtIndex(10, 0);
+ is(byteArray.toHexString(), "0x0ab2c3d4e5f6", "setByteAtIndex( , 0) works fine");
+
+ byteArray.setByteAtIndex(10, 5);
+ is(byteArray.toHexString(), "0x0ab2c3d4e50a", "setByteAtIndex( , 5) works fine");
+
+ byteArray.setByteAtIndex(10, 6);
+ is(byteArray.toHexString(), "0x0ab2c3d4e50a0a", "setByteAtIndex( , 6) works fine");
+
+ byteArray.setByteAtIndex(10, 10);
+ is(byteArray.toHexString(), "0x0ab2c3d4e50a0a0000000a", "setByteAtIndex( , 10) works fine");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'string_encoding_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("string_encoding_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ is(Clipperz.ByteArray.unicodeToUtf8HexString(40), "28", "String encoding - One byte character - middle");
+ is(Clipperz.ByteArray.unicodeToUtf8HexString(127), "7f", "String encoding - One byte character - top");
+
+ is(Clipperz.ByteArray.unicodeToUtf8HexString(128), "c280", "String encoding - Two bytes character - bottom");
+ is(Clipperz.ByteArray.unicodeToUtf8HexString(300), "c4ac", "String encoding - Two bytes character - middle");
+ is(Clipperz.ByteArray.unicodeToUtf8HexString(2047), "dfbf", "String encoding - Two bytes character - top");
+
+ is(Clipperz.ByteArray.unicodeToUtf8HexString(2048), "e0a080", "String encoding - Three bytes character - bottom");
+ is(Clipperz.ByteArray.unicodeToUtf8HexString(8192), "e28080", "String encoding - Three bytes character - middle");
+ is(Clipperz.ByteArray.unicodeToUtf8HexString(65535), "efbfbf", "String encoding - Three bytes character - top");
+
+ is(Clipperz.ByteArray.unicodeToUtf8HexString(65536), "f0908080", "String encoding - Four bytes character - bottom");
+ is(Clipperz.ByteArray.unicodeToUtf8HexString(1000000), "f3b48980", "String encoding - Four bytes character - middle");
+ is(Clipperz.ByteArray.unicodeToUtf8HexString(2097151), "f7bfbfbf", "String encoding - Four bytes character - top");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'string_decoding_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("string_decoding_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray;
+ var byteArray2;
+ var unicodeString;
+
+ is(new Clipperz.ByteArray("0x28").asString().charCodeAt(0), 40, "String decoding - One byte character - middle");
+ is(new Clipperz.ByteArray("0x7f").asString().charCodeAt(0), 127, "String decoding - One byte character - top");
+
+ is(new Clipperz.ByteArray("0xc280").asString().charCodeAt(0), 128, "String decoding - Two bytes character - bottom");
+ is(new Clipperz.ByteArray("0xc4ac").asString().charCodeAt(0), 300, "String decoding - Two bytes character - middle");
+ is(new Clipperz.ByteArray("0xceb1").asString().charCodeAt(0), 945, "String decoding - Two bytes char: greek lowercase alpha - α");
+ is(new Clipperz.ByteArray("0xd790").asString().charCodeAt(0), 1488, "String decoding - Two bytes char: hebrew Aleph - א");
+ is(new Clipperz.ByteArray("0xdfbf").asString().charCodeAt(0), 2047, "String decoding - Two bytes character - top");
+
+ is(new Clipperz.ByteArray("0xe0a080").asString().charCodeAt(0), 2048, "String decoding - Three bytes character - bottom");
+ is(new Clipperz.ByteArray("0xe0bc80").asString().charCodeAt(0), 3840, "String decoding - Three bytes char: tibetan syllable Om - ༀ");
+ is(new Clipperz.ByteArray("0xe28080").asString().charCodeAt(0), 8192, "String decoding - Three bytes character - middle");
+ is(new Clipperz.ByteArray("0xe4b899").asString().charCodeAt(0), 19993, "String decoding - Three bytes char: CJK ideograph - 丙");
+ is(new Clipperz.ByteArray("0xefbfbf").asString().charCodeAt(0), 65535, "String decoding - Three bytes character - top");
+
+/*
+ is(new Clipperz.ByteArray("0xf0908080").asString().charCodeAt(0), 65536, "String decoding - Four bytes character - bottom");
+ is(new Clipperz.ByteArray("0xf0a08294").asString().charCodeAt(0), 131220, "String decoding - Four bytes char: CJK extended ideograph - ”");
+ is(new Clipperz.ByteArray("0xf3b48980").asString().charCodeAt(0), 1000000, "String decoding - Four bytes character - middle");
+ is(new Clipperz.ByteArray("0xf7bfbfbf").asString().charCodeAt(0), 2097151, "String decoding - Four bytes character - top");
+
+ is(String.fromCharCode(65535).charCodeAt(0), 65535, "test fromCharCode - charCodeAt (65535)");
+ is(String.fromCharCode(65536).charCodeAt(0), 65536, "test fromCharCode - charCodeAt (65536)");
+ is(String.fromCharCode(1000000).charCodeAt(0), 1000000, "test fromCharCode - charCodeAt (1000000)");
+*/
+ //----------------------------------------------------------
+
+ byteArray = new Clipperz.ByteArray("ABCD");
+ byteArray2 = new Clipperz.ByteArray("0x41424344");
+ is(byteArray.toHexString(), byteArray2.toHexString(), "the string constructor works fine (1 byte codes)");
+
+ unicodeString = "una stringa un po' piu' semplice";
+ byteArray = new Clipperz.ByteArray(unicodeString);
+ is(byteArray.asString(), unicodeString, "");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'base64_encoding_decoding_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("base64_encoding_decoding_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray;
+
+ byteArray = new Clipperz.ByteArray("\n");
+ is(byteArray.toBase64String(), "Cg==", "base64 encoding test (1)");
+
+ byteArray = new Clipperz.ByteArray("what");
+ is(byteArray.toBase64String(), "d2hhdA==", "base64 encoding test (2)");
+
+ byteArray = new Clipperz.ByteArray("what will print out");
+ is(byteArray.toBase64String(), "d2hhdCB3aWxsIHByaW50IG91dA==", "base64 encoding test (3)");
+
+ byteArray = new Clipperz.ByteArray("what will print out ");
+ is(byteArray.toBase64String(), "d2hhdCAgd2lsbCAgIHByaW50ICAgICBvdXQgICAgICA=", "base64 encoding test (4)");
+
+ byteArray = new Clipperz.ByteArray("what will print out");
+ is(byteArray.toBase64String(), "d2hhdCAgd2lsbCAgIHByaW50ICAgICBvdXQ=", "base64 encoding test (5)");
+
+ byteArray = new Clipperz.ByteArray().appendBase64String("Cg==");
+ is(byteArray.asString(), "\n", "base64 encoding test (1)");
+
+ byteArray = new Clipperz.ByteArray().appendBase64String("d2hhdA==");
+ is(byteArray.asString(), "what", "base64 encoding test (2)");
+
+ byteArray = new Clipperz.ByteArray().appendBase64String("d2hhdCB3aWxsIHByaW50IG91dA==");
+ is(byteArray.asString(), "what will print out", "base64 encoding test (3)");
+
+ byteArray = new Clipperz.ByteArray().appendBase64String("d2hhdCAgd2lsbCAgIHByaW50ICAgICBvdXQgICAgICA=");
+ is(byteArray.asString(), "what will print out ", "base64 encoding test (4)");
+
+ byteArray = new Clipperz.ByteArray().appendBase64String("d2hhdCAgd2lsbCAgIHByaW50ICAgICBvdXQ=");
+ is(byteArray.asString(), "what will print out", "base64 deconding test (5)");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'base64_encoding_decoding_longText_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("base64_encoding_decoding_longText_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var longText;
+ var byteArray;
+ var base64encoding;
+
+ longText = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur interdum vulputate ligula. Aliquam erat volutpat. Fusce malesuada felis et purus. Vivamus convallis, metus id lacinia venenatis, est eros sagittis neque, at porttitor erat lorem a risus. Phasellus ultricies nunc et turpis. Ut nec sem ut quam ornare feugiat. Donec nibh. Quisque ullamcorper, neque eu convallis dictum, orci nisl dictum quam, ac elementum arcu sem varius sem. Suspendisse vitae dolor non magna suscipit semper. Suspendisse ac magna. Praesent et purus. Aenean ut justo. Curabitur dictum, nisl a consectetuer viverra, libero est auctor metus, et rhoncus risus diam in orci. Nam magna felis, lobortis eu, eleifend quis, tristique quis, mi. Praesent aliquet. Aenean mollis turpis sed dolor. Donec ac nunc. Nulla eu lacus in ipsum molestie rutrum. Nunc dignissim purus non nibh. Maecenas congue risus at neque sollicitudin eleifend.\n\nNunc purus orci, sagittis ut, vehicula non, auctor eu, orci. Fusce non nisl vel risus rutrum venenatis. Donec dapibus sodales eros. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ultrices fringilla dui. Phasellus sit amet enim in tellus rutrum dapibus. Sed blandit malesuada turpis. Ut vel orci. Curabitur id eros. Sed sodales tempus urna. Praesent et neque. Sed ultricies. Praesent risus quam, elementum eget, tincidunt ac, condimentum sit amet, urna.\n\nLorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin vel diam imperdiet felis luctus luctus. Nunc tincidunt nisl ac arcu. Sed id urna id magna nonummy varius. Mauris ligula. Vivamus purus eros, dignissim non, bibendum eget, dapibus sit amet, urna. Donec scelerisque dapibus odio. Aenean gravida ante at eros. Aenean volutpat vehicula urna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed elementum nisi ac dui. Fusce consectetuer venenatis nisi. Etiam diam. Nunc urna tortor, feugiat sed, facilisis eu, lacinia ut, felis. Vivamus vel lacus in massa accumsan faucibus. Cras iaculis eros. Donec non risus eu mi aliquam facilisis. Quisque vitae erat. Vivamus sed felis at metus ullamcorper ornare. Aliquam orci.\n\nPellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras ultrices, tortor in tempus laoreet, orci magna auctor quam, ultricies consequat sem eros eu magna. Mauris tempus egestas libero. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Curabitur auctor molestie ante. Quisque laoreet urna a quam. Sed sagittis, nulla vitae bibendum tempus, metus ante bibendum urna, ut ullamcorper mi urna vitae neque. Praesent dolor. Maecenas sit amet tortor. Proin erat. Suspendisse ipsum. Nulla facilisi. Vestibulum nonummy nulla ac libero. Aliquam in mauris ut libero cursus ullamcorper. Nam ullamcorper auctor tortor.\n\nNulla et odio. Duis nec velit. Sed posuere neque vitae dolor. Phasellus diam massa, sollicitudin vel, pellentesque in, fringilla pretium, libero. In lacinia massa ut libero pharetra sodales. Aliquam erat volutpat. Suspendisse egestas, turpis at pretium placerat, sem dolor tristique felis, nec egestas lectus risus eu quam. Curabitur leo dolor, varius sed, tristique non, fermentum eget, elit. Vivamus a leo eu diam faucibus congue. Nam quam. Curabitur est velit, luctus quis, tempor et, mattis consectetuer, dolor. Ut accumsan dui nec mi. Donec enim. Mauris accumsan nisl. Praesent sit amet diam ut velit suscipit vehicula. Vestibulum augue diam, placerat sit amet, gravida volutpat, egestas nec, metus. Curabitur risus felis, tempus nec, blandit a, condimentum at, risus.";
+
+ byteArray = new Clipperz.ByteArray(longText);
+ base64encoding = byteArray.toBase64String();
+ byteArray = new Clipperz.ByteArray().appendBase64String(base64encoding);
+ is(byteArray.asString(), longText, "the base64 encoding/decoding works also with long texts");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'base32_encoding_decoding_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("base32_encoding_decoding_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray;
+
+ byteArray = new Clipperz.ByteArray("\n");
+ is(byteArray.toBase32String(), "18======", "base32 encoding test (1)");
+
+ byteArray = new Clipperz.ByteArray().appendBase32String("18======");
+ is(byteArray.toBase32String(), "18======", "base32 encoding test (2)");
+
+ byteArray = new Clipperz.ByteArray().appendBase32String("lLiIo0O1");
+ is(byteArray.toBase32String(), "11110001", "base32 encoding test (3)");
+
+ byteArray = new Clipperz.ByteArray().appendBase32String("lLiI o0O1");
+ is(byteArray.toBase32String(), "11110001", "base32 encoding test (3.1)");
+
+ byteArray = new Clipperz.ByteArray("0xffffffffff");
+ is(byteArray.toBase32String(), "zzzzzzzz", "base32 encoding test (4)");
+
+ byteArray = new Clipperz.ByteArray().appendBase32String("cccccccc");
+ is(byteArray.toBase32String(), "cccccccc", "base32 encoding test (5)");
+
+ byteArray = new Clipperz.ByteArray().appendBase32String("bbbbbbbb");
+ is(byteArray.toBase32String(), "bbbbbbbb", "base32 encoding test (6)");
+
+ byteArray = new Clipperz.ByteArray().appendBase32String("aAbBcCdD");
+ is(byteArray.toHexString(), "0x5296b631ad", "base32 encoding test (7 hex)");
+ is(byteArray.toBase32String(), "aabbccdd", "base32 encoding test (7)");
+
+ byteArray = new Clipperz.ByteArray().appendBase32String("lLiIo0O1-aAbBcCdD-abcdefge-ll11ooOO");
+ is(byteArray.toBase32String(), "11110001aabbccddabcdefge11110000", "base32 encoding test (8)");
+
+ byteArray = new Clipperz.ByteArray().appendBase32String("lLiI o0O1 - aAbB cCdD - abcd efge - ll11 ooOO");
+ is(byteArray.toBase32String(), "11110001aabbccddabcdefge11110000", "base32 encoding test (8.1)");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'base32_encoding_decoding_longText_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("base32_encoding_decoding_longText_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var longText;
+ var base32String;
+ var byteArray;
+
+ longText = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Curabitur interdum vulputate ligula. Aliquam erat volutpat. Fusce malesuada felis et purus. Vivamus convallis, metus id lacinia venenatis, est eros sagittis neque, at porttitor erat lorem a risus. Phasellus ultricies nunc et turpis. Ut nec sem ut quam ornare feugiat. Donec nibh. Quisque ullamcorper, neque eu convallis dictum, orci nisl dictum quam, ac elementum arcu sem varius sem. Suspendisse vitae dolor non magna suscipit semper. Suspendisse ac magna. Praesent et purus. Aenean ut justo. Curabitur dictum, nisl a consectetuer viverra, libero est auctor metus, et rhoncus risus diam in orci. Nam magna felis, lobortis eu, eleifend quis, tristique quis, mi. Praesent aliquet. Aenean mollis turpis sed dolor. Donec ac nunc. Nulla eu lacus in ipsum molestie rutrum. Nunc dignissim purus non nibh. Maecenas congue risus at neque sollicitudin eleifend.\n\nNunc purus orci, sagittis ut, vehicula non, auctor eu, orci. Fusce non nisl vel risus rutrum venenatis. Donec dapibus sodales eros. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In ultrices fringilla dui. Phasellus sit amet enim in tellus rutrum dapibus. Sed blandit malesuada turpis. Ut vel orci. Curabitur id eros. Sed sodales tempus urna. Praesent et neque. Sed ultricies. Praesent risus quam, elementum eget, tincidunt ac, condimentum sit amet, urna.\n\nLorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin vel diam imperdiet felis luctus luctus. Nunc tincidunt nisl ac arcu. Sed id urna id magna nonummy varius. Mauris ligula. Vivamus purus eros, dignissim non, bibendum eget, dapibus sit amet, urna. Donec scelerisque dapibus odio. Aenean gravida ante at eros. Aenean volutpat vehicula urna. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Sed elementum nisi ac dui. Fusce consectetuer venenatis nisi. Etiam diam. Nunc urna tortor, feugiat sed, facilisis eu, lacinia ut, felis. Vivamus vel lacus in massa accumsan faucibus. Cras iaculis eros. Donec non risus eu mi aliquam facilisis. Quisque vitae erat. Vivamus sed felis at metus ullamcorper ornare. Aliquam orci.\n\nPellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Cras ultrices, tortor in tempus laoreet, orci magna auctor quam, ultricies consequat sem eros eu magna. Mauris tempus egestas libero. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Curabitur auctor molestie ante. Quisque laoreet urna a quam. Sed sagittis, nulla vitae bibendum tempus, metus ante bibendum urna, ut ullamcorper mi urna vitae neque. Praesent dolor. Maecenas sit amet tortor. Proin erat. Suspendisse ipsum. Nulla facilisi. Vestibulum nonummy nulla ac libero. Aliquam in mauris ut libero cursus ullamcorper. Nam ullamcorper auctor tortor.\n\nNulla et odio. Duis nec velit. Sed posuere neque vitae dolor. Phasellus diam massa, sollicitudin vel, pellentesque in, fringilla pretium, libero. In lacinia massa ut libero pharetra sodales. Aliquam erat volutpat. Suspendisse egestas, turpis at pretium placerat, sem dolor tristique felis, nec egestas lectus risus eu quam. Curabitur leo dolor, varius sed, tristique non, fermentum eget, elit. Vivamus a leo eu diam faucibus congue. Nam quam. Curabitur est velit, luctus quis, tempor et, mattis consectetuer, dolor. Ut accumsan dui nec mi. Donec enim. Mauris accumsan nisl. Praesent sit amet diam ut velit suscipit vehicula. Vestibulum augue diam, placerat sit amet, gravida volutpat, egestas nec, metus. Curabitur risus felis, tempus nec, blandit a, condimentum at, risus.";
+ byteArray = new Clipperz.ByteArray(longText);
+ base32String = byteArray.toBase32String();
+ byteArray = new Clipperz.ByteArray().appendBase32String(base32String);
+ is(byteArray.asString(), longText, "base32 encoding test (9)");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'error_correction_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("error_correction_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var oddInput;
+ var byteArray;
+
+ oddInput = "0x1aa22bb33cc";
+ byteArray = new Clipperz.ByteArray(oddInput);
+ is(byteArray.toHexString(), "0x01aa22bb33cc", "fix an input hex string with on odd string length");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'zero_values_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("zero_values_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray;
+
+ byteArray = new Clipperz.ByteArray(0, 0, 0, 0);
+ is(byteArray.length(), 4, "An array with 4 '0' values has length = 4");
+ is(byteArray.byteAtIndex(0), 0, "The first element of a '0' filled array is '0'");
+
+ byteArray = new Clipperz.ByteArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ is(byteArray.length(), 16, "An array with 16 '0' values has length = 16");
+ is(byteArray.byteAtIndex(0), 0, "The first element of a '0' filled array is '0'");
+ is(byteArray.byteAtIndex(15), 0, "The last element of a '0' filled array is '0'");
+ is(byteArray.toHexString(), "0x00000000000000000000000000000000", "HEX representation of an array full of '0'");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'array_values_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("array_values_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray;
+ var arrayValues;
+
+ byteArray = new Clipperz.ByteArray("0xa1b2c3d4e5f6");
+ arrayValues = byteArray.arrayValues();
+ is(arrayValues[0], parseInt("0xa1"), "the first value of arrayValues is 'a1'");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'string_contructor_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("string_contructor_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+// var longAsciiText;
+// var longIsoLatin1Text;
+// var longUtf8Text;
+ var stringConstructorTestFunction;
+
+// longAsciiText = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam ac ipsum. Morbi mauris. Aenean ac elit id metus lobortis elementum. Proin at quam ac ipsum pellentesque adipiscing. Aenean vestibulum, nisl eu suscipit iaculis, quam pede congue mi, sit amet dapibus metus neque eget dui. Suspendisse posuere diam ac sapien. Nulla lobortis dapibus leo. Quisque ornare tortor quis turpis. Aliquam erat volutpat. Ut faucibus lacinia magna. Nunc metus leo, volutpat quis, mollis ac, sagittis ut, turpis. Quisque purus. Mauris ante enim, vehicula eu, suscipit vitae, laoreet vel, nulla. Pellentesque pede leo, aliquam quis, vehicula eget, rhoncus nec, metus. Vestibulum tellus. Suspendisse blandit. Pellentesque vel tellus. Maecenas arcu. Duis eget purus. Curabitur non pede nec odio cursus luctus. In non elit. Nullam eget nunc in nisl elementum commodo. Vivamus sollicitudin pede quis dui. Morbi commodo. Praesent a risus id urna hendrerit fermentum. Nunc ultricies tristique odio. Phasellus imperdiet, sapien eget viverra blandit, tortor risus blandit nisi, et sodales libero dolor quis nisl. Morbi vel enim. Nunc in quam. Vestibulum a magna. Fusce auctor elit in augue. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris tincidunt consectetuer leo. Etiam non turpis. Vestibulum eros. Praesent venenatis adipiscing augue. Pellentesque dapibus odio ac arcu rhoncus sagittis. Nullam vitae augue. Ut magna nulla, congue eu, porta in, egestas quis, ligula. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur malesuada neque non nulla. Nulla facilisi. Fusce viverra magna ut tellus. Sed rutrum pretium sapien. Vivamus dui. Cras fringilla. Nullam lorem. Vestibulum varius, purus at imperdiet fermentum, metus diam ultricies lacus, vitae aliquam ipsum libero sit amet felis. Sed eget eros ac velit commodo sollicitudin. Morbi in metus in mi viverra lacinia. Sed ut urna. Suspendisse imperdiet tellus ac velit. Duis malesuada velit sit amet sapien. Vestibulum a sapien id libero accumsan luctus. Fusce iaculis. Donec pulvinar orci ut pede. Nam placerat sem ut sem. Ut pretium bibendum nisl. Suspendisse potenti. Phasellus mollis neque in neque. Suspendisse augue magna, eleifend et, malesuada at, viverra in, nisl. Donec vel lectus in justo ultrices tristique. Aliquam erat volutpat. Morbi suscipit, risus ac volutpat mollis, risus metus hendrerit sapien, ac scelerisque est orci eu est. Quisque sit amet velit. Sed libero diam, semper id, eleifend ac, iaculis non, nulla. Donec varius tincidunt arcu. Sed quis metus eu erat adipiscing viverra. Donec odio. Aenean sagittis nisl sed purus. Fusce vel nibh quis felis accumsan bibendum. Etiam et risus ac tortor cursus pharetra. Maecenas tellus. Pellentesque nec felis id eros vehicula commodo. Aliquam interdum sagittis odio. Maecenas at lorem eget mi aliquet sagittis. Mauris quis nibh in odio sodales lacinia. Proin augue mauris, placerat a, blandit vel, tincidunt eget, ante. Quisque turpis purus, placerat eget, tempor consectetuer, aliquet ac, enim. Etiam eleifend vestibulum mi. Vivamus gravida. Morbi dolor. In hac habitasse platea dictumst. Nulla commodo lectus faucibus lorem. Phasellus aliquet pede id metus hendrerit tempus. Fusce convallis pede ac neque tempor dignissim. Sed vitae lorem sit amet justo dapibus porta. Ut quam orci, pretium non, sagittis nec, condimentum id, dolor. Sed tempor. Nunc porta rutrum leo. Nunc id sem. Sed nibh tortor, dapibus eget, feugiat a, pretium pretium, purus. Suspendisse suscipit lobortis sem. Praesent pharetra orci. Quisque molestie tristique quam. Maecenas nunc lorem, rhoncus non, venenatis sed, sodales at, felis. Quisque semper. Quisque malesuada est quis lacus. Nullam a justo. Aliquam pellentesque, ante ut congue molestie, nisl sapien posuere nisl, eu cursus nulla ligula vel nisl. Fusce commodo lacinia magna. Aenean rutrum vestibulum lorem. Pellentesque fermentum tristique ipsum. Nulla facilisi. Donec id mi eget ipsum commodo egestas. Mauris iaculis. Nulla vulputate mi at nisl. In condimentum sodales tellus. Donec metus orci, mollis vel, accumsan ac, ornare ac, lacus. Pellentesque accumsan est et tellus. Nam mollis. Aenean accumsan eros sit amet tellus. Praesent eu libero. Sed tempus urna nec dolor. Nulla facilisi. Duis eleifend rhoncus neque. Curabitur consectetuer quam eu justo. Sed metus. Vivamus risus. Aliquam erat volutpat. Aliquam erat volutpat. Nunc semper urna. Praesent molestie libero a lacus. Nullam suscipit lobortis velit. Praesent rhoncus, felis ut interdum dapibus, ipsum lectus vestibulum nulla, in interdum risus dolor eget orci. Nullam venenatis. Suspendisse laoreet, arcu a luctus consectetuer, libero ligula condimentum quam, eget elementum mauris tortor sed enim. Pellentesque leo. Nam interdum malesuada ante. Praesent fermentum nunc et dolor. Donec auctor volutpat odio. Pellentesque volutpat egestas ipsum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ac ligula eu justo dignissim accumsan. Nullam nisi. Fusce id sem. Fusce et urna. Pellentesque commodo pharetra lorem. Donec erat. Vestibulum elit arcu, commodo et, consequat eget, posuere eget, sem. Morbi sed nulla sed neque commodo commodo. Aliquam erat volutpat. Ut id turpis a enim malesuada vestibulum. In arcu dui, dignissim vitae, blandit eu, egestas ac, arcu. In ultricies sapien vitae nisi. Proin rhoncus magna eget tortor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In dictum. Sed volutpat pharetra quam. Mauris eget eros. Fusce malesuada dolor id pede. Praesent nec justo sed nisi vehicula varius. In scelerisque convallis nulla. Pellentesque sodales massa vulputate urna. Duis metus urna, imperdiet ac, sodales vel, ullamcorper sed, pede. Vestibulum aliquam mollis metus. Praesent tempus tristique elit. Maecenas tellus tortor, pretium id, mollis id, molestie non, turpis. Vivamus nibh magna, bibendum vitae, a.";
+ is(longAsciiText.length, 6000, "tThe ascii string should be 6000 char long");
+
+// longIsoLatin1Text = "¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùù";
+ is(longIsoLatin1Text.length, 3000, "The Iso-Latin1 string should be 3000 char long");
+
+// longUtf8Text = "客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之";
+ is(longUtf8Text.length, 2000, "tThe UTF8 string should be 2000 char long");
+
+ stringConstructorTestFunction = function(aTestString, aLabel) {
+ var byteArray;
+ var base64String;
+ var stringConstructorStartTime, stringConstructorEndTime;
+ var maxExpectedTime;
+
+stringConstructorStartTime = new Date();
+ byteArray = new Clipperz.ByteArray(aTestString);
+stringConstructorEndTime = new Date();
+ maxExpectedTime = 30;
+ is(byteArray.length(), 6000, "[" + aLabel + "] The reference text should be 6000 bytes long");
+ is((stringConstructorEndTime - stringConstructorStartTime) < maxExpectedTime, true, "[" + aLabel + "] The construction of the byte array took " + (stringConstructorEndTime - stringConstructorStartTime) + " (expected < " + maxExpectedTime + ")");
+//MochiKit.Logging.logDebug("[" + aLabel + "] The construction of the byte array took " + (stringConstructorEndTime - stringConstructorStartTime));
+
+stringConstructorStartTime = new Date();
+ base64String = byteArray.toBase64String();
+stringConstructorEndTime = new Date();
+ maxExpectedTime = 30;
+ is(base64String.length, 8000, "[" + aLabel + "] the base64 representation of 6000 bytes is 8000 chars long");
+ is((stringConstructorEndTime - stringConstructorStartTime) < maxExpectedTime, true, "[" + aLabel + "] The generation of the base64 string took " + (stringConstructorEndTime - stringConstructorStartTime) + " (expected < " + maxExpectedTime + ")");
+//MochiKit.Logging.logDebug("[" + aLabel + "] The generation of the base64 string took " + (stringConstructorEndTime - stringConstructorStartTime));
+
+stringConstructorStartTime = new Date();
+ byteArray = new Clipperz.ByteArray();
+ byteArray.appendBase64String(base64String);
+stringConstructorEndTime = new Date();
+ maxExpectedTime = 200;
+ is(byteArray.length(), 6000, "[" + aLabel + "] a byte array build from a 8000 chars base64 string should contain 6000 bytes");
+ is((stringConstructorEndTime - stringConstructorStartTime) < maxExpectedTime, true, "[" + aLabel + "] The construction of the byte array from a base64 string took " + (stringConstructorEndTime - stringConstructorStartTime) + " (expected < " + maxExpectedTime + ")");
+//MochiKit.Logging.logDebug("[" + aLabel + "] The construction of the byte array from a base64 string took " + (stringConstructorEndTime - stringConstructorStartTime));
+ }
+
+ stringConstructorTestFunction(longAsciiText, "ASCII");
+ stringConstructorTestFunction(longIsoLatin1Text, "ISO-Latin1");
+ stringConstructorTestFunction(longUtf8Text, "UTF-8");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'bit_operations_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("bit_operations_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var byteArray;
+
+ byteArray = new Clipperz.ByteArray(0, 255, 0, 255);
+ is(byteArray.bitAtIndex(0), 1, "bitAtIndex - test 1");
+ is(byteArray.bitAtIndex(7), 1, "bitAtIndex - test 2");
+ is(byteArray.bitAtIndex(8), 0, "bitAtIndex - test 3");
+
+ is(byteArray.bitBlockAtIndexWithSize(0, 4), 15, "bitBlockAtIndexWithSize - test 1");
+ is(byteArray.bitBlockAtIndexWithSize(4, 4), 15, "bitBlockAtIndexWithSize - test 2");
+ is(byteArray.bitBlockAtIndexWithSize(4, 6), 15, "bitBlockAtIndexWithSize - test 3");
+ is(byteArray.bitBlockAtIndexWithSize(8, 4), 0, "bitBlockAtIndexWithSize - test 4");
+ is(byteArray.bitBlockAtIndexWithSize(12, 4), 0, "bitBlockAtIndexWithSize - test 5");
+ is(byteArray.bitBlockAtIndexWithSize(12, 5), 16, "bitBlockAtIndexWithSize - test 6");
+ is(byteArray.bitBlockAtIndexWithSize(12, 6), 48, "bitBlockAtIndexWithSize - test 7");
+
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'prefixMatchingBits_tests': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("simple_tests", someTestArgs);
+ deferredResult.addCallback(function() {
+ var value1;
+ var value2;
+ var toll;
+
+// toll = new Clipperz.PM.Toll();
+
+ value1 = new Clipperz.ByteArray("0x0000000000000000000000000000000000000000000000000000000000000000");
+ value2 = new Clipperz.ByteArray("0x0000000000000000000000000000000000000000000000000000000000000000");
+ is(Clipperz.ByteArray.prefixMatchingBits(value1, value2), 256);
+
+ value1 = new Clipperz.ByteArray("0x0000000000000000000000000000000000000000000000000000000000000000");
+ value2 = new Clipperz.ByteArray("0x0000000000000000000000000000000000000000000000000000000000000008");
+ is(Clipperz.ByteArray.prefixMatchingBits(value1, value2), 252);
+
+ value1 = new Clipperz.ByteArray("0x0000000000000000000000000000000000000000000000000000000000000000");
+ value2 = new Clipperz.ByteArray("0x0000000000000000000000000000000080000000000000000000000000000000");
+ is(Clipperz.ByteArray.prefixMatchingBits(value1, value2), 128);
+
+ value1 = new Clipperz.ByteArray("0x0000000000000000000000000000000000000000000000000000000000000000");
+ value2 = new Clipperz.ByteArray("0x8000000000000000000000000000000080000000000000000000000000000000");
+ is(Clipperz.ByteArray.prefixMatchingBits(value1, value2), 0);
+
+ value1 = new Clipperz.ByteArray("0x0000000000000000000000000000000000000000000000000000000000000000");
+ value2 = new Clipperz.ByteArray("0x0100000000000000000000000000000000000000000000000000000000000000");
+ is(Clipperz.ByteArray.prefixMatchingBits(value1, value2), 7);
+
+ value1 = new Clipperz.ByteArray("0x0000000000000000000000000000000000000000000000000000000000000000");
+ value2 = new Clipperz.ByteArray("0x0000000000000000000000000000000000000000000000000000000000000001");
+ is(Clipperz.ByteArray.prefixMatchingBits(value1, value2), 255);
+
+ value1 = new Clipperz.ByteArray("0x0000000000000000000000000000000000000000000000000000000000000000");
+ value2 = new Clipperz.ByteArray("0x4000000000000000000000000000000000000000000000000000000000000000");
+ is(Clipperz.ByteArray.prefixMatchingBits(value1, value2), 1);
+
+ value1 = new Clipperz.ByteArray("0x0853120d776e04325d070c082e06390315505166740b07007f060f003e0c576f");
+ value2 = new Clipperz.ByteArray("0x0853120d776e04325d070c082e06390315505166740b07007f060f003e0c576f");
+ is(Clipperz.ByteArray.prefixMatchingBits(value1, value2), 256);
+
+ value1 = new Clipperz.ByteArray("0x0a03580756011d000a620e3b60670508092f020a0a0c2500282d480307000046");
+ value2 = new Clipperz.ByteArray("0x0a03580756011d000a620e3b60670508092f020a0a0c2500282d480307004d46");
+ is(Clipperz.ByteArray.prefixMatchingBits(value1, value2), 241);
+
+ value1 = new Clipperz.ByteArray("0x0a03580756011d000a620e3b60670508092f020a0a0c2500282d480307000046");
+ value2 = new Clipperz.ByteArray("0x0a83580756011d000a620e3b60670508092f020a0a0c2500282d480307004d46");
+ is(Clipperz.ByteArray.prefixMatchingBits(value1, value2), 8);
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'binaryString_test': function (someTestArgs) {
+ var hexString;
+ var binaryString;
+
+ var testBinaryString = function (anHexString, aBinaryString) {
+ var byteArray;
+ var byteArrayFromBinaryString;
+
+ byteArray = new Clipperz.ByteArray(anHexString);
+ byteArrayFromBinaryString = (new Clipperz.ByteArray()).appendBinaryString(aBinaryString);
+ ok(byteArray.equals(byteArrayFromBinaryString), "the two byteArray have the same values");
+ is(byteArray.toBinaryString(), aBinaryString, "the binaryString matches");
+ };
+
+ hexString = "0x888990";
+ binaryString = "\x88\x89\x90";
+ testBinaryString(hexString, binaryString);
+
+ hexString = "0x000102030405060708090a0b0c0d0e0f";
+ binaryString = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f";
+ testBinaryString(hexString, binaryString);
+
+ hexString = "0x101112131415161718191a1b1c1d1e1f";
+ binaryString = "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";
+ testBinaryString(hexString, binaryString);
+
+ hexString = "0xd0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
+ binaryString = "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf";
+ testBinaryString(hexString, binaryString);
+
+ hexString = "0xe0e1e2e3e4e5e6e7e8e9eaebecedeeef";
+ binaryString = "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef";
+ testBinaryString(hexString, binaryString);
+
+ hexString = "0xf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff";
+ binaryString = "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
+ testBinaryString(hexString, binaryString);
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+//#############################################################################
+
+SimpleTest.runDeferredTests("Clipperz.ByteArray", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/AES.html b/frontend/gamma/tests/tests/Clipperz/Crypto/AES.html
new file mode 100644
index 0000000..93089b7
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/AES.html
@@ -0,0 +1,292 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.Crypto.AES_v3 - TEST</title>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+
+try {
+ var block;
+ var keyValue;
+ var key;
+ var encryptedBlock;
+ var startTime, endTime;
+
+ startTime = new Date();
+
+ keyValue = new Clipperz.ByteArray("0x00010203050607080a0b0c0d0f10111214151617191a1b1c1e1f202123242526");
+ key = new Clipperz.Crypto.AES.Key({key:keyValue});
+ block = new Clipperz.ByteArray("0x834eadfccac7e1b30664b1aba44815ab");
+ encryptedBlock = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(key, block.arrayValues()));
+ is(encryptedBlock.toHexString(), "0x1946dabf6a03a2a2c3d0b05080aed6fc", "Test 1");
+
+ keyValue = new Clipperz.ByteArray("0x28292a2b2d2e2f30323334353738393a3c3d3e3f41424344464748494b4c4d4e");
+ key = new Clipperz.Crypto.AES.Key({key:keyValue});
+ block = new Clipperz.ByteArray("0xd9dc4dba3021b05d67c0518f72b62bf1");
+ encryptedBlock = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(key, block.arrayValues()));
+ is(encryptedBlock.toHexString(), "0x5ed301d747d3cc715445ebdec62f2fb4", "Test 2");
+
+ keyValue = new Clipperz.ByteArray("0x50515253555657585a5b5c5d5f60616264656667696a6b6c6e6f707173747576");
+ key = new Clipperz.Crypto.AES.Key({key:keyValue});
+ block = new Clipperz.ByteArray("0xa291d86301a4a739f7392173aa3c604c");
+ encryptedBlock = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(key, block.arrayValues()));
+ is(encryptedBlock.toHexString(), "0x6585c8f43d13a6beab6419fc5935b9d0", "Test 3");
+
+ keyValue = new Clipperz.ByteArray("0x78797a7b7d7e7f80828384858788898a8c8d8e8f91929394969798999b9c9d9e");
+ key = new Clipperz.Crypto.AES.Key({key:keyValue});
+ block = new Clipperz.ByteArray("0x4264b2696498de4df79788a9f83e9390");
+ encryptedBlock = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(key, block.arrayValues()));
+ is(encryptedBlock.toHexString(), "0x2a5b56a596680fcc0e05f5e0f151ecae", "Test 4");
+
+ keyValue = new Clipperz.ByteArray("0xa0a1a2a3a5a6a7a8aaabacadafb0b1b2b4b5b6b7b9babbbcbebfc0c1c3c4c5c6");
+ key = new Clipperz.Crypto.AES.Key({key:keyValue});
+ block = new Clipperz.ByteArray("0xee9932b3721804d5a83ef5949245b6f6");
+ encryptedBlock = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(key, block.arrayValues()));
+ is(encryptedBlock.toHexString(), "0xf5d6ff414fd2c6181494d20c37f2b8c4", "Test 5");
+
+ keyValue = new Clipperz.ByteArray("0xc8c9cacbcdcecfd0d2d3d4d5d7d8d9dadcdddedfe1e2e3e4e6e7e8e9ebecedee");
+ key = new Clipperz.Crypto.AES.Key({key:keyValue});
+ block = new Clipperz.ByteArray("0xe6248f55c5fdcbca9cbbb01c88a2ea77");
+ encryptedBlock = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(key, block.arrayValues()));
+ is(encryptedBlock.toHexString(), "0x85399c01f59fffb5204f19f8482f00b8", "Test 6");
+
+ keyValue = new Clipperz.ByteArray("0xf0f1f2f3f5f6f7f8fafbfcfdfe01000204050607090a0b0c0e0f101113141516");
+ key = new Clipperz.Crypto.AES.Key({key:keyValue});
+ block = new Clipperz.ByteArray("0xb8358e41b9dff65fd461d55a99266247");
+ encryptedBlock = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(key, block.arrayValues()));
+ is(encryptedBlock.toHexString(), "0x92097b4c88a041ddf98144bc8d22e8e7", "Test 7");
+
+ keyValue = new Clipperz.ByteArray("0x18191a1b1d1e1f20222324252728292a2c2d2e2f31323334363738393b3c3d3e");
+ key = new Clipperz.Crypto.AES.Key({key:keyValue});
+ block = new Clipperz.ByteArray("0xf0e2d72260af58e21e015ab3a4c0d906");
+ encryptedBlock = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(key, block.arrayValues()));
+ is(encryptedBlock.toHexString(), "0x89bd5b73b356ab412aef9f76cea2d65c", "Test 8");
+
+ keyValue = new Clipperz.ByteArray("0x40414243454647484a4b4c4d4f50515254555657595a5b5c5e5f606163646566");
+ key = new Clipperz.Crypto.AES.Key({key:keyValue});
+ block = new Clipperz.ByteArray("0x475b8b823ce8893db3c44a9f2a379ff7");
+ encryptedBlock = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(key, block.arrayValues()));
+ is(encryptedBlock.toHexString(), "0x2536969093c55ff9454692f2fac2f530", "Test 9");
+
+ keyValue = new Clipperz.ByteArray("0x68696a6b6d6e6f70727374757778797a7c7d7e7f81828384868788898b8c8d8e");
+ key = new Clipperz.Crypto.AES.Key({key:keyValue});
+ block = new Clipperz.ByteArray("0x688f5281945812862f5f3076cf80412f");
+ encryptedBlock = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(key, block.arrayValues()));
+ is(encryptedBlock.toHexString(), "0x07fc76a872843f3f6e0081ee9396d637", "Test 10");
+
+ //-------------------------------------------------------------------------
+ //
+ // Key expansion
+ //
+ //-------------------------------------------------------------------------
+ // test vector: http://en.wikipedia.org/wiki/Rijndael_key_schedule#Test_vectors
+
+ keyValue = new Clipperz.ByteArray("0x0000000000000000000000000000000012345678");
+ try {
+ key = new Clipperz.Crypto.AES.Key({key:keyValue});
+ is(true, false, "Unsupported key size");
+ } catch (exception) {
+ is(true, true, "Unsupported key size");
+ }
+
+ keyValue = new Clipperz.ByteArray("0x00000000000000000000000000000000");
+ key = new Clipperz.Crypto.AES.Key({key:keyValue});
+ is( key.stretchedKey().toHexString(),
+ "0x" + "00000000000000000000000000000000" +
+ "62636363626363636263636362636363" +
+ "9b9898c9f9fbfbaa9b9898c9f9fbfbaa" +
+ "90973450696ccffaf2f457330b0fac99" +
+ "ee06da7b876a1581759e42b27e91ee2b" +
+ "7f2e2b88f8443e098dda7cbbf34b9290" +
+ "ec614b851425758c99ff09376ab49ba7" +
+ "217517873550620bacaf6b3cc61bf09b" +
+ "0ef903333ba9613897060a04511dfa9f" +
+ "b1d4d8e28a7db9da1d7bb3de4c664941" +
+ "b4ef5bcb3e92e21123e951cf6f8f188e",
+ "Stretched empty key");
+
+
+ keyValue = new Clipperz.ByteArray("0x0000000000000000000000000000000000000000000000000000000000000000");
+ key = new Clipperz.Crypto.AES.Key({key:keyValue});
+ is( key.stretchedKey().toHexString(),
+ "0x" + "00000000000000000000000000000000" +
+ "00000000000000000000000000000000" +
+ "62636363626363636263636362636363" +
+ "aafbfbfbaafbfbfbaafbfbfbaafbfbfb" +
+ "6f6c6ccf0d0f0fac6f6c6ccf0d0f0fac" +
+ "7d8d8d6ad77676917d8d8d6ad7767691" +
+ "5354edc15e5be26d31378ea23c38810e" +
+ "968a81c141fcf7503c717a3aeb070cab" +
+ "9eaa8f28c0f16d45f1c6e3e7cdfe62e9" +
+ "2b312bdf6acddc8f56bca6b5bdbbaa1e" +
+ "6406fd52a4f79017553173f098cf1119" +
+ "6dbba90b0776758451cad331ec71792f" +
+ "e7b0e89c4347788b16760b7b8eb91a62" +
+ "74ed0ba1739b7e252251ad14ce20d43b" +
+ "10f80a1753bf729c45c979e7cb706385",
+ "Stretched empty key");
+
+ var roundIndex;
+
+ roundIndex = 0;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0x00000000000000000000000000000000", "empty key, subKeyAtRound(0)");
+ roundIndex = 1;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0x00000000000000000000000000000000", "empty key, subKeyAtRound(1)");
+ roundIndex = 2;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0x62636363626363636263636362636363", "empty key, subKeyAtRound(2)");
+ roundIndex = 3;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0xaafbfbfbaafbfbfbaafbfbfbaafbfbfb", "empty key, subKeyAtRound(3)");
+ roundIndex = 4;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0x6f6c6ccf0d0f0fac6f6c6ccf0d0f0fac", "empty key, subKeyAtRound(4)");
+ roundIndex = 5;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0x7d8d8d6ad77676917d8d8d6ad7767691", "empty key, subKeyAtRound(5)");
+ roundIndex = 6;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0x5354edc15e5be26d31378ea23c38810e", "empty key, subKeyAtRound(6)");
+ roundIndex = 7;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0x968a81c141fcf7503c717a3aeb070cab", "empty key, subKeyAtRound(7)");
+ roundIndex = 8;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0x9eaa8f28c0f16d45f1c6e3e7cdfe62e9", "empty key, subKeyAtRound(8)");
+ roundIndex = 9;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0x2b312bdf6acddc8f56bca6b5bdbbaa1e", "empty key, subKeyAtRound(9)");
+ roundIndex = 10;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0x6406fd52a4f79017553173f098cf1119", "empty key, subKeyAtRound(10)");
+ roundIndex = 11;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0x6dbba90b0776758451cad331ec71792f", "empty key, subKeyAtRound(11)");
+ roundIndex = 12;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0xe7b0e89c4347788b16760b7b8eb91a62", "empty key, subKeyAtRound(12)");
+ roundIndex = 13;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0x74ed0ba1739b7e252251ad14ce20d43b", "empty key, subKeyAtRound(13)");
+ roundIndex = 14;
+ is(key.stretchedKey().split(roundIndex*16, roundIndex*16 + 16).toHexString(), "0x10f80a1753bf729c45c979e7cb706385", "empty key, subKeyAtRound(14)");
+
+
+ //-------------------------------------------------------------------------
+ //
+ // Encrypt / decrypt
+ //
+ //-------------------------------------------------------------------------
+ // Test vectors: http://www.zvon.org/tmRFC/RFC3686/Output/chapter6.html
+ // http://www.cs.utsa.edu/~wagner/laws/AEStestRuns.html
+ // http://www.ietf.org/rfc/rfc3686.txt
+
+ {
+ //
+ // http://www.cs.utsa.edu/~wagner/laws/AEStestRuns.html
+ //
+ var key;
+ var plainText;
+ var cipherText;
+ var result;
+
+ //
+ // 256-bit key size
+ //
+
+ // Gladman's Test Data, 256-bit key - encrypt
+ key = new Clipperz.ByteArray("0x2b7e151628aed2a6abf7158809cf4f3c762e7160f38b4da56a784d9045190cfe", 16);
+ plainText = new Clipperz.ByteArray("0x3243f6a8885a308d313198a2e0370734", 16);
+ cipherText = new Clipperz.ByteArray("0x1a6e6c2c662e7da6501ffb62bc9e93f3", 16);
+
+ result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(new Clipperz.Crypto.AES.Key({key:key}), plainText.arrayValues()));
+ is(result.toHexString(), cipherText.toHexString(), "Gladman's Test Data, 256-bit key - encrypt");
+
+ // AES Specification Test Data, 256-bit key - encrypt
+ key = new Clipperz.ByteArray("0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", 16);
+ plainText = new Clipperz.ByteArray("0x00112233445566778899aabbccddeeff", 16);
+ cipherText = new Clipperz.ByteArray("0x8ea2b7ca516745bfeafc49904b496089", 16);
+
+ result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(new Clipperz.Crypto.AES.Key({key:key}), plainText.arrayValues()));
+ is(result.toHexString(), cipherText.toHexString(), "AES Specification Test Data, 256-bit key - encrypt");
+
+ //
+ // 128-bit key size
+ //
+
+ // Gladman's Test Data, 128-bit key - encrypt
+ key = new Clipperz.ByteArray("0x2b7e151628aed2a6abf7158809cf4f3c", 16);
+ plainText = new Clipperz.ByteArray("0x3243f6a8885a308d313198a2e0370734", 16);
+ cipherText = new Clipperz.ByteArray("0x3925841d02dc09fbdc118597196a0b32", 16);
+
+ result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(new Clipperz.Crypto.AES.Key({key:key}), plainText.arrayValues()));
+ is(result.toHexString(), cipherText.toHexString(), "Gladman's Test Data, 128-bit key - encrypt");
+
+ // AES Specification Test Data, 128-bit key - encrypt
+ key = new Clipperz.ByteArray("0x000102030405060708090a0b0c0d0e0f", 16);
+ plainText = new Clipperz.ByteArray("0x00112233445566778899aabbccddeeff", 16);
+ cipherText = new Clipperz.ByteArray("0x69c4e0d86a7b0430d8cdb78070b4c55a", 16);
+
+ result = new Clipperz.ByteArray(Clipperz.Crypto.AES.encryptBlock(new Clipperz.Crypto.AES.Key({key:key}), plainText.arrayValues()));
+ is(result.toHexString(), cipherText.toHexString(), "AES Specification Test Data, 128-bit key - encrypt");
+
+ }
+
+
+ endTime = new Date();
+ MochiKit.Logging.logDebug("elapsed time: " + (endTime - startTime));
+
+//#############################################################################
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/AES.performance.html b/frontend/gamma/tests/tests/Clipperz/Crypto/AES.performance.html
new file mode 100644
index 0000000..0d1cf07
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/AES.performance.html
@@ -0,0 +1,344 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.Crypto.AES_performance - TEST</title>
+
+ <script>
+ jslog_config_enabled = true;
+ </script>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+
+try {
+
+ var password;
+ var plainText;
+ var encryptedText;
+ var decryptedText;
+/*
+ password = "trustno1";
+ plainText = "The quick brown fox jumps over the lazy dog";
+//console.profile("encrypt");
+ encryptedText = Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].encrypt(password, plainText);
+//console.profileEnd();
+//console.profile("decrypt");
+ decryptedText = Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].decrypt(password, encryptedText);
+//console.profileEnd();
+ is(decryptedText, plainText, "simple string encrypted/decrypted");
+*/
+
+ password = "L7bd9fQMhborMbYcHtlr";
+ plainText = {"records":{"f1aac97154a0e52c5e33508afa82df5a9d6dcde24883a240b8c072a3238da0b6":{"label":"imap4all [no]", "key":"f54b5033d1152456acb67974c45ee6771f8411e300c9533359dfacacf60dcbbd", "notes":""}, "c9dae2b7a60b300008306f5ec731b60050250df8f8ff34f7d9cce92762121b99":{"label":"Il manifesto", "key":"6e0ef134503110e72f444e7d102a4b1cc6ae28f2e0b1287c2b1875ff052fc16c", "notes":""}, "70d536c89a86b1aa9e077d6f9c717306a5d6c8d5549789e42dfb4f981484f116":{"label":"OmniGroup applications", "key":"7b432b7dae39ff5951db31947fa721dc012af0da4055760c6df3b02e776ef22c", "notes":"url: http://www.omnigroup.com\n\nLicence owner: Giulio Cesare Solaroli\n\nOmniWeb: EQGP-EMKH-LKWP-MUHQ-OUHL-LDF\nOmniGraffle:\nOmniOutliner:\nOmniDiskSweeper:"}, "111855cedd650dfcbbce597d764583c6b040df4b71f5fa0161fb8d10514ee48f":{"label":"R@cine", "key":"57295772c84669b0a224f435e9b75c797ae5999a2d9473ab50f9384ae54f49d6", "notes":""}, "378a790452de46e1079a99eba2e15094a096b418cccd0262b8b20244eb94d2df":{"label":"NewsGator", "key":"6ee16f6932ee02000c49dbcc685c84074b40d7956e5f4bc1100030a0f9a41f1a", "notes":""}, "30c4f575799fc6908765fc8b54f4a9a483cb32e12aa89feae545976870a9102e":{"label":"GMail - giulio.cesare", "key":"0395efd852b00700bcf78b65350ec15932430df71201d2c53a11b0269b557d1a", "notes":""}, "b2836a864ff081b6f053c3f5f13dfb29c81af33d25a316cdd82af747ea71bea0":{"label":"GMail - clipperz.com", "key":"90d6ae70d89c8211404b6f9d6c70b6b9c113fff74f474a67b34acd9c1c048d1f", "notes":""}, "6ad2cda35f97743cfddf2133cdf3142fe6419e683484531f1ef1e67431f44284":{"label":"Aruba - hosting", "key":"5c7472d24d57391c63ea99ed1fc9de179d225abd335fa65702018cfea6083d47", "notes":""}, "741ce1d21839c69db754309b04ce02fbb4104f6cb87572c056ae4af918420700":{"label":"Aruba - sql hosting", "key":"f6bd942ac3b0b7065771e5197c7499b345a10f7a4843d00c3ba3809d0ea059dc", "notes":""}, "1cef440eecea59f47554aa04b94e18c1d9fc761246b911f89a7da72d544cac48":{"label":"Amazon", "key":"1ae022b4d14b642f113703b2a98931bd892dec2da785ab5ff6fc1d0aac7537f1", "notes":""}, "d34c13773b5d8154355c2605024a1dfaf66279ba0fbe3ac19fc1cbc642278fe4":{"label":"YouTube [no]", "key":"4c6593d4f6448137939b364b84c81501fadb60f7871fe5fa63c93e97bb5c4648", "notes":""}, "5054f0b94cd97610a1bc0ed8671b6fb5b25bf7a5582677059fcaaea75fac27bc":{"label":"DynDns - gcsolaroli", "key":"f8ed9e7a3630deed046eda37ebc63ecb4d63668a2f97224d7628fdc53b242467", "notes":""}, "73fb52ed51533657d6ebb020d5026fb4deb601dadce802de58f7fff4b56e1495":{"label":"DynDns - clipperz", "key":"d8bc295177383a523e67b61b166e0ca956ab4c2ee86800559a009d2716064f6d", "notes":""}, "48d4c0546c032be26ecce4da41e020129afa7fc34cfe164ea72e1c9953d2e6bb":{"label":"Bol.it", "key":"cada5dadeebd8d12190954d21f1a944c8799d034f028be195b448935fcf970c7", "notes":""}, "d62d420db34720ccc054df06b88725ea79020ffa9389ca15e70137fb4dfd0883":{"label":"Freenigma - clipperz.com", "key":"f09cb3790c1110794b834702b8c487c1a42b2508fbe6450a8468477d93790b2e", "notes":""}, "ccd44ae294e7694ea53009c7198506cc0fe3121ad5d9fe2635d247e2afdab2ae":{"label":"Freenigma", "key":"4b05738f6faebc147eac5e425054a91d3cc59dd63844e82d1f0864c0ac8efec7", "notes":""}, "bd5a587bb977a2c728fcd0fa6093dd63a4e62138cf89721115fe45e0396ba5d2":{"label":"clipperz.com - blog", "key":"9cc24328bbce18e8713962428d8123e309a12f7e1d9537bc252e134501734003", "notes":""}, "c2b99939e40d100218baa3ed1cb2a25a5cf726485b0336a0989b104a94157b5f":{"label":"Apple", "key":"75f2651af400629c4e5dd8bcdc3a6c691150d23d6e1a4eb263ff810926d1228f", "notes":""}, "b5bd38d8eb5e23b1354884cc519e05580864fadf74d0a19d2c691cd0c7054d77":{"label":".mac", "key":"5934ae96d2e01282effb368d9086c2ba5d1d856ad91dd6f04f5bace26a1c0cbe", "notes":""}, "ff79a2282cf246add520a3c06e835cf6ffaaae95067d45e8e2e8f44da2501380":{"label":"3nity", "key":"33d84c4a91ab053cbf8115c689ede7e504b81199884de449acc257bea534f57f", "notes":""}, "7b2f2a59ebb34b5a49f20b99b546f08b9f4f62cbefdce9699f8ef7e74aeb0552":{"label":"ACM", "key":"b4976bb0892baba81d628513d191de100d89acd58efbb07c823a5bb4abe48a7a", "notes":""}, "b83a6bac0da3a27eb909d34cbad183e77088952f01d8d5321613b7b01635a020":{"label":"Adobe", "key":"d162bc404994a79ec97e0106c3a4edf2f83aca25def130242e11e95e74bd0aaa", "notes":""}, "befc571e9cda1a7dfb1d15200240ca5170386280ee7be6a12716904cb6d0ea44":{"label":"Adobe Photoshop Elements 3", "key":"18a62c3c2065399819707322f467ff4be030d7939acbe5182c8194599845c428", "notes":"Photoshop Elements 2:\n1057-4312-5223-2206-9509-6837"}, "0424f72608fedc969d64a6d5b4a16dd3ce860a230cd6d87d936439f4dd2aafc7":{"label":"Agatra", "key":"c35158a21b2af75d414232b742ab738d042314e00209f8fca94c8c704c891f23", "notes":""}, "e5e17c29fd598acb4f4c7d621dbdcb045d4d0cabf7d8a19e24420c440cdc3935":{"label":"AIM", "key":"8561ac421d845921978387b5e6b362750b57ed08feda8ec12b9378b69f67ceff", "notes":""}, "de890eb76a4b0cabd4ffd490adad1ff1b73238c7b5ee6dde1a2aeab2d03ebe93":{"label":"Anna Vespignani", "key":"79a970af0d2d30643dc2db4d16757395c1f22c311919036c2a22b7581982144a", "notes":""}, "0dc8d3989d0b35d672c012057d3eb7b111f16e79329e08a9ffb31ac7accbab21":{"label":"Bloglines", "key":"fe81f4df8c42fd81c830f9af408e9b074e77fd430e26d0ee285844fe3b092aec", "notes":""}, "85a40a322a59c80cb46519900269dcc7cf6947213d03dfc9371dd1930373a65b":{"label":"Bow.it", "key":"64a1a9fec99c9238dc8180a01484a1ccf5f50fcd6e9a95a52b8b49fb9ca00bdc", "notes":""}, "60308062a1848a301641a74712d220eef191a280ba0a8355992f0e61ed793811":{"label":"GMail - feedback", "key":"fad310cb2e6152c3faf78b7183c99f3044f5d31ee364068b80580c271a7784ef", "notes":""}, "257ac2da79ee1cd46dfa214d91f5ece213b6bbade28d1ee71495c81a3d7e033a":{"label":"Fineco", "key":"8f99de2635b5dad7987180bc0bff49947eb37cc75d6a5d1ee1f13ed7567465a3", "notes":""}, "78261622810232b6da5efcd52b1c9b0bd87c62517bf4df25323ca6a0b49d84ec":{"label":"mon.itor.us", "key":"d2aa7164007c5deac8bb73580a6ab0d051f747e801ecd30284eff725d0ffaba2", "notes":""}, "4b78dc0376d07e57d77b4c7318d2f222956adb6ff7360b73e60b8bb8b85f3d11":{"label":"Lamba Probe - forum", "key":"f73906817fddba4d8f816334cb2fd0cd5ae91bc29bce6a69fdd5cf98fc96911f", "notes":""}, "78ca2c85908275d788c2f7dd0306ca5e03b83637bb3812272b697e12e9dbf941":{"label":"MeasureMap", "key":"2385ce9536ebb7863b6a4c8b1f5c428587e4d6420a4bbcd31b935cb00bbd768e", "notes":""}, "4c2c7f0d733b647e6f388c9a4590a2a864cd2de259b66aba9b3cf92bdc3cf9bc":{"label":"NGI - Squillo", "key":"96f20c212be02fb38c8b2dfc83d8e864dd84dcb95297a7fecf9280e1e4dcffe3", "notes":""}, "eaeadf6d36f8ee6916c33b9e5bf480b663dc90c0c7f370ff5a1f2fd998cf1143":{"label":"NGI - F5", "key":"00347769244b208647c24e6a64f8fa4213e97eb2135ecfcb277b341c28616a59", "notes":""}, "19654392222206d60547073209672dde1c743ea371ddc20a2bd8254e561a4ec0":{"label":"CVSdude", "key":"ed0ab5080a29eb1b20927142d21ab8f67b61c2c7b19623bb610af030dfd42c02", "notes":""}, "6b10514d50e745f1dab5a40e8629ecf1a8c78a5d6e3895f3637fb67d2d3f9993":{"label":"Yahoo", "key":"6380a7655cd790d1f1e6f482e92ae04201568ff0cab887e65102e9396df1b86e", "notes":"note"}}, "directLogins":{"eac496e0b1ec75ea403f821fedc7f51f98dac639713ebe577f969f607a8943f5":{"record":"111855cedd650dfcbbce597d764583c6b040df4b71f5fa0161fb8d10514ee48f", "label":"R@cine - WebMail", "favicon":"http://www.racine.ra.it/favicon.ico"}, "ef564a022630d4395a9ecac854f3b127b3518cec362323ccc605079c0749c152":{"record":"1cef440eecea59f47554aa04b94e18c1d9fc761246b911f89a7da72d544cac48", "label":"Amazon sign in", "favicon":"http://www.amazon.com/favicon.ico"}, "4f14b88a4055ff23a00d625382650888ce9284fe869304775e43e3e33ee5bbb6":{"record":"6ad2cda35f97743cfddf2133cdf3142fe6419e683484531f1ef1e67431f44284", "label":"Aruba - hosting", "favicon":"http://hosting.aruba.it/favicon.ico"}, "e94c0d12d1db0badc31a8bbbbc4b08d2065a39f458462bbff9756f7b5eb7fedf":{"record":"741ce1d21839c69db754309b04ce02fbb4104f6cb87572c056ae4af918420700", "label":"Aruba - sql hosting", "favicon":"http://mysql.aruba.it/favicon.ico"}, "7299249153ef93a44e2f248ca3a73badde56e71d70919bb5637093c2abbe2c9a":{"record":"bd5a587bb977a2c728fcd0fa6093dd63a4e62138cf89721115fe45e0396ba5d2", "label":"clipperz.com - blog", "favicon":"http://www.clipperz.com/favicon.ico"}, "66876dbae68778d4c104bc12f01adcb21d47d9eace8db30ef95f74f461afcb59":{"record":"73fb52ed51533657d6ebb020d5026fb4deb601dadce802de58f7fff4b56e1495", "label":"DynDns - clipperz", "favicon":"http://www.dyndns.com/favicon.ico"}, "a60c65030a1797abde3e2089c3e5de9648f66bf71cebf0b58c26e729ad8d6a45":{"record":"5054f0b94cd97610a1bc0ed8671b6fb5b25bf7a5582677059fcaaea75fac27bc", "label":"DynDns - gcsolaroli", "favicon":"http://www.dyndns.com/favicon.ico"}, "08d6c5dff9fed4a2f237c32dd0a93ac46b2c45370d07f56fa76064be3b8fecbf":{"record":"30c4f575799fc6908765fc8b54f4a9a483cb32e12aa89feae545976870a9102e", "label":"GMail - giulio.cesare", "favicon":"http://www.google.com/favicon.ico"}, "9e75e12f0f52f248cc7ae517869dd7b02303037d32d9fb4fa0ab0e013923c304":{"record":"c9dae2b7a60b300008306f5ec731b60050250df8f8ff34f7d9cce92762121b99", "label":"Il manifesto", "favicon":"http://abbonati.ilmanifesto.it/favicon.ico"}, "935bf9553fbcb85b8bd5b98c6901d7cccb2566b395f192cbea71e7822979aaf2":{"record":"f1aac97154a0e52c5e33508afa82df5a9d6dcde24883a240b8c072a3238da0b6", "label":"Imap4All.com - account", "favicon":"http://www.imap4all.com/favicon.ico"}, "9504205ec29b89e6ccd0f3afc7a447d8891da0c71a0222f1860f98a8f8bc6677":{"record":"f1aac97154a0e52c5e33508afa82df5a9d6dcde24883a240b8c072a3238da0b6", "label":"Imap4all.com - WebMail", "favicon":"http://webmail.imap4all.com/favicon.ico"}, "3d8dd32d2290ca98789c914580ac2436ece97234217a07d752726d2ac48a4ebf":{"record":"d34c13773b5d8154355c2605024a1dfaf66279ba0fbe3ac19fc1cbc642278fe4", "label":"YouTube [no]", "favicon":"http://www.youtube.com/favicon.ico"}, "7c4b6b5a16984c43ed6d99b04ddfa7e00b624de729ec8aaa3d0f539fb67587e2":{"record":"c2b99939e40d100218baa3ed1cb2a25a5cf726485b0336a0989b104a94157b5f", "label":"Apple Store - Italia", "favicon":"http://store.apple.com/favicon.ico"}, "0b9a98262b50f0ebae5af077467bc627619738873690238fd61093ce9922c9f9":{"record":"ff79a2282cf246add520a3c06e835cf6ffaaae95067d45e8e2e8f44da2501380", "label":"3nity", "favicon":"http://www.3nity.de/favicon.ico"}, "aadeb3388629cfc3b15954f26cf284f52e084191dcdf75752dc4c53d2006c5be":{"record":"7b2f2a59ebb34b5a49f20b99b546f08b9f4f62cbefdce9699f8ef7e74aeb0552", "label":"ACM Web Account", "favicon":"http://portal.acm.org/favicon.ico"}, "3d21c71f2e284ec76f1ae0bb990b683979918f758635bb7d008150f4d7b1447d":{"record":"b83a6bac0da3a27eb909d34cbad183e77088952f01d8d5321613b7b01635a020", "label":"Adobe - Sign In", "favicon":"http://www.adobe.com/favicon.ico"}, "e61a331c998804d46044d4c2acaf96c2fce806f6549e1e16c7d2334872a70953":{"record":"0424f72608fedc969d64a6d5b4a16dd3ce860a230cd6d87d936439f4dd2aafc7", "label":"Agatra [no]", "favicon":"http://www.agatra.com/favicon.ico"}, "9bcd99564fda778061246439fa098dcc79de75b16c542f61e6de7d36dbaf97dc":{"record":"e5e17c29fd598acb4f4c7d621dbdcb045d4d0cabf7d8a19e24420c440cdc3935", "label":"AIM [no]", "favicon":"http://my.screenname.aol.com/favicon.ico"}, "c7093f4663c6e0eba941c557cb86da83fc68cbea36c922e168d0867e6cabe9fe":{"record":"0dc8d3989d0b35d672c012057d3eb7b111f16e79329e08a9ffb31ac7accbab21", "label":"Bloglines", "favicon":"http://www.bloglines.com/favicon.ico"}, "915f2e9460f6e54c6137f3876f9179fc8d2162c59f26e12899c2db6b0e70a68f":{"record":"85a40a322a59c80cb46519900269dcc7cf6947213d03dfc9371dd1930373a65b", "label":"Bow.it", "favicon":"http://www.bow.it/favicon.ico"}, "779701af1beb2a91735ba1a2e471b948f0d985bb0df256f5e089291ce3405bd2":{"record":"b2836a864ff081b6f053c3f5f13dfb29c81af33d25a316cdd82af747ea71bea0", "label":"GMail - Clipperz", "favicon":"http://www.google.com/favicon.ico"}, "1c300539a98c874d52134b6b5a591172acc00c0947692f3da284447f7d511eaf":{"record":"60308062a1848a301641a74712d220eef191a280ba0a8355992f0e61ed793811", "label":"GMail - feedback", "favicon":"http://www.google.com/favicon.ico"}, "f9dccdf7a98735fd7a6b5d04c09177005c0de14f8f92b04007f06a281ecdf31e":{"record":"30c4f575799fc6908765fc8b54f4a9a483cb32e12aa89feae545976870a9102e", "label":"Blogger", "favicon":"http://www.google.com/favicon.ico"}, "48497a89f3bfd567758977e1c32b4497d28c843880667ee52fa4cfcb53c5f9e4":{"record":"378a790452de46e1079a99eba2e15094a096b418cccd0262b8b20244eb94d2df", "label":"NewsGator", "favicon":"http://www.newsgator.com/favicon.ico"}, "134cd28f150df4f2a089f4807bb7a35fb7ece22ec41244f72e63f8b43637a4cd":{"record":"4b78dc0376d07e57d77b4c7318d2f222956adb6ff7360b73e60b8bb8b85f3d11", "label":"Lambda Probe - forum", "favicon":"http://www.lambdaprobe.org/favicon.ico"}, "2ab6106a81513b70f1ba0d7c5c3ef54fa6f4bcadf01d2eeaa2b31b9299551398":{"record":"78ca2c85908275d788c2f7dd0306ca5e03b83637bb3812272b697e12e9dbf941", "label":"Measure Map", "favicon":"http://alpha.measuremap.com/favicon.ico"}, "53ccdc41b43da9b018847f9faa8effb35e7a6c6e78a54e9ee7816fc02f0ea63b":{"record":"4c2c7f0d733b647e6f388c9a4590a2a864cd2de259b66aba9b3cf92bdc3cf9bc", "label":"NGI - Squillo", "favicon":"http://www.ngi.it/favicon.ico"}, "ca520e7081fba1df3ef79c3d00266cffc8e4567def29d67ae812b7ed6283fb12":{"record":"eaeadf6d36f8ee6916c33b9e5bf480b663dc90c0c7f370ff5a1f2fd998cf1143", "label":"NGI - F5", "favicon":"http://www.ngi.it/favicon.ico"}, "80e63e135d7abd2b2990f42af4f8d1f8e8b1146aed44dc36975061fbf360a983":{"record":"6b10514d50e745f1dab5a40e8629ecf1a8c78a5d6e3895f3637fb67d2d3f9993", "label":"Yahoo! Mail", "favicon":"http://login.yahoo.com/favicon.ico"}}, "preferences":{"preferredLanguage":"en-US"}};
+/* */
+ plainText = {
+ "records": {
+ "1": {
+ "label":"imap4all [no]",
+ "key":"f54b5033d1152456acb67974c45ee6771f8411e300c9533359dfacacf60dcbbd",
+ "notes":""
+ },
+ "2": {
+ "label":"Il manifesto",
+ "key":"6e0ef134503110e72f444e7d102a4b1cc6ae28f2e0b1287c2b1875ff052fc16c",
+ "notes":""
+ },
+ "3": {
+ "label": "OmniGroup applications",
+ "key": "7b432b7dae39ff5951db31947fa721dc012af0da4055760c6df3b02e776ef22c",
+ "notes": "url: http://www.omnigroup.com\n\nLicence owner: Giulio Cesare Solaroli\n\nOmniWeb: EQGP-EMKH-LKWP-MUHQ-OUHL-LDF\nOmniGraffle:\nOmniOutliner:\nOmniDiskSweeper:"
+ },
+ "4": {
+ "label": "R@cine",
+ "key": "57295772c84669b0a224f435e9b75c797ae5999a2d9473ab50f9384ae54f49d6",
+ "notes": ""
+ },
+ "5": {
+ "label": "NewsGator",
+ "key": "6ee16f6932ee02000c49dbcc685c84074b40d7956e5f4bc1100030a0f9a41f1a",
+ "notes": ""
+ },
+ "6": {
+ "label": "GMail - giulio.cesare",
+ "key": "0395efd852b00700bcf78b65350ec15932430df71201d2c53a11b0269b557d1a",
+ "notes": ""
+ },
+ "7": {
+ "label": "GMail - clipperz.com",
+ "key": "90d6ae70d89c8211404b6f9d6c70b6b9c113fff74f474a67b34acd9c1c048d1f",
+ "notes": ""
+ },
+ "8": {
+ "label": "Aruba - hosting",
+ "key": "5c7472d24d57391c63ea99ed1fc9de179d225abd335fa65702018cfea6083d47",
+ "notes": ""
+ },
+ "9": {
+ "label": "Aruba - sql hosting",
+ "key": "f6bd942ac3b0b7065771e5197c7499b345a10f7a4843d00c3ba3809d0ea059dc",
+ "notes": ""
+ },
+ "10": {
+ "label": "Amazon",
+ "key": "1ae022b4d14b642f113703b2a98931bd892dec2da785ab5ff6fc1d0aac7537f1",
+ "notes": ""
+ },
+ "11": {
+ "label": "YouTube [no]",
+ "key": "4c6593d4f6448137939b364b84c81501fadb60f7871fe5fa63c93e97bb5c4648",
+ "notes": ""
+ },
+ "12": {
+ "label": "DynDns - gcsolaroli",
+ "key": "f8ed9e7a3630deed046eda37ebc63ecb4d63668a2f97224d7628fdc53b242467",
+ "notes": ""
+ },
+ "13": {
+ "label": "DynDns - clipperz",
+ "key": "d8bc295177383a523e67b61b166e0ca956ab4c2ee86800559a009d2716064f6d",
+ "notes": ""
+ },
+ "14": {
+ "label": "Bol.it",
+ "key": "cada5dadeebd8d12190954d21f1a944c8799d034f028be195b448935fcf970c7",
+ "notes": ""
+ },
+ "15": {
+ "label": "Freenigma - clipperz.com",
+ "key": "f09cb3790c1110794b834702b8c487c1a42b2508fbe6450a8468477d93790b2e",
+ "notes": ""
+ },
+ "16": {
+ "label": "Freenigma",
+ "key": "4b05738f6faebc147eac5e425054a91d3cc59dd63844e82d1f0864c0ac8efec7",
+ "notes": ""
+ },
+ "17": {
+ "label": "clipperz.com - blog",
+ "key": "9cc24328bbce18e8713962428d8123e309a12f7e1d9537bc252e134501734003",
+ "notes": ""
+ },
+ "18": {
+ "label": "Apple",
+ "key": "75f2651af400629c4e5dd8bcdc3a6c691150d23d6e1a4eb263ff810926d1228f",
+ "notes": ""
+ },
+ "19": {
+ "label": ".mac",
+ "key": "5934ae96d2e01282effb368d9086c2ba5d1d856ad91dd6f04f5bace26a1c0cbe",
+ "notes": ""
+ },
+ "20": {
+ "label": "3nity",
+ "key": "33d84c4a91ab053cbf8115c689ede7e504b81199884de449acc257bea534f57f",
+ "notes": ""
+ },
+ "21": {
+ "label": "ACM",
+ "key": "b4976bb0892baba81d628513d191de100d89acd58efbb07c823a5bb4abe48a7a",
+ "notes": ""
+ },
+ "22": {
+ "label": "Adobe",
+ "key": "d162bc404994a79ec97e0106c3a4edf2f83aca25def130242e11e95e74bd0aaa",
+ "notes": ""
+ },
+ "23": {
+ "label": "Adobe Photoshop Elements 3",
+ "key": "18a62c3c2065399819707322f467ff4be030d7939acbe5182c8194599845c428",
+ "notes": "Photoshop Elements 2:\n1057-4312-5223-2206-9509-6837"
+ },
+ "24": {
+ "label": "Agatra",
+ "key": "c35158a21b2af75d414232b742ab738d042314e00209f8fca94c8c704c891f23",
+ "notes": ""
+ },
+ "25": {
+ "label": "AIM",
+ "key": "8561ac421d845921978387b5e6b362750b57ed08feda8ec12b9378b69f67ceff",
+ "notes": ""
+ },
+ "26": {
+ "label": "Anna Vespignani",
+ "key": "79a970af0d2d30643dc2db4d16757395c1f22c311919036c2a22b7581982144a",
+ "notes": ""
+ },
+ "27": {
+ "label": "Bloglines",
+ "key": "fe81f4df8c42fd81c830f9af408e9b074e77fd430e26d0ee285844fe3b092aec",
+ "notes": ""
+ },
+ "28": {
+ "label": "Bow.it",
+ "key": "64a1a9fec99c9238dc8180a01484a1ccf5f50fcd6e9a95a52b8b49fb9ca00bdc",
+ "notes": ""
+ },
+ "29": {
+ "label": "GMail - feedback",
+ "key": "fad310cb2e6152c3faf78b7183c99f3044f5d31ee364068b80580c271a7784ef",
+ "notes": ""
+ },
+ "30": {
+ "label": "Fineco",
+ "key": "8f99de2635b5dad7987180bc0bff49947eb37cc75d6a5d1ee1f13ed7567465a3",
+ "notes": ""
+ },
+ "31": {
+ "label": "mon.itor.us",
+ "key": "d2aa7164007c5deac8bb73580a6ab0d051f747e801ecd30284eff725d0ffaba2",
+ "notes": ""
+ },
+ "32": {
+ "label": "Lamba Probe - forum",
+ "key": "f73906817fddba4d8f816334cb2fd0cd5ae91bc29bce6a69fdd5cf98fc96911f",
+ "notes": ""
+ },
+ "33": {
+ "label": "MeasureMap",
+ "key": "2385ce9536ebb7863b6a4c8b1f5c428587e4d6420a4bbcd31b935cb00bbd768e",
+ "notes": ""
+ },
+ "34": {
+ "label": "NGI - Squillo",
+ "key": "96f20c212be02fb38c8b2dfc83d8e864dd84dcb95297a7fecf9280e1e4dcffe3",
+ "notes": ""
+ },
+ "35": {
+ "label": "NGI - F5",
+ "key": "00347769244b208647c24e6a64f8fa4213e97eb2135ecfcb277b341c28616a59",
+ "notes": ""
+ },
+ "36": {
+ "label": "CVSdude",
+ "key": "ed0ab5080a29eb1b20927142d21ab8f67b61c2c7b19623bb610af030dfd42c02",
+ "notes": ""
+ },
+ "37": {
+ "label": "Yahoo",
+ "key": "6380a7655cd790d1f1e6f482e92ae04201568ff0cab887e65102e9396df1b86e",
+ "notes": "note"
+ }
+ },
+ "directLogins": {
+ "1": { "record": "1", "label": "R@cine - WebMail", "favicon": "http://www.racine.ra.it/favicon.ico" },
+ "2": { "record": "2", "label": "Amazon sign in", "favicon": "http://www.amazon.com/favicon.ico" },
+ "3": { "record": "3", "label": "Aruba - hosting", "favicon": "http://hosting.aruba.it/favicon.ico" },
+ "4": { "record": "4", "label": "Aruba - sql hosting", "favicon":"http://mysql.aruba.it/favicon.ico" },
+ "5": { "record": "5", "label":"clipperz.com - blog", "favicon":"http://www.clipperz.com/favicon.ico" },
+ "6": { "record":"6", "label":"DynDns - clipperz", "favicon":"http://www.dyndns.com/favicon.ico" },
+ "7": { "record":"7", "label":"DynDns - gcsolaroli", "favicon":"http://www.dyndns.com/favicon.ico" },
+ "8":{"record":"8", "label":"GMail - giulio.cesare", "favicon":"http://www.google.com/favicon.ico" },
+ "9":{"record":"9", "label":"Il manifesto", "favicon":"http://abbonati.ilmanifesto.it/favicon.ico" },
+ "10":{"record":"10", "label":"Imap4All.com - account", "favicon":"http://www.imap4all.com/favicon.ico" },
+ "11":{"record":"12", "label":"Imap4all.com - WebMail", "favicon":"http://webmail.imap4all.com/favicon.ico" },
+ "13":{"record":"13", "label":"YouTube [no]", "favicon":"http://www.youtube.com/favicon.ico" },
+ "14":{"record":"14", "label":"Apple Store - Italia", "favicon":"http://store.apple.com/favicon.ico" },
+ "15":{"record":"15", "label":"3nity", "favicon":"http://www.3nity.de/favicon.ico" },
+ "16":{"record":"16", "label":"ACM Web Account", "favicon":"http://portal.acm.org/favicon.ico" },
+ "17":{"record":"17", "label":"Adobe - Sign In", "favicon":"http://www.adobe.com/favicon.ico" },
+ "18":{"record":"18", "label":"Agatra [no]", "favicon":"http://www.agatra.com/favicon.ico" },
+ "19":{"record":"19", "label":"AIM [no]", "favicon":"http://my.screenname.aol.com/favicon.ico" },
+ "20":{"record":"20", "label":"Bloglines", "favicon":"http://www.bloglines.com/favicon.ico" },
+ "21":{"record":"21", "label":"Bow.it", "favicon":"http://www.bow.it/favicon.ico" },
+ "22":{"record":"22", "label":"GMail - Clipperz", "favicon":"http://www.google.com/favicon.ico" },
+ "23":{"record":"23", "label":"GMail - feedback", "favicon":"http://www.google.com/favicon.ico" },
+ "24":{"record":"24", "label":"Blogger", "favicon":"http://www.google.com/favicon.ico" },
+ "25":{"record":"25", "label":"NewsGator", "favicon":"http://www.newsgator.com/favicon.ico" },
+ "26":{"record":"26", "label":"Lambda Probe - forum", "favicon":"http://www.lambdaprobe.org/favicon.ico" },
+ "27":{"record":"27", "label":"Measure Map", "favicon":"http://alpha.measuremap.com/favicon.ico" },
+ "28":{"record":"28", "label":"NGI - Squillo", "favicon":"http://www.ngi.it/favicon.ico" },
+ "29":{"record":"29", "label":"NGI - F5", "favicon":"http://www.ngi.it/favicon.ico" },
+ "30":{"record":"30", "label":"Yahoo! Mail", "favicon":"http://login.yahoo.com/favicon.ico"}
+ },
+ "preferences":{"preferredLanguage":"en-US"}
+ }
+/* */
+
+//console.profile("encrypt 0.2");
+ encryptedText = Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].encrypt(password, plainText);
+//console.profileEnd();
+//console.profile("decrypt");
+// decryptedText = Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].decrypt(password, encryptedText);
+//console.profileEnd();
+// is(MochiKit.Base.serializeJSON(decryptedText), MochiKit.Base.serializeJSON(plainText), "complex structure encrypted/decrypted");
+
+//console.profile("encrypt 0.3");
+ encryptedText = Clipperz.PM.Crypto.encryptingFunctions.versions['0.3'].encrypt(password, plainText);
+//console.profileEnd();
+ decryptedText = Clipperz.PM.Crypto.encryptingFunctions.versions['0.3'].decrypt(password, encryptedText);
+ is(MochiKit.Base.serializeJSON(decryptedText), MochiKit.Base.serializeJSON(plainText), "complex structure encrypted/decrypted");
+
+
+//#############################################################################
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/Base.html b/frontend/gamma/tests/tests/Clipperz/Crypto/Base.html
new file mode 100644
index 0000000..86fc49a
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/Base.html
@@ -0,0 +1,428 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Functions.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+try {
+ var secretKey;
+ var publicKey;
+ var plainString;
+ var encryptedString;
+
+
+ secretKey = "s3cr37k39";
+ plainString = "The Quick Brown Fox Jumps Over The Lazy Dog";
+ encryptedString = Clipperz.Crypto.Base.encryptUsingSecretKey(secretKey, plainString);
+
+ //-------------------------------------------------------------------------
+ //
+ // Secret key encryption / decryption
+ //
+ is (isUndefinedOrNull(encryptedString), false, "An encrypted string should not be empty");
+ is (plainString, Clipperz.Crypto.Base.decryptUsingSecretKey(secretKey, encryptedString), "I should be able to encrypt and then decrypt safely");
+
+ try {
+ var decryptedText;
+
+ decryptedText = Clipperz.Crypto.Base.decryptUsingSecretKey("anotherKey", encryptedString);
+ ok( false, "It should not be possible to decrypt a text with a different passphrase (decrypted text: " + decryptedText + ")" );
+ } catch (e) {
+ ok( e instanceof Error, "Trying to decrypt a message with the wrong passphrase raised an error" );
+ }
+
+ is (encryptedString == Clipperz.Crypto.Base.encryptUsingSecretKey(secretKey, plainString), false, "Two consecutive encryption of the same text should return different values");
+
+ secretKey = "trustno1";
+ plainString = "59fed719f8959a468de367f77a33a7536d53b8e4d25ed49ccc89a94cd6899da90415623fb73386e9635034fb65ad5f248445a1c66703f760d64a8271ad342b1";
+ encryptedString = Clipperz.Crypto.Base.encryptUsingSecretKey(secretKey, plainString);
+ is (plainString, Clipperz.Crypto.Base.decryptUsingSecretKey(secretKey, encryptedString), "I should be able to encrypt and then decrypt safely");
+
+ secretKey = "trustno1";
+ plainString = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed pede. Curabitur a mi id nisi euismod rutrum. Phasellus gravida. Ut luctus. Praesent quis leo sit amet orci imperdiet malesuada. Aenean molestie mauris euismod odio. Suspendisse ullamcorper facilisis nisl. Fusce vestibulum consectetuer risus. Curabitur ut turpis eget arcu facilisis ultricies. Morbi elementum, erat vitae dictum imperdiet, nisi purus rutrum odio, eget ornare ipsum nisl in tortor. Duis vestibulum, nulla et bibendum volutpat, mauris metus facilisis elit, vel gravida tortor leo at enim. Vivamus pulvinar lorem vitae tortor. Morbi rhoncus suscipit urna. Praesent placerat tempus augue. Fusce varius dui a nisi consequat ultricies. Curabitur at nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.";
+ encryptedString = Clipperz.Crypto.Base.encryptUsingSecretKey(secretKey, plainString);
+ is (plainString, Clipperz.Crypto.Base.decryptUsingSecretKey(secretKey, encryptedString), "I should be able to encrypt and then decrypt safely");
+
+ secretKey = "trustno1";
+ plainString = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed pede. Curabitur a mi id nisi euismod rutrum. Phasellus gravida. Ut luctus. Praesent quis leo sit amet orci imperdiet malesuada. Aenean molestie mauris euismod odio. Suspendisse ullamcorper facilisis nisl. Fusce vestibulum consectetuer risus. Curabitur ut turpis eget arcu facilisis ultricies. Morbi elementum, erat vitae dictum imperdiet, nisi purus rutrum odio, eget ornare ipsum nisl in tortor. Duis vestibulum, nulla et bibendum volutpat, mauris metus facilisis elit, vel gravida tortor leo at enim. Vivamus pulvinar lorem vitae tortor. Morbi rhoncus suscipit urna. Praesent placerat tempus augue. Fusce varius dui a nisi consequat ultricies. Curabitur at nisi. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas./n/n/nMorbi vel leo non justo condimentum convallis. Vestibulum posuere aliquam nunc. Donec magna magna, euismod nec, pharetra fringilla, tristique mattis, turpis. Duis condimentum lacus eu felis. Sed ultricies. Nullam lacinia ante id diam. Ut quis enim. Fusce at felis quis neque vehicula tempor. Sed feugiat sodales sem. Duis cursus massa in ligula. Vestibulum volutpat, risus in ornare porta, tortor orci vestibulum felis, et eleifend risus odio nec eros. Integer lorem turpis, imperdiet eu, tempor eu, ultricies nec, est. Ut congue. Morbi lacinia vehicula pede. Cras neque sapien, feugiat ac, eleifend eget, mattis et, nisl. Morbi at augue vitae massa laoreet gravida./n/n/nSuspendisse vehicula convallis sem. Sed vel urna. Proin dolor diam, malesuada in, aliquet a, sagittis et, magna. Cras at dui eu mi porta fermentum. Donec pharetra purus sed velit. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque euismod ornare neque. In odio nisi, bibendum non, vulputate ut, tincidunt a, ante. Sed risus arcu, tempus laoreet, euismod id, laoreet mollis, arcu. Ut tempor orci in nibh. Suspendisse potenti. Maecenas accumsan augue at nisl. Donec elementum diam nec metus. Sed vitae lacus sed libero varius semper. Aenean hendrerit tristique arcu. Praesent adipiscing ornare purus. Vestibulum quis eros nec risus accumsan laoreet. Duis consequat ante ut turpis. Curabitur aliquam suscipit ligula. Vivamus adipiscing./n/n/nCurabitur facilisis neque sit amet erat. Aliquam odio augue, vulputate lobortis, rutrum ut, tristique id, leo. Vivamus eu magna. Maecenas et libero. Integer porta, lorem at mollis ullamcorper, purus metus vestibulum erat, ut fringilla dui ante id mi. Morbi vitae ligula. Praesent ornare sapien sed massa. Mauris rhoncus fermentum dolor. Mauris gravida, justo et mollis malesuada, dolor erat fermentum nulla, vel suscipit leo ligula vel augue. Praesent magna enim, dignissim sed, aliquet quis, fermentum viverra, nisi. Vivamus condimentum, nisi quis posuere viverra, enim nunc faucibus lectus, mollis aliquam ipsum enim vel lacus. Suspendisse eget ligula. Aliquam ut metus et justo consectetuer ornare. Donec dapibus tristique pede. Vestibulum interdum ultricies tortor./n/n/nNunc nonummy dictum tortor. Quisque at elit a arcu nonummy elementum. Quisque auctor, risus et sodales euismod, turpis tellus consectetuer ante, quis egestas justo enim quis mi. Nunc fermentum sodales felis. Vivamus odio mi, dignissim vitae, auctor nec, tempus eget, lacus. Ut sapien massa, hendrerit eget, sagittis at, eleifend condimentum, arcu. Curabitur purus orci, facilisis vel, dapibus id, varius rutrum, tortor. Fusce accumsan viverra sem. Quisque tincidunt venenatis risus. Sed tortor justo, volutpat malesuada, sodales ut, vehicula id, magna. Nunc placerat, nibh et imperdiet ultricies, urna nulla luctus sapien, et porta mi odio ac neque. Morbi dignissim. Sed risus pede, adipiscing gravida, pharetra sit amet, convallis non, orci. Morbi adipiscing mauris id massa. Nullam fermentum. Suspendisse eget est";
+ encryptedString = Clipperz.Crypto.Base.encryptUsingSecretKey(secretKey, plainString);
+ is (plainString, Clipperz.Crypto.Base.decryptUsingSecretKey(secretKey, encryptedString), "I should be able to encrypt and then decrypt safely");
+
+// secretKey = "trustno1";
+// plainString = "{}";
+// plainString = "{'tags': {'personal': ['ref_1', 'ref_3'], 'business': ['ref_2', 'ref_3']}, 'records': {'ref_1': {'label': 'record_1', 'key': 'key_1'}, 'ref_2': {'label': 'record_2', 'key': 'key_2'}, 'ref_3': {'label': 'record_3', 'key': 'key_3'}}} ";
+// plainString = "{'tags': {}, 'records': {'07a5a92fcb334f757998ba14f3251f126d038318b3ac5e584bd712804c548084': {'label': 'Un bel record', 'key': '2a3f261c20a6a98dcc82b13fba013130b759f20602b4b13c5760879e087482a4'}}}";
+// encryptedString = Clipperz.Crypto.Base.encryptUsingSecretKey(secretKey, plainString);
+// is(encryptedString, "{}", "encrypted value");
+
+
+// secretKey = "trustno1";
+// encryptedString = "0d43a4544424ffa519f2e43b7a46f703884fd94ff9879479563f6f252a573b253d3e77bc4f5f30f17bd11d2907718921ab8c9e1faccbe4314793fa323eb85eaf1bfbce5f7deea601e15b781782181cbff3c649dafef39abb70e8573e4f9be220f2286b01c3bd51d5c4a79b9d44a27be3b0994667302e301ca3dc074fb1bc7abc03d12b9e58ba0249435a120858c96e8ae99570718541499ab958a8fb92b63390be070ff61fc6ef107061693ab14c1915118cc6671ab7cf99b9cca553d6b5a7c314bffcd933e0a59f056d842a47cfe8571110b4764c5225443210d99b43b80a23c20fe953de3e1329d72cfb20139fe1ca";
+// plainString = Clipperz.Crypto.Base.decryptUsingSecretKey(secretKey, encryptedString);
+// is(plainString, "{}", "decrypted value");
+
+ //-------------------------------------------------------------------------
+ //
+ // Java secret key encryption / JavaScript decryption
+ //
+ secretKey = "s3cr37k39";
+ plainString = "The Quick Brown Fox Jumps Over The Lazy Dog";
+ encryptedString = "9be538c3dde4dfab9384c0ef71dc624299fbbe71be8d1fe8991fd6cae88a883cf459d7cd56913a2b69815782cf74d7ce5c2c08034661f7f8aa59cf420e913086896840ebb45102d44d733d32de2a7dc8";
+ is (plainString, Clipperz.Crypto.Base.decryptUsingSecretKey(secretKey, encryptedString), "I should be able to encrypt and then decrypt safely");
+
+ //-------------------------------------------------------------------------
+ //
+ // Public key encryption -> Private key decryption
+ //
+ {
+ var cleanKey;
+ var t1, t2;
+/*
+ //
+ // 128
+ //
+ cleanKey = "248d6a61d20638b8e5c026930c3e6039"; // a33ce45964ff2167f6ecedd419db06c1";
+ publicKey = Clipperz.Crypto.Base.publicKeyWithValues(
+ "10001",
+ "202700adbd85e2d7182720c3a0ee19c1",
+ "30db31542ace0f7d37a629ee5eba28cb"
+ );
+ encryptedString = Clipperz.Crypto.Base.encryptUsingPublicKey(publicKey, cleanKey);
+
+ is (isUndefinedOrNull(encryptedString), false, "An encrypted string is not empty - PUBLIC 128");
+ is (cleanKey, Clipperz.Crypto.Base.decryptUsingPrivateKey(publicKey, encryptedString), "I can encrypt and then decrypt safely - PUBLIC 128");
+ isnt (cleanKey, Clipperz.Crypto.Base.decryptUsingPublicKey(publicKey, encryptedString), "I should not be able to decrypt using again th public key - PUBLIC 128");
+*/
+/*
+ //
+ // 256
+ //
+ cleanKey = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1";
+ cleanKey = "a3c2863242653caf566b02d8be5d6eb6c816ac212378bcec7ff2bdce8e2ec709";
+ publicKey = Clipperz.Crypto.Base.publicKeyWithValues(
+ "10001",
+ "8064edb1f26944f6bec2b68789db7ffd08b074d0953b76feca71dc8265c60e9",
+ "2687f5ac6c70f9cab32fcbded7059502f4c7cc95fc3e09a560c68975ac4bf5e3"
+ );
+ encryptedString = Clipperz.Crypto.Base.encryptUsingPublicKey(publicKey, cleanKey);
+
+ is (isUndefinedOrNull(encryptedString), false, "An encrypted string is not empty - PUBLIC 256");
+ is (cleanKey, Clipperz.Crypto.Base.decryptUsingPrivateKey(publicKey, encryptedString), "I can encrypt and then decrypt safely - PUBLIC 256");
+ isnt (cleanKey, Clipperz.Crypto.Base.decryptUsingPublicKey(publicKey, encryptedString), "I should not be able to decrypt using again th public key - PUBLIC 256");
+*/
+/*
+ //
+ // 512
+ //
+ cleanKey = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1";
+ publicKey = Clipperz.Crypto.Base.publicKeyWithValues(
+ "10001",
+ "59fed719f8959a468de367f77a33a7536d53b8e4d25ed49ccc89a94cd6899da90415623fb73386e9635034fb65ad5f248445a1c66703f760d64a8271ad342b1",
+ "8de7066f67be16fcacd05d319b6729cd85fe698c07cec504776146eb7a041d9e3cacbf0fcd86441981c0083eed1f8f1b18393f0b186e47ce1b7b4981417b491"
+ );
+t1 = new Date().getTime();
+ encryptedString = Clipperz.Crypto.Base.encryptUsingPublicKey(publicKey, cleanKey);
+t2 = new Date().getTime();
+//is("Encrypting with public key (512)", (t2 - t1));
+
+ is (isUndefinedOrNull(encryptedString), false, "An encrypted string is not empty - PUBLIC 512");
+t1 = new Date().getTime();
+ is (cleanKey, Clipperz.Crypto.Base.decryptUsingPrivateKey(publicKey, encryptedString), "I can encrypt and then decrypt safely - PUBLIC 512");
+t2 = new Date().getTime();
+//is("Decrypting with private key (512)", (t2 - t1));
+ isnt (cleanKey, Clipperz.Crypto.Base.decryptUsingPublicKey(publicKey, encryptedString), "I should not be able to decrypt using again th public key - PUBLIC 512");
+*/
+/*
+ //
+ // 1024
+ //
+ cleanKey = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1";
+ publicKey = Clipperz.Crypto.Base.publicKeyWithValues(
+ "10001",
+ "12e8da920d4599458e84ec5ef1656161807f427d05eb79182b7418259d6f6c14364d1f5caf9130c8d9d9d6ea71d1bdbc87781a46a16bcb9e672814fed3b9c96ddffe0a1b0955ae68055c8f92fef518a04fc32a2ea8390e617cc5556a251f9ae9eee70a32e579cb3e9f298848a9b3aaf634f5930ffbf74473f7cb6c0cefee1751",
+ "130ebebd67b16a9ab2c53a437badbf8f01a80c750095a7fcfe95742c3d5ed1abb318babc5cb5d9350fee4da65ee074f65e1758117e6945f0fcfc8137528053ce9d1da8618890dee24e5e0bf8c87795bb1d09eddd544640824ee0dd0ea9fd908d27b0f8a1ae5c37f3647fbf2f5795500ad76c195b3387d0458a8f51b701472301"
+ );
+t1 = new Date().getTime();
+ encryptedString = Clipperz.Crypto.Base.encryptUsingPublicKey(publicKey, cleanKey);
+t2 = new Date().getTime();
+is("Encrypting with public key (1024)", (t2 - t1));
+
+ is (isUndefinedOrNull(encryptedString), false, "An encrypted string is not empty - PUBLIC 1024");
+t1 = new Date().getTime();
+ is (cleanKey, Clipperz.Crypto.Base.decryptUsingPrivateKey(publicKey, encryptedString), "I can encrypt and then decrypt safely - PUBLIC 1024");
+t2 = new Date().getTime();
+is("Decrypting with private key (1024)", (t2 - t1));
+ isnt (cleanKey, Clipperz.Crypto.Base.decryptUsingPublicKey(publicKey, encryptedString), "I should not be able to decrypt using again th public key - PUBLIC 1024");
+*/
+/*
+ //
+ // 2048
+ //
+ cleanKey = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1";
+ publicKey = Clipperz.Crypto.Base.publicKeyWithValues(
+ "10001",
+ "409c6fe2b6474762b5c07f4e55ef80d174814dc1fb0fb58e979691116fb3dc433f759ff8a88d1a0f0666862b0b3758c54b7355fa87ee827369381e1f97c5d74944e032c7186b51a956fb49d6deb3aee0b2c7e65fc53bfd46d217764850667ed0363de143f3f3d06d5a0018693ad3dacdf78a18d037ceeccb7508776f27b30852b8b505666a8dca5bfbb455d2f85918f8b5295061c97673c78802c5f5cf4581c7215dc32af8dfb6fc10e9ba51fb5a88abab94157ccecf615e104a91a45e9bee072fe7b388344c1bbad4a8f7d5daeccbadf778d59eff2a491a067bba5343c5a094c61b575fe367ecfcc01c3d208c2f8c05b9496a929b2b72e70160d07d07f248f1",
+ "9800012b1e533c2c28187424e1289fd4f7fe67487058f5ac7f27f18476c6c93db20b6d2c63d04ff310c1e7211cf8014adc006176529abc53fd1780274fc2629cf51d627c7465c3cbf4f110c3560e2128b97c4ea8a431f0b2a326fc31899790515ad45874ca75c68ee6695558736490ea895d598b8525bccab3156104d360b115ae25e99e9d899a2219136bad0336eeee0c6d725aa9c3b6b923c1ad95a9057b9deb7b563e05614acc800d9d8ec5de405d74feea722c5146feb80829508180ab5c80bf792b83f07c04c73ce0b3cf0d9f74aa92a4704819d103e58f5d4b8ca750148ba1cbab8eb55f92775b18da427c3a0b592809f3853274841a44b7129ec6a623"
+ );
+t1 = new Date().getTime();
+ encryptedString = Clipperz.Crypto.Base.encryptUsingPublicKey(publicKey, cleanKey);
+t2 = new Date().getTime();
+is("Encrypting with public key (2048)", (t2 - t1));
+
+ is (isUndefinedOrNull(encryptedString), false, "An encrypted string is not empty - PUBLIC 2048");
+t1 = new Date().getTime();
+ is (cleanKey, Clipperz.Crypto.Base.decryptUsingPrivateKey(publicKey, encryptedString), "I can encrypt and then decrypt safely - PUBLIC 2048");
+t2 = new Date().getTime();
+is("Decrypting with private key (2048)", (t2 - t1));
+ isnt (cleanKey, Clipperz.Crypto.Base.decryptUsingPublicKey(publicKey, encryptedString), "I should not be able to decrypt using again th public key - PUBLIC 2048");
+*/
+ }
+
+ //-------------------------------------------------------------------------
+ //
+ // Private key encryption -> Public key decryption
+ //
+ {
+ var cleanKey;
+ var t1, t2;
+/*
+ //
+ // 128
+ //
+ cleanKey = "248d6a61d20638b8e5c026930c3e6039"; // a33ce45964ff2167f6ecedd419db06c1";
+ publicKey = Clipperz.Crypto.Base.publicKeyWithValues(
+ "10001",
+ "202700adbd85e2d7182720c3a0ee19c1",
+ "30db31542ace0f7d37a629ee5eba28cb"
+ );
+ encryptedString = Clipperz.Crypto.Base.encryptUsingPrivateKey(publicKey, cleanKey);
+
+ is (isUndefinedOrNull(encryptedString), false, "An encrypted string is not empty - PRIVATE 128");
+ is (cleanKey, Clipperz.Crypto.Base.decryptUsingPublicKey(publicKey, encryptedString), "I can encrypt and then decrypt safely - PRIVATE 128");
+ isnt (cleanKey, Clipperz.Crypto.Base.decryptUsingPrivateKey(publicKey, encryptedString), "I should not be able to decrypt using again the private key - PRIVATE 128");
+*/
+/*
+ //
+ // 256
+ //
+ cleanKey = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1";
+ cleanKey = "a3c2863242653caf566b02d8be5d6eb6c816ac212378bcec7ff2bdce8e2ec709";
+ publicKey = Clipperz.Crypto.Base.publicKeyWithValues(
+ "10001",
+ "8064edb1f26944f6bec2b68789db7ffd08b074d0953b76feca71dc8265c60e9",
+ "2687f5ac6c70f9cab32fcbded7059502f4c7cc95fc3e09a560c68975ac4bf5e3"
+ );
+ encryptedString = Clipperz.Crypto.Base.encryptUsingPrivateKey(publicKey, cleanKey);
+
+ is (isUndefinedOrNull(encryptedString), false, "An encrypted string is not empty - PRIVATE 256");
+ is (cleanKey, Clipperz.Crypto.Base.decryptUsingPublicKey(publicKey, encryptedString), "I can encrypt and then decrypt safely - PRIVATE 256");
+ isnt (cleanKey, Clipperz.Crypto.Base.decryptUsingPrivateKey(publicKey, encryptedString), "I should not be able to decrypt using again the private key - PRIVATE 256");
+*/
+/*
+ //
+ // 512
+ //
+ cleanKey = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1";
+ publicKey = Clipperz.Crypto.Base.publicKeyWithValues(
+ "10001",
+ "59fed719f8959a468de367f77a33a7536d53b8e4d25ed49ccc89a94cd6899da90415623fb73386e9635034fb65ad5f248445a1c66703f760d64a8271ad342b1",
+ "8de7066f67be16fcacd05d319b6729cd85fe698c07cec504776146eb7a041d9e3cacbf0fcd86441981c0083eed1f8f1b18393f0b186e47ce1b7b4981417b491"
+ );
+t1 = new Date().getTime();
+ encryptedString = Clipperz.Crypto.Base.encryptUsingPrivateKey(publicKey, cleanKey);
+t2 = new Date().getTime();
+//is("Encrypting with private key (512)", (t2 - t1));
+
+ is (isUndefinedOrNull(encryptedString), false, "An encrypted string is not empty - PRIVATE 512");
+t1 = new Date().getTime();
+ is (cleanKey, Clipperz.Crypto.Base.decryptUsingPublicKey(publicKey, encryptedString), "I can encrypt and then decrypt safely - PRIVATE 512");
+t2 = new Date().getTime();
+//is("Decrypting with public key (512)", (t2 - t1));
+ isnt (cleanKey, Clipperz.Crypto.Base.decryptUsingPrivateKey(publicKey, encryptedString), "I should not be able to decrypt using again th public key - PRIVATE 512");
+*/
+/*
+ //
+ // 1024
+ //
+ cleanKey = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1";
+ publicKey = Clipperz.Crypto.Base.publicKeyWithValues(
+ "10001",
+ "12e8da920d4599458e84ec5ef1656161807f427d05eb79182b7418259d6f6c14364d1f5caf9130c8d9d9d6ea71d1bdbc87781a46a16bcb9e672814fed3b9c96ddffe0a1b0955ae68055c8f92fef518a04fc32a2ea8390e617cc5556a251f9ae9eee70a32e579cb3e9f298848a9b3aaf634f5930ffbf74473f7cb6c0cefee1751",
+ "130ebebd67b16a9ab2c53a437badbf8f01a80c750095a7fcfe95742c3d5ed1abb318babc5cb5d9350fee4da65ee074f65e1758117e6945f0fcfc8137528053ce9d1da8618890dee24e5e0bf8c87795bb1d09eddd544640824ee0dd0ea9fd908d27b0f8a1ae5c37f3647fbf2f5795500ad76c195b3387d0458a8f51b701472301"
+ );
+t1 = new Date().getTime();
+ encryptedString = Clipperz.Crypto.Base.encryptUsingPrivateKey(publicKey, cleanKey);
+t2 = new Date().getTime();
+is("Encrypting with private key (1024)", (t2 - t1));
+
+ is (isUndefinedOrNull(encryptedString), false, "An encrypted string is not empty - PRIVATE 1024");
+t1 = new Date().getTime();
+ is (cleanKey, Clipperz.Crypto.Base.decryptUsingPublicKey(publicKey, encryptedString), "I can encrypt and then decrypt safely - PRIVATE 1024");
+t2 = new Date().getTime();
+is("Decrypting with public key (1024)", (t2 - t1));
+ isnt (cleanKey, Clipperz.Crypto.Base.decryptUsingPrivateKey(publicKey, encryptedString), "I should not be able to decrypt using again th public key - PRIVATE 1024");
+*/
+/*
+ //
+ // 2048
+ //
+ cleanKey = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1";
+ publicKey = Clipperz.Crypto.Base.publicKeyWithValues(
+ "10001",
+ "409c6fe2b6474762b5c07f4e55ef80d174814dc1fb0fb58e979691116fb3dc433f759ff8a88d1a0f0666862b0b3758c54b7355fa87ee827369381e1f97c5d74944e032c7186b51a956fb49d6deb3aee0b2c7e65fc53bfd46d217764850667ed0363de143f3f3d06d5a0018693ad3dacdf78a18d037ceeccb7508776f27b30852b8b505666a8dca5bfbb455d2f85918f8b5295061c97673c78802c5f5cf4581c7215dc32af8dfb6fc10e9ba51fb5a88abab94157ccecf615e104a91a45e9bee072fe7b388344c1bbad4a8f7d5daeccbadf778d59eff2a491a067bba5343c5a094c61b575fe367ecfcc01c3d208c2f8c05b9496a929b2b72e70160d07d07f248f1",
+ "9800012b1e533c2c28187424e1289fd4f7fe67487058f5ac7f27f18476c6c93db20b6d2c63d04ff310c1e7211cf8014adc006176529abc53fd1780274fc2629cf51d627c7465c3cbf4f110c3560e2128b97c4ea8a431f0b2a326fc31899790515ad45874ca75c68ee6695558736490ea895d598b8525bccab3156104d360b115ae25e99e9d899a2219136bad0336eeee0c6d725aa9c3b6b923c1ad95a9057b9deb7b563e05614acc800d9d8ec5de405d74feea722c5146feb80829508180ab5c80bf792b83f07c04c73ce0b3cf0d9f74aa92a4704819d103e58f5d4b8ca750148ba1cbab8eb55f92775b18da427c3a0b592809f3853274841a44b7129ec6a623"
+ );
+t1 = new Date().getTime();
+ encryptedString = Clipperz.Crypto.Base.encryptUsingPrivateKey(publicKey, cleanKey);
+t2 = new Date().getTime();
+is("Encrypting with private key (2048)", (t2 - t1));
+
+ is (isUndefinedOrNull(encryptedString), false, "An encrypted string is not empty - PRIVATE 2048");
+t1 = new Date().getTime();
+ is (cleanKey, Clipperz.Crypto.Base.decryptUsingPublicKey(publicKey, encryptedString), "I can encrypt and then decrypt safely - PRIVATE 2048");
+t2 = new Date().getTime();
+is("Decrypting with public key (2048)", (t2 - t1));
+ isnt (cleanKey, Clipperz.Crypto.Base.decryptUsingPrivateKey(publicKey, encryptedString), "I should not be able to decrypt using again th public key - PRIVATE 2048");
+*/
+ }
+
+ var originalMessage;
+ var processedMessage;
+ var expectedResult;
+
+ //-------------------------------------------------------------------------
+ //
+ // Hash SHA-256
+ //
+
+ originalMessage = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";
+ expectedResult = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1";
+ processedMessage = Clipperz.Crypto.Base.computeHashValue(originalMessage);
+ is(processedMessage, expectedResult, "");
+
+ originalMessage = "";
+ expectedResult = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
+ processedMessage = Clipperz.Crypto.Base.computeHashValue(originalMessage);
+ is(processedMessage, expectedResult, "");
+
+ originalMessage = "abc";
+ expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
+ processedMessage = Clipperz.Crypto.Base.computeHashValue(originalMessage);
+ is(processedMessage, expectedResult, "");
+
+ originalMessage = "message digest";
+ expectedResult = "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650";
+ processedMessage = Clipperz.Crypto.Base.computeHashValue(originalMessage);
+ is(processedMessage, expectedResult, "");
+
+ originalMessage = "secure hash algorithm";
+ expectedResult = "f30ceb2bb2829e79e4ca9753d35a8ecc00262d164cc077080295381cbd643f0d";
+ processedMessage = Clipperz.Crypto.Base.computeHashValue(originalMessage);
+ is(processedMessage, expectedResult, "");
+
+ originalMessage = "SHA256 is considered to be safe";
+ expectedResult = "6819d915c73f4d1e77e4e1b52d1fa0f9cf9beaead3939f15874bd988e2a23630";
+ processedMessage = Clipperz.Crypto.Base.computeHashValue(originalMessage);
+ is(processedMessage, expectedResult, "");
+
+ originalMessage = "For this sample, this 63-byte string will be used as input data";
+ expectedResult = "f08a78cbbaee082b052ae0708f32fa1e50c5c421aa772ba5dbb406a2ea6be342";
+ processedMessage = Clipperz.Crypto.Base.computeHashValue(originalMessage);
+ is(processedMessage, expectedResult, "");
+
+ originalMessage = "This is exactly 64 bytes long, not counting the terminating byte";
+ expectedResult = "ab64eff7e88e2e46165e29f2bce41826bd4c7b3552f6b382a9e7d3af47c245f8";
+ processedMessage = Clipperz.Crypto.Base.computeHashValue(originalMessage);
+ is(processedMessage, expectedResult, "");
+
+ originalMessage = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut urna diam, vulputate quis, tempus vel, pretium in, mauris. Mauris aliquet sem a elit. Nunc molestie rutrum sem.";
+ expectedResult = "528059709af4087fb8cd4427e291d89f24d8c0429b2a3b6fd152c32ce5b4680f";
+ processedMessage = Clipperz.Crypto.Base.computeHashValue(originalMessage);
+ is(processedMessage, expectedResult, "");
+
+ //-------------------------------------------------------------------------
+ //
+ // Hash MD5
+ //
+ originalMessage = "59fed719f8959a468de367f77a33a7536d53b8e4d25ed49ccc89a94cd6899da9";
+ expectedResult = "fde790d7da7d0d54a8db4ac500f1bbdb";
+ processedMessage = Clipperz.Crypto.Base.computeMD5HashValue(originalMessage);
+ is(processedMessage, expectedResult, "");
+
+
+
+
+ //-------------------------------------------------------------------------
+ //
+ // Random seed
+ //
+ var randomSeed;
+
+ randomSeed = Clipperz.Crypto.Base.generateRandomSeed();
+ is(randomSeed.length, 64, "");
+
+ ok(randomSeed != Clipperz.Crypto.Base.generateRandomSeed(), "");
+
+//#############################################################################
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/BigInt.html b/frontend/gamma/tests/tests/Clipperz/Crypto/BigInt.html
new file mode 100644
index 0000000..bdb0cbc
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/BigInt.html
@@ -0,0 +1,478 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Functions.js'></script>
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+try {
+ var bigInt_1;
+ var bigInt_2;
+ var result;
+ var expectedResult;
+
+ //
+ // Constructur and equality test
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("110");
+ is (bigInt_1.equals(bigInt_1), true, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("110");
+ bigInt_2 = new Clipperz.Crypto.BigInt("110", 10);
+ is (bigInt_1.equals(bigInt_2), true, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("110");
+ bigInt_2 = new Clipperz.Crypto.BigInt(110);
+ is (bigInt_1.equals(bigInt_2), true, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt(6);
+ bigInt_2 = new Clipperz.Crypto.BigInt("110", 2);
+ is (bigInt_1.equals(bigInt_2), true, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt(6);
+ bigInt_2 = new Clipperz.Crypto.BigInt("110", 3);
+ is (bigInt_1.equals(bigInt_2), false, "");
+
+
+ //
+ // Addition test
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt(6);
+ bigInt_2 = new Clipperz.Crypto.BigInt(110);
+ result = bigInt_1.add(bigInt_2);
+ expectedResult = new Clipperz.Crypto.BigInt(116);
+ is (result.equals(expectedResult), true, "");
+ is (result.equals(Clipperz.Crypto.BigInt.add(bigInt_1, bigInt_2)), true, "instance method === static function");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt(6);
+ result = bigInt_1.add(6);
+ expectedResult = new Clipperz.Crypto.BigInt(12);
+ is (result.equals(expectedResult), true, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("16161616161616161616161616161616161616161616161616161");
+ bigInt_2 = new Clipperz.Crypto.BigInt("42424242424242424242424242424242424242424242424242424");
+ result = bigInt_1.add(bigInt_2);
+ expectedResult = new Clipperz.Crypto.BigInt("58585858585858585858585858585858585858585858585858585");
+ is (result.equals(expectedResult), true, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("16161616161616161616161616161616161616161616161616161");
+ bigInt_2 = new Clipperz.Crypto.BigInt("42424242424242424242424242424242424242424242424242424");
+ result = bigInt_1.add(bigInt_2);
+ expectedResult = new Clipperz.Crypto.BigInt("58585858585858585858585851585858585858585858585858585");
+ is (result.equals(expectedResult), false, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("86161616161616161616161616161616161616161616161616161");
+ bigInt_2 = new Clipperz.Crypto.BigInt("42424242424242424242424242424242424242424242424242424");
+ result = bigInt_1.add(bigInt_2);
+ expectedResult = new Clipperz.Crypto.BigInt("128585858585858585858585858585858585858585858585858585");
+ is (result.equals(expectedResult), true, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt( "6541652165410321654063516540621063540654" +
+ "0654065106540654165416521654103216540635" +
+ "1654062106354065406540651065406541");
+ bigInt_2 = new Clipperz.Crypto.BigInt( "3046540351035403510354035103510351351351" +
+ "0351350435103213540634132135401351035403" +
+ "5403540354103540");
+ result = bigInt_1.add(bigInt_2);
+ expectedResult = new Clipperz.Crypto.BigInt( "6541652165410321657110056891656467051008" +
+ "1005100210054167675767872089206430081269" +
+ "2975416119864419441944191419510081");
+ is (result.equals(expectedResult), true, "");
+
+
+ //
+ // Moltiplication test
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt(6);
+ bigInt_2 = new Clipperz.Crypto.BigInt(110);
+ result = bigInt_1.multiply(bigInt_2);
+ expectedResult = new Clipperz.Crypto.BigInt(660);
+ is (result.equals(expectedResult), true, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt(6);
+ result = bigInt_1.multiply(5);
+ expectedResult = new Clipperz.Crypto.BigInt(30);
+ is (result.equals(expectedResult), true, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt( "5465465165465465132743540354354032135463" +
+ "5435135403513516843052413543054035");
+ bigInt_2 = new Clipperz.Crypto.BigInt( "3543513543543213543032135435413054365430" +
+ "5130513540351354354305435403");
+ result = bigInt_1.multiply(bigInt_2);
+ expectedResult = new Clipperz.Crypto.BigInt( "1936694983559052629352223965314822970014" +
+ "6364423657014976098029153153101751605574" +
+ "5077086464435601381095664357540911830059" +
+ "9503335163757031001105");
+ is (result.equals(expectedResult), true, "");
+
+ //
+ // Module test
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt(106);
+ bigInt_2 = new Clipperz.Crypto.BigInt(10);
+ result = bigInt_1.module(bigInt_2);
+ expectedResult = new Clipperz.Crypto.BigInt(6);
+ is (result.equals(expectedResult), true, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt(106);
+ result = bigInt_1.module(10);
+ expectedResult = new Clipperz.Crypto.BigInt(6);
+ is (result.equals(expectedResult), true, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt( "5465465465468468465468463541358438543513" +
+ "8543135435135423545624354235123512531235" +
+ "1356463543840351351305135435121354305413" +
+ "543");
+
+
+ bigInt_2 = new Clipperz.Crypto.BigInt( "3543543213543213540543545463542354385768" +
+ "512584354354215");
+ result = bigInt_1.module(bigInt_2);
+ expectedResult = new Clipperz.Crypto.BigInt("52689987206612998786765715819079250963638640081836513");
+ is (result.equals(expectedResult), true, "");
+
+ //
+ // Power (Module) test
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt(6);
+ bigInt_2 = new Clipperz.Crypto.BigInt(3);
+ result = bigInt_1.powerModule(bigInt_2, new Clipperz.Crypto.BigInt(1000));
+ expectedResult = new Clipperz.Crypto.BigInt(216);
+ is (result.equals(expectedResult), true, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt(6);
+ result = bigInt_1.powerModule(3, 1000);
+ expectedResult = new Clipperz.Crypto.BigInt(216);
+ is (result.equals(expectedResult), true, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("354354354354687638546846846846846576876468746846846846");
+ bigInt_2 = new Clipperz.Crypto.BigInt("354");
+ result = bigInt_1.powerModule(bigInt_2, new Clipperz.Crypto.BigInt("3543541354354354354354351354354351354354354354354354"));
+ expectedResult = new Clipperz.Crypto.BigInt("1957028940698171231089373321334263118681605242465644");
+ is (result.equals(expectedResult), true, "");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("e0f6c73cf1d3715a0d77dc3a4eb9c66c01d913c91bc22d9672d83958445424a1", 16);
+// is(bigInt_1.toString(16), "e0f6c73cf1d3715a0d77dc3a4eb9c66c01d913c91bc22d9672d83958445424a1", "IE bug");
+ is(bigInt_1.asString(16), "e0f6c73cf1d3715a0d77dc3a4eb9c66c01d913c91bc22d9672d83958445424a1", "fix for IE bug");
+
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("000108cbbacda1f03ea9360301045434ec7d82ba150936df08a229cbb4832ce1", 16);
+ is(bigInt_1.asString(16, 64), "000108cbbacda1f03ea9360301045434ec7d82ba150936df08a229cbb4832ce1", "fix to ensure the string representation has a minimum fixed length");
+
+/*
+ //
+ // Comparison
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("0", 10);
+ bigInt_2 = new Clipperz.Crypto.BigInt("0", 10);
+ is (bigInt_1.equals(bigInt_2), true, "bigInt(0) = bigInt(0)");
+ is (bigInt_1.equals(0), true, "bigInt(0) = 0");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("000108cbbacda1f03ea9360301045434ec7d82ba150936df08a229cbb4832ce1", 16);
+ is (bigInt_1.equals(bigInt_2), false, "bigInt(xxxxxx) != bigInt(0)");
+ is (bigInt_1.equals(0), false, "bigInt(xxxxx) != 0");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("000108cbbacda1f03ea9360301045434ec7d82ba150936df08a229cbb4832ce1", 16);
+ bigInt_2 = new Clipperz.Crypto.BigInt("0", 16);
+ is(bigInt_1.compare(bigInt_2), 1, "bigInt(xxxxxx) > bigInt(0)");
+ is(bigInt_2.compare(bigInt_1), -1, "bigInt(0) < bigInt(xxxx)");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("000108cbbacda1f03ea9360301045434ec7d82ba150936df08a229cbb4832ce1", 16);
+ bigInt_2 = new Clipperz.Crypto.BigInt("05", 16);
+ is(bigInt_1.compare(bigInt_2), 1, "bigInt(xxxxxx) > bigInt(05)");
+ is(bigInt_2.compare(bigInt_1), -1, "bigInt(05) < bigInt(xxxx)");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("-10", 10);
+ bigInt_2 = new Clipperz.Crypto.BigInt("10", 10);
+ is(bigInt_1.equals(bigInt_2), true, "bigInt(-10) - bigInt(10). No negative number are managed");
+
+ //
+ // XOR
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ bigInt_2 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ result = bigInt_1.xor(bigInt_2);
+ expectedResult = new Clipperz.Crypto.BigInt(0);
+ is(result.asString(16), expectedResult.asString(16), "a xor a = 0");
+
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ bigInt_2 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b935ca495991b7852b855", 16);
+ result = bigInt_1.xor(bigInt_2);
+ expectedResult = new Clipperz.Crypto.BigInt('295147905179352825856');
+ is(result.asString(16), expectedResult.asString(16), "single bit difference");
+
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("01", 16);
+ bigInt_2 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b935ca495991b7852b855", 16);
+ result = bigInt_1.xor(bigInt_2);
+ expectedResult = new Clipperz.Crypto.BigInt('102987336249554097029535212322581322789799900648198034993674544906295017912404');
+ is(result.asString(16), expectedResult.asString(16), "01 xor value");
+
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ bigInt_2 = new Clipperz.Crypto.BigInt("f3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ result = bigInt_1.xor(bigInt_2);
+ expectedResult = new Clipperz.Crypto.BigInt('7237005577332262213973186563042994240829374041602535252466099000494570602496');
+ is(result.asString(16), expectedResult.asString(16), "first bit difference xor");
+
+
+ //
+ // isBitSet
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("ff", 16);
+ result = bigInt_1.isBitSet(1);
+ expectedResult = true;
+ is(result, expectedResult, "'ff'.isBitSet(1)");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("f0", 16);
+ result = bigInt_1.isBitSet(1);
+ expectedResult = false;
+ is(result, expectedResult, "'f0'.isBitSet(1)");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("f0", 16);
+ result = bigInt_1.isBitSet(3);
+ expectedResult = false;
+ is(result, expectedResult, "'f0'.isBitSet(3)");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("f0", 16);
+ result = bigInt_1.isBitSet(4);
+ expectedResult = true;
+ is(result, expectedResult, "'f0'.isBitSet(4)");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("ff00", 16);
+ result = bigInt_1.isBitSet(7);
+ expectedResult = false;
+ is(result, expectedResult, "'ff00'.isBitSet(7)");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("ff00", 16);
+ result = bigInt_1.isBitSet(8);
+ expectedResult = true;
+ is(result, expectedResult, "'ff00'.isBitSet(8)");
+
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("05000000000000", 16);
+ result = bigInt_1.isBitSet(47);
+ expectedResult = false;
+ is(result, expectedResult, "'05000000000000'.isBitSet(47)");
+
+ result = bigInt_1.isBitSet(48);
+ expectedResult = true;
+ is(result, expectedResult, "'05000000000000'.isBitSet(48)");
+
+ result = bigInt_1.isBitSet(49);
+ expectedResult = false;
+ is(result, expectedResult, "'05000000000000'.isBitSet(49)");
+
+ result = bigInt_1.isBitSet(50);
+ expectedResult = true;
+ is(result, expectedResult, "'05000000000000'.isBitSet(50)");
+
+ result = bigInt_1.isBitSet(51);
+ expectedResult = false;
+ is(result, expectedResult, "'05000000000000'.isBitSet(51)");
+
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+
+ result = bigInt_1.isBitSet(52);
+ expectedResult = true;
+ is(result, expectedResult, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(52)");
+
+ result = bigInt_1.isBitSet(53);
+ expectedResult = false;
+ is(result, expectedResult, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(53)");
+
+ result = bigInt_1.isBitSet(54);
+ expectedResult = false;
+ is(result, expectedResult, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(54)");
+
+ result = bigInt_1.isBitSet(55);
+ expectedResult = true;
+ is(result, expectedResult, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(55)");
+
+ result = bigInt_1.isBitSet(56);
+ expectedResult = false;
+ is(result, expectedResult, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(56)");
+
+ result = bigInt_1.isBitSet(57);
+ expectedResult = false;
+ is(result, expectedResult, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(57)");
+
+ result = bigInt_1.isBitSet(58);
+ expectedResult = true;
+ is(result, expectedResult, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(58)");
+
+ result = bigInt_1.isBitSet(59);
+ expectedResult = false;
+ is(result, expectedResult, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(59)");
+
+ result = bigInt_1.isBitSet(60);
+ expectedResult = false;
+ is(result, expectedResult, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(60)");
+
+ //
+ // shiftLeft
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("7f", 16);
+ result = bigInt_1.shiftLeft(1);
+ expectedResult = new Clipperz.Crypto.BigInt('fe', 16);
+ is(result.asString(16), expectedResult.asString(16), "'7f'.shiftLeft(1)");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("ff", 16);
+ result = bigInt_1.shiftLeft(1);
+ expectedResult = new Clipperz.Crypto.BigInt('01fe', 16);
+ is(result.asString(16), expectedResult.asString(16), "'ff'.shiftLeft(1)");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ result = bigInt_1.shiftLeft(2);
+ expectedResult = new Clipperz.Crypto.BigInt('411949344998216388118140849290325291159199602592792139973517588004462660346196', 10);
+ is(result.asString(16), expectedResult.asString(16), "bigInt.shiftLeft(10)");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ result = bigInt_1.shiftLeft(8);
+ expectedResult = new Clipperz.Crypto.BigInt('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85500', 16);
+ is(result.asString(16), expectedResult.asString(16), "bigInt.shiftLeft(8)");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ result = bigInt_1.shiftLeft(10);
+ expectedResult = new Clipperz.Crypto.BigInt('105459032319543395358244057418323274536755098263754787833220502529142441048626176', 10);
+ is(result.asString(16), expectedResult.asString(16), "bigInt.shiftLeft(10)");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("ff", 16);
+ result = bigInt_1.shiftLeft(4096);
+ expectedResult = new Clipperz.Crypto.BigInt('266319164760353889206396941232739217557890883507082863997979538237408246532747151496450837043424377376926977212182012023686831226737377369852125202402098145876219029018646049576792205484267848170179157853023266287725961304046416750146445344507869587461686016719979944538177432428730245324189334334817497396705169439104855885416460935698516539852892760625369984672271807592980051379072961966267124963131928067770749329011150668180796667192392027523071601150548205543997146350727148885425131890513407882508735446345822174200042918879518190588482963417582471561436215675823872015307629566605147920139961896995509627341070659007877630760561618021922340198636222738900413041589858099507891702174848695380017286939422770656819923801325579542295611580916900945707539132241939193098989585491346846486694653352501301851631933610655701026861715541355665900384634131852357081890301147104554877895768806174478161952060916705243614916310627428392386264214492834954273769685672081818149530274447979003153864646452529328518204716201193108795473912970645455457215455929896570875795325190705652768977680951535622436287312272907838194995042100153360373621439300266297151905265332115434133380301670205335338558744799343198526203012170200626802804318535680', 10);
+ is(result.asString(16), expectedResult.asString(16), "bigInt.shiftLeft(4096)");
+
+ bigInt_1 = new Clipperz.Crypto.BigInt("ff", 16);
+ result = bigInt_1.shiftLeft(5000);
+ expectedResult = new Clipperz.Crypto.BigInt('36017909319555363939297846508911757008556852467205798478749046189356513330989041570231272721076143922520578818149998351104871978707844731275672652360293180474918203352225676748028889909508585302690242044220987556901043359920075229167479636668489487021705618421769517884399224788393498408327257966673365451264730932480701037648195190724361287852846952667257156204462064385766889505990099642052739974651257588866645027017486311782036674195285521311468922365736517586569614071211079825802088151607502649165228246449902253708785396560087430392277977851200155957347440614508171640900912431375050142178348130480158080696562512167652410483775588091117019722112093545783277082149415339867358805673644654236371762589715111732737686904860620316822561292797144756685380676343141118415434643259498221414744450502163805872581378284735047416230112208369784803081434462030568662742790926051825877463257023387907801068796855629691810029349692983890802136654401365294584656484852908751516361546884362396124203127393434938355516740711953765305060269622960662047729516459906444429108776596594293559927265789943280929098971285454533928986078946124455350540187565506016643147748500262510780357259199808936108629893209819473029835119866186316144675107047007737043503194737001430981972314376700993832503282107582239603281145093446879837002884732470988727066207277180181469885503549870618810897831820650576980763622189213611885522245978572420535750015505830146119605502167931087454823309031494727688701857532561113118183883936890880', 10);
+ is(result.asString(16), expectedResult.asString(16), "bigInt.shiftLeft(4096)");
+
+
+ //
+ // BigInt compare vs ByteArray compare
+ //
+ var bigInt_byteArray_1;
+ var bigInt_byteArray_2;
+
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ bigInt_2 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ bitInt_byteArray_1 = bigInt_1.asByteArray();
+ bitInt_byteArray_2 = bigInt_2.asByteArray();
+
+ result = bigInt_1.compare(bigInt_2);
+ expectedResult = bitInt_byteArray_1.compare(bitInt_byteArray_2);
+ is(result, expectedResult, "equal compare");
+
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ bigInt_2 = new Clipperz.Crypto.BigInt("f3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ bitInt_byteArray_1 = bigInt_1.asByteArray();
+ bitInt_byteArray_2 = bigInt_2.asByteArray();
+
+ result = bigInt_1.compare(bigInt_2);
+ expectedResult = bitInt_byteArray_1.compare(bitInt_byteArray_2);
+ is(result, expectedResult, "second term with one more bit at the leftmost - compare");
+
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("f3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ bigInt_2 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ bitInt_byteArray_1 = bigInt_1.asByteArray();
+ bitInt_byteArray_2 = bigInt_2.asByteArray();
+
+ result = bigInt_1.compare(bigInt_2);
+ expectedResult = bitInt_byteArray_1.compare(bitInt_byteArray_2);
+ is(result, expectedResult, "first term with one more bit at the leftmost - compare");
+
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427af41e4649b934ca495991b7852b855", 16);
+ bigInt_2 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ bitInt_byteArray_1 = bigInt_1.asByteArray();
+ bitInt_byteArray_2 = bigInt_2.asByteArray();
+
+ result = bigInt_1.compare(bigInt_2);
+ expectedResult = bitInt_byteArray_1.compare(bitInt_byteArray_2);
+ is(result, expectedResult, "first term with one more bit in the middle - compare");
+
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427af41e4649b934ca495991b7852b855", 16);
+ bigInt_2 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427aeffffffffffffffffffffffffffff", 16);
+ bitInt_byteArray_1 = bigInt_1.asByteArray();
+ bitInt_byteArray_2 = bigInt_2.asByteArray();
+
+ result = bigInt_1.compare(bigInt_2);
+ expectedResult = bitInt_byteArray_1.compare(bitInt_byteArray_2);
+ is(result, expectedResult, "first term with one more bit in the middle - compare");
+
+ //
+ bigInt_1 = new Clipperz.Crypto.BigInt("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ bigInt_2 = new Clipperz.Crypto.BigInt("05", 16);
+ bitInt_byteArray_1 = bigInt_1.asByteArray();
+ bitInt_byteArray_2 = bigInt_2.asByteArray();
+
+ result = bigInt_1.compare(bigInt_2);
+ expectedResult = bitInt_byteArray_1.compare(bitInt_byteArray_2);
+ is(result, expectedResult, "equal compare");
+*/
+ //-------------------------------------------------------------------------
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.B283.deferred.html b/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.B283.deferred.html
new file mode 100644
index 0000000..ba98167
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.B283.deferred.html
@@ -0,0 +1,155 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+<!-- - ->
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+<!- - -->
+<!-- -->
+ <script type="text/javascript" src="../../../../js/MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/Async.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/Logging.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/Iter.js"></script>
+<!-- -->
+
+<!-- - ->
+ <script type="text/javascript" src="../../../../js/MochiKit/Style.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/Signal.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/Color.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/Position.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/Visual.js"></script>
+<!- - -->
+
+
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+<!--<script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>-->
+<!--<script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>-->
+<!--<script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>-->
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Value.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Point.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Curve.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/StandardCurves.js'></script>
+
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+try {
+
+ var deferredResult;
+
+
+ deferredResult = new MochiKit.Async.Deferred();
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("** 1: " + res); return res;});
+
+ //
+ // ECC.Curve.multiplication
+ //
+ var curve;
+ var f2m;
+ var f2m_improved;
+ var value;
+ var moduledValue;
+ var result;
+ var result_improved;
+ var expectedResul;
+
+ f2m = new Clipperz.Crypto.ECC.BinaryField.FiniteField({modulus:new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16)})
+ f2m_improved = Clipperz.Crypto.ECC.StandardCurves.B283().finiteField();
+
+ curve = Clipperz.Crypto.ECC.StandardCurves.B283();
+
+/** /
+ value = new Clipperz.Crypto.ECC.BinaryField.Value("7b", 16);
+ result = curve.multiply(value, curve.G());
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Point({
+ x: new Clipperz.Crypto.ECC.BinaryField.Value('29705d23a9cda75e43984bdb9a8fd33304682da0f506a69bdbd5f36657e11b41e35fcdd', 16),
+ y: new Clipperz.Crypto.ECC.BinaryField.Value('59157d2ace16563a905361c5206cc0775c3330f4978bddf8aa9916c451cf9951313623b', 16)
+ });
+ is(result.x().asString(16), expectedResult.x().asString(16), "ECC.Curve.multiplication: result.x does match");
+ is(result.y().asString(16), expectedResult.y().asString(16), "ECC.Curve.multiplication: result.y does match");
+/ **/
+
+ value = new Clipperz.Crypto.ECC.BinaryField.Value("ba35032a24eb81238251d85824998bebae3b3e09f4d3845256c87585cf62416ee43191", 16);
+
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("** 6: " + res); return res;});
+// deferredResult.addCallback(console.time, 'B283.deferred.multiply - moduled value');
+//deferredResult.addBoth(function(res) {MochiKit.Base.logDebug("2 - " + res); return res;});
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("** 7: " + res); return res;});
+ deferredResult.addMethod(curve, 'deferredMultiply', value, curve.G());
+//deferredResult.addBoth(function(res) {MochiKit.Base.logDebug("3 - " + res); return res;});
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("** 8: " + res); return res;});
+// deferredResult.addBoth(function(res) {console.timeEnd('B283.deferred.multiply - moduled value'); return res;});
+//deferredResult.addBoth(function(res) {MochiKit.Base.logDebug("4 - " + res); return res;});
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("** 9: " + res); return res;});
+ deferredResult.addCallback(function(res) {
+ var expectedResult;
+
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Point({
+ x: new Clipperz.Crypto.ECC.BinaryField.Value('7cf07c0880d1ae59f567a2ce420e78d1fdfc1249df694a60e5d40d23c6dc631e1501b77', 16),
+ y: new Clipperz.Crypto.ECC.BinaryField.Value('97d1257d5c98cf71cf481bc0a495e0588150ea904526f503cd600f5e971c39700e95f1', 16)
+ });
+
+ is(res.x().asString(16), expectedResult.x().asString(16), "ECC.Curve.multiplication: result.x does match");
+ is(res.y().asString(16), expectedResult.y().asString(16), "ECC.Curve.multiplication: result.y does match");
+ })
+//deferredResult.addBoth(function(res) {MochiKit.Base.logDebug("5 - " + res); return res;});
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("** 10: " + res); return res;});
+ deferredResult.addBoth(function(res) {SimpleTest.finish(); return res;});
+ deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug(res); return res;});
+ deferredResult.callback();
+
+ SimpleTest.waitForExplicitFinish();
+
+ //-------------------------------------------------------------------------
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.BinaryField.FiniteField.B283.html b/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.BinaryField.FiniteField.B283.html
new file mode 100644
index 0000000..3d7efaa
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.BinaryField.FiniteField.B283.html
@@ -0,0 +1,209 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+<!--<script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC.js'></script>-->
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Value.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Point.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Curve.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Functions.js'></script>
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+try {
+ //
+ // ECC.BinaryFiniteField
+ //
+ var f2m;
+ var f2m_improved;
+ var a, a1, b;
+ var result;
+ var result_improved;
+ var expectedResul;
+
+ f2m = new Clipperz.Crypto.ECC.BinaryField.FiniteField({modulus:new Clipperz.Crypto.ECC.BinaryField.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16)})
+ f2m_improved = Clipperz.Crypto.ECC.StandardCurves.B283().finiteField();
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("05c91e41 d9ca17ef 9d8a33c1 a44eba6d 368fde02 1c492077 1a46eb01 a481e5f7 f430749d", 16);
+ b = new Clipperz.Crypto.ECC.BinaryField.Value("07377071 2de7d57b a803f65f 45786c06 876b8066 db75ec47 81c053b0 a0f78e2c a6ab5187", 16);
+
+ //
+ // addition
+ //
+ result = f2m.add(a, b);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("2fe6e30f42dc2943589c59ee136d66bb1e45e64c73ccc309b86b8b104766bdb529b251a", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.add");
+
+
+ //
+ // negation
+ //
+ result = f2m.negate(a);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("5c91e41d9ca17ef9d8a33c1a44eba6d368fde021c4920771a46eb01a481e5f7f430749d", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.negate");
+
+
+ //
+ // multiplication
+ //
+ result = f2m.multiply(a, b);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("2bacb89668741f6d1f7fd7d3df2f045814086adba11d8bb5f12f3f9851e3b66fbe283cb", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.multiply");
+
+
+ //
+ // fast multiplication
+ //
+ result = f2m.fastMultiply(a, b);
+ expectedResult = f2m.multiply(a, b);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.fastMultiply");
+
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("2fe6e30f42dc2943589c59ee136d66bb1e45e64c73ccc309b86b8b104766bdb529b251a", 16);
+ b = new Clipperz.Crypto.ECC.BinaryField.Value("5c91e41d9ca17ef9d8a33c1a44eba6d368fde021c4920771a46eb01a481e5f7f430749d", 16);
+ result = f2m.fastMultiply(a, b);
+ expectedResult = f2m.multiply(a, b);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.B283.fastMultiply");
+
+ //
+ // square
+ //
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("1111", 16);
+ result = f2m.square(a);
+ expectedResult = f2m.multiply(a, a);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.square");
+
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("11111111", 16);
+ result = f2m.square(a);
+ expectedResult = f2m.multiply(a, a);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.square");
+
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("5c91e41d9ca17ef9d8a33c1a44eba6d368fde021c4920771a46eb01a481e5f7f430749d", 16);
+ result = f2m.square(a);
+ expectedResult = f2m.multiply(a, a);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.square");
+
+
+ //
+ // inverse
+ //
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("2fe6e30f42dc2943589c59ee136d66bb1e45e64c73ccc309b86b8b104766bdb529b251a", 16);
+ result = f2m.inverse(a);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("3812fc574f3728c60384e141c0e2a808e21adec22dcd407b9e25dd13c6d1bf22defd84a", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.inverse");
+
+
+ //
+ // module
+ //
+
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("015655ebcb09fac51945162a0775f42df6151169826efdc55dea5d17c22adb92e6b1a6ae8311545ad7e0f46f09a5b960855e673db1e803a5b94562161213204ca1f24792e81f060a0aa6c29a492f106cc6d0b0ff4617b736dab590590a8cff9f807a15282544404e6b35841703c9fb00a9cad1d6878d601efc25368bdc51d5ff14a81610f4fe62cb2f452aee520a16", 16);
+ a1 = new Clipperz.Crypto.ECC.BinaryField.Value("015655ebcb09fac51945162a0775f42df6151169826efdc55dea5d17c22adb92e6b1a6ae8311545ad7e0f46f09a5b960855e673db1e803a5b94562161213204ca1f24792e81f060a0aa6c29a492f106cc6d0b0ff4617b736dab590590a8cff9f807a15282544404e6b35841703c9fb00a9cad1d6878d601efc25368bdc51d5ff14a81610f4fe62cb2f452aee520a16", 16);
+ result = f2m.module(a);
+ result_improved = f2m_improved.module(a1);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("2bacb89668741f6d1f7fd7d3df2f045814086adba11d8bb5f12f3f9851e3b66fbe283cb", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFiniteField.module");
+ is(result_improved.asString(16), expectedResult.asString(16), "ECC.BinaryFiniteField.module (improved)");
+ is(result.asString(16), result_improved.asString(16), "standard vs improved 'module' methods");
+
+
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("1401ca87b8f144684a2c58ae9308c237789e4bf1f36dd117c150b7d6076dd1da6197fe4c5225a064db0e4222589d5ca50eb6bb6b7147a03f61528438a8767c6a6c4a6883fd6f067112f5c97e74737b38925fafe22cea3e12b868d4ddea5b3341db8fc2e788cab74f0a7a3cc27087a89365945369938650a99217d566e13f80dc87f08273f7411b6b01ef1d399c772a", 16);
+ a1 = new Clipperz.Crypto.ECC.BinaryField.Value("1401ca87b8f144684a2c58ae9308c237789e4bf1f36dd117c150b7d6076dd1da6197fe4c5225a064db0e4222589d5ca50eb6bb6b7147a03f61528438a8767c6a6c4a6883fd6f067112f5c97e74737b38925fafe22cea3e12b868d4ddea5b3341db8fc2e788cab74f0a7a3cc27087a89365945369938650a99217d566e13f80dc87f08273f7411b6b01ef1d399c772a", 16);
+ result = f2m.module(a);
+ result_improved = f2m_improved.module(a1);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("15e2097d116e745ac47480807cb5eb99dad902728aaf5692241063bc70a5b372dbce798", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFiniteField.module (2)");
+ is(result_improved.asString(16), expectedResult.asString(16), "ECC.BinaryFiniteField.module (improved) (2)");
+ is(result.asString(16), result_improved.asString(16), "standard vs improved 'module' methods (2)");
+
+
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("112f5c97e74737b38925fafe22cea3e12b868d4ddea5b3341db8fc2e788cab74f0a7a3cc27087a89365945369938650a99217d566e13f80dc87f08273f7411b6b01ef1d399c772a1401ca87b8f144684a2c58ae9308c237789e4bf1f36dd117c150b7d6076dd1da6197fe4c5225a064db0e4222589d5ca50eb6bb6b7147a03f61528438a8767c6a6c4a6883fd6f067", 16);
+ a1 = new Clipperz.Crypto.ECC.BinaryField.Value("112f5c97e74737b38925fafe22cea3e12b868d4ddea5b3341db8fc2e788cab74f0a7a3cc27087a89365945369938650a99217d566e13f80dc87f08273f7411b6b01ef1d399c772a1401ca87b8f144684a2c58ae9308c237789e4bf1f36dd117c150b7d6076dd1da6197fe4c5225a064db0e4222589d5ca50eb6bb6b7147a03f61528438a8767c6a6c4a6883fd6f067", 16);
+ result = f2m.module(a);
+ result_improved = f2m_improved.module(a1);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("40f04cec8fe9caedf82adeff7e1aa06dcb9d08e097db8be2ad54b2ddc2e752152395623", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFiniteField.module (3)");
+ is(result_improved.asString(16), expectedResult.asString(16), "ECC.BinaryFiniteField.module (improved) (3)");
+ is(result.asString(16), result_improved.asString(16), "standard vs improved 'module' methods (3)");
+
+
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("02f4bf57710a7e0826a80a339e59e34476c343e75452e4bf4355847e6b41e655ecb08f4c418b172d7963c525c26fdc84ac294a348d3907652f0fcbff3e4c8e2238a478e4277489ce", 16);
+ is(a.asString(16), "02f4bf57710a7e0826a80a339e59e34476c343e75452e4bf4355847e6b41e655ecb08f4c418b172d7963c525c26fdc84ac294a348d3907652f0fcbff3e4c8e2238a478e4277489ce", "ECC.BinaryFiniteField - original value as expected (4)")
+ a1 = new Clipperz.Crypto.ECC.BinaryField.Value("02f4bf57710a7e0826a80a339e59e34476c343e75452e4bf4355847e6b41e655ecb08f4c418b172d7963c525c26fdc84ac294a348d3907652f0fcbff3e4c8e2238a478e4277489ce", 16);
+ result = f2m.module(a);
+ result_improved = f2m_improved.module(a1);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("ba35032a24eb81238251d85824998bebae3b3e09f4d3845256c87585cf62416ee43191", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFiniteField.module (4)");
+ is(result_improved.asString(16), expectedResult.asString(16), "ECC.BinaryFiniteField.module (improved) (4)");
+ is(result_improved.asString(16), "ba35032a24eb81238251d85824998bebae3b3e09f4d3845256c87585cf62416ee43191", "ECC.BinaryFinetField.module (static check) (4)");
+ is(result.asString(16), result_improved.asString(16), "standard vs improved 'module' methods (4)");
+
+ is(a.asString(16), "02f4bf57710a7e0826a80a339e59e34476c343e75452e4bf4355847e6b41e655ecb08f4c418b172d7963c525c26fdc84ac294a348d3907652f0fcbff3e4c8e2238a478e4277489ce", "ECC.BinaryFiniteField - original value preserved by standard method (4)")
+ is(a1.asString(16), "02f4bf57710a7e0826a80a339e59e34476c343e75452e4bf4355847e6b41e655ecb08f4c418b172d7963c525c26fdc84ac294a348d3907652f0fcbff3e4c8e2238a478e4277489ce", "ECC.BinaryFiniteField - original value preserved by improved method (4)")
+
+
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("2f4bf57710a7e0826a80a339e59e34476c343e75452e4bf4355847e6b41e655ecb08f4c418b172d7963c525c26fdc84ac294a348d3907652f0fcbff3e4c8e2238a478e4277489ce", 16);
+ result_improved = f2m_improved.module(a);
+ result = f2m.module(a);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("ba35032a24eb81238251d85824998bebae3b3e09f4d3845256c87585cf62416ee43191", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFiniteField.module (5)");
+ is(result_improved.asString(16), expectedResult.asString(16), "ECC.BinaryFiniteField.module (improved) (5)");
+ is(result_improved.asString(16), "ba35032a24eb81238251d85824998bebae3b3e09f4d3845256c87585cf62416ee43191", "ECC.BinaryFinetField.module (static check) (5)");
+ is(result.asString(16), result_improved.asString(16), "standard vs improved 'module' methods (5)");
+
+ //-------------------------------------------------------------------------
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.BinaryField.FiniteField.html b/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.BinaryField.FiniteField.html
new file mode 100644
index 0000000..6bddb26
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.BinaryField.FiniteField.html
@@ -0,0 +1,183 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+<!--<script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC.js'></script>-->
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Value.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Point.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Curve.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Functions.js'></script>
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+try {
+ //
+ // ECC.BinaryFiniteField
+ //
+ var f2m;
+ var f2m_improved;
+ var a, b;
+ var result;
+ var result_improved;
+ var expectedResul;
+
+ f2m = new Clipperz.Crypto.ECC.BinaryField.FiniteField({modulus:new Clipperz.Crypto.ECC.BinaryField.Value('80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425', 16)})
+ f2m_improved = Clipperz.Crypto.ECC.StandardCurves.B571().finiteField();
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("01401ca8 7b8f1446 84a2c58a e9308c23 7789e4bf 1f36dd11 7c150b7d 6076dd1d a6197fe4 c5225a06 4db0e422 2589d5ca 50eb6bb6 b7147a03 f6152843 8a8767c6 a6c4a688 3fd6f067", 16);
+ b = new Clipperz.Crypto.ECC.BinaryField.Value("0112f5c9 7e74737b 38925faf e22cea3e 12b868d4 ddea5b33 41db8fc2 e788cab7 4f0a7a3c c27087a8 93659453 69938650 a99217d5 66e13f80 dc87f082 73f7411b 6b01ef1d 399c772a", 16);
+
+ //
+ // addition
+ //
+ result = f2m.add(a, b);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("52e96105fb673dbc309a250b1c661d65318c6bc2dc86223dce84bf87fe17aae91305d80752ddaeded570714c1a539af9797c63d1f545832a92d8c1f97026ddcdc54995064a874d", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.add");
+
+
+ //
+ // negation
+ //
+ result = f2m.negate(a);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("1401ca87b8f144684a2c58ae9308c237789e4bf1f36dd117c150b7d6076dd1da6197fe4c5225a064db0e4222589d5ca50eb6bb6b7147a03f61528438a8767c6a6c4a6883fd6f067", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.negate");
+
+
+ //
+ // multiplication
+ //
+ result = f2m.multiply(a, b);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("4f8e4c0ae7664b284d3b4cb1b3f9568a1ce6e6e96b5381e184fe0822cb3d5c3a3f01ffd0206355d9e5c4853472bb33cf6b2d861d6b48c39d33a360e9a63ad2f7102f92e68a12312", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.multiply");
+
+
+ //
+ // fast multiplication
+ //
+ result = f2m.fastMultiply(a, b);
+ expectedResult = f2m.multiply(a, b);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.fastMultiply");
+
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("52e96105fb673dbc309a250b1c661d65318c6bc2dc86223dce84bf87fe17aae91305d80752ddaeded570714c1a539af9797c63d1f545832a92d8c1f97026ddcdc54995064a874d", 16);
+ b = new Clipperz.Crypto.ECC.BinaryField.Value("1401ca87b8f144684a2c58ae9308c237789e4bf1f36dd117c150b7d6076dd1da6197fe4c5225a064db0e4222589d5ca50eb6bb6b7147a03f61528438a8767c6a6c4a6883fd6f067", 16);
+ result = f2m.fastMultiply(a, b);
+ expectedResult = f2m.multiply(a, b);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.fastMultiply");
+
+ //
+ // square
+ //
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("1111", 16);
+ result = f2m.square(a);
+ expectedResult = f2m.multiply(a, a);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.square");
+
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("11111111", 16);
+ result = f2m.square(a);
+ expectedResult = f2m.multiply(a, a);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.square");
+
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("1401ca87b8f144684a2c58ae9308c237789e4bf1f36dd117c150b7d6076dd1da6197fe4c5225a064db0e4222589d5ca50eb6bb6b7147a03f61528438a8767c6a6c4a6883fd6f067", 16);
+ result = f2m.square(a);
+ expectedResult = f2m.multiply(a, a);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.square");
+
+
+ //
+ // inverse
+ //
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("1401ca87b8f144684a2c58ae9308c237789e4bf1f36dd117c150b7d6076dd1da6197fe4c5225a064db0e4222589d5ca50eb6bb6b7147a03f61528438a8767c6a6c4a6883fd6f067", 16);
+ result = f2m.inverse(a);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("1f898c60983c4e807e619b9cbe528585fc33aaae419d5e5cb2107269ccdcf21d5ad5b5d78d37fa435a0d0a8a75f2506240c325c6a2eee1a03008f9e1b9c6c0a511b730cdaf9b97e", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.inverse");
+
+
+ //
+ // module
+ //
+
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("015655ebcb09fac51945162a0775f42df6151169826efdc55dea5d17c22adb92e6b1a6ae8311545ad7e0f46f09a5b960855e673db1e803a5b94562161213204ca1f24792e81f060a0aa6c29a492f106cc6d0b0ff4617b736dab590590a8cff9f807a15282544404e6b35841703c9fb00a9cad1d6878d601efc25368bdc51d5ff14a81610f4fe62cb2f452aee520a16", 16);
+ a1 = new Clipperz.Crypto.ECC.BinaryField.Value("015655ebcb09fac51945162a0775f42df6151169826efdc55dea5d17c22adb92e6b1a6ae8311545ad7e0f46f09a5b960855e673db1e803a5b94562161213204ca1f24792e81f060a0aa6c29a492f106cc6d0b0ff4617b736dab590590a8cff9f807a15282544404e6b35841703c9fb00a9cad1d6878d601efc25368bdc51d5ff14a81610f4fe62cb2f452aee520a16", 16);
+ result = f2m.module(a);
+ result_improved = f2m_improved.module(a1);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("4f8e4c0ae7664b284d3b4cb1b3f9568a1ce6e6e96b5381e184fe0822cb3d5c3a3f01ffd0206355d9e5c4853472bb33cf6b2d861d6b48c39d33a360e9a63ad2f7102f92e68a12312", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.module");
+ is(result_improved.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.module (improved)");
+// is(result.asString(16), result_improved.asString(16), "standard vs improved 'module' methods");
+
+
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("1401ca87b8f144684a2c58ae9308c237789e4bf1f36dd117c150b7d6076dd1da6197fe4c5225a064db0e4222589d5ca50eb6bb6b7147a03f61528438a8767c6a6c4a6883fd6f067112f5c97e74737b38925fafe22cea3e12b868d4ddea5b3341db8fc2e788cab74f0a7a3cc27087a89365945369938650a99217d566e13f80dc87f08273f7411b6b01ef1d399c772a", 16);
+ a1 = new Clipperz.Crypto.ECC.BinaryField.Value("1401ca87b8f144684a2c58ae9308c237789e4bf1f36dd117c150b7d6076dd1da6197fe4c5225a064db0e4222589d5ca50eb6bb6b7147a03f61528438a8767c6a6c4a6883fd6f067112f5c97e74737b38925fafe22cea3e12b868d4ddea5b3341db8fc2e788cab74f0a7a3cc27087a89365945369938650a99217d566e13f80dc87f08273f7411b6b01ef1d399c772a", 16);
+ result = f2m.module(a);
+ result_improved = f2m_improved.module(a1);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("1704018ce75dc462a5ccd1eb18b8002ecb8536c616ec625f440f6888f8c32387e53a5cb3b6050688e9b64a32215a385ee98c518d6a484d5ac0ceeafa825743c84b075bdfabc341b", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.module (2)");
+ is(result_improved.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.module (improved) (2)");
+ is(a.asString(16), "1401ca87b8f144684a2c58ae9308c237789e4bf1f36dd117c150b7d6076dd1da6197fe4c5225a064db0e4222589d5ca50eb6bb6b7147a03f61528438a8767c6a6c4a6883fd6f067112f5c97e74737b38925fafe22cea3e12b868d4ddea5b3341db8fc2e788cab74f0a7a3cc27087a89365945369938650a99217d566e13f80dc87f08273f7411b6b01ef1d399c772a", "ECC.BinaryFinetField.module (2)");
+ is(a1.asString(16), "1401ca87b8f144684a2c58ae9308c237789e4bf1f36dd117c150b7d6076dd1da6197fe4c5225a064db0e4222589d5ca50eb6bb6b7147a03f61528438a8767c6a6c4a6883fd6f067112f5c97e74737b38925fafe22cea3e12b868d4ddea5b3341db8fc2e788cab74f0a7a3cc27087a89365945369938650a99217d566e13f80dc87f08273f7411b6b01ef1d399c772a", "ECC.BinaryFinetField.module (2)");
+
+
+ a = new Clipperz.Crypto.ECC.BinaryField.Value("112f5c97e74737b38925fafe22cea3e12b868d4ddea5b3341db8fc2e788cab74f0a7a3cc27087a89365945369938650a99217d566e13f80dc87f08273f7411b6b01ef1d399c772a1401ca87b8f144684a2c58ae9308c237789e4bf1f36dd117c150b7d6076dd1da6197fe4c5225a064db0e4222589d5ca50eb6bb6b7147a03f61528438a8767c6a6c4a6883fd6f067", 16);
+ result = f2m.module(a);
+ result_improved = f2m_improved.module(a);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("e160dd4a436e63877e1343d06576beaa66e06863ffe4335be38d6a37460a62d11133584a5bc6ac0590e18942e1fa88bb64a4d9fc6c1fd7b55d7e57b50b70a9e7cb2ed904ad77f4", 16);
+ is(result.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.module (2)");
+ is(result_improved.asString(16), expectedResult.asString(16), "ECC.BinaryFinetField.module (improved) (2)");
+
+ //-------------------------------------------------------------------------
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.BinaryField.Value.html b/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.BinaryField.Value.html
new file mode 100644
index 0000000..885bcc4
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.BinaryField.Value.html
@@ -0,0 +1,496 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+<!--<script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC.js'></script>-->
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Value.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Point.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Curve.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Functions.js'></script>
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+try {
+ var value_1;
+ var value_2;
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("a", 16);
+ is(value_1.asString(16), "0a");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("ffff", 16);
+ is(value_1.asString(16), "ffff");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("7fff", 16);
+ is(value_1.asString(16), "7fff");
+
+ is(parseInt("ffff", 16), 65535);
+ is(parseInt("ffffff", 16), 16777215);
+ is(parseInt("ffffffff", 16), 4294967295);
+ is(parseInt("ffffffffff", 16), 1099511627775);
+ is(parseInt("ffffffffffff", 16), 281474976710655);
+ is(parseInt("ffffffffffffff", 16), 72057594037927940);
+ is(parseInt("ffffffffffffffff", 16), 18446744073709552000);
+ is(parseInt("10000000000000000", 16), 18446744073709552001);
+ is(parseInt("10000000000000001", 16), 18446744073709552002);
+ is(parseInt("10000000000000009", 16), 18446744073709552010);
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("000108cbbacda1f03ea9360301045434ec7d82ba150936df08a229cbb4832ce1", 16);
+ is(value_1.wordSize(), 8, "check the number of words of a 64 char hex string using the 'wordSize' method");
+
+// 000108cb bacda1f0 3ea93603 01045434 ec7d82ba 150936df 08a229cb b4832ce1
+ is(value_1.value()[0], parseInt("b4832ce1", 16), "word[0]");
+ is(value_1.value()[1], parseInt("08a229cb", 16), "word[1]");
+ is(value_1.value()[2], parseInt("150936df", 16), "word[2]");
+ is(value_1.value()[3], parseInt("ec7d82ba", 16), "word[3]");
+ is(value_1.value()[4], parseInt("01045434", 16), "word[4]");
+ is(value_1.value()[5], parseInt("3ea93603", 16), "word[5]");
+ is(value_1.value()[6], parseInt("bacda1f0", 16), "word[6]");
+ is(value_1.value()[7], parseInt("000108cb", 16), "word[7]");
+
+ is(value_1.asString(16), "0108cbbacda1f03ea9360301045434ec7d82ba150936df08a229cbb4832ce1", "asString(16)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value('10 00000000 00000000', 16);
+ is(value_1.wordSize(), 3, "check the number of words of a value with only a bit set on the first slot of byte at position 17");
+ is(value_1.value()[0], parseInt("00000000", 16), "word[0]");
+ is(value_1.value()[1], parseInt("00000000", 16), "word[1]");
+ is(value_1.value()[2], parseInt("10", 16), "word[2]");
+ is(value_1.asString(16), "100000000000000000", "2^17 asString(16)");
+
+ //
+ // XOR
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 16);
+ result = value_1.xor(value_2);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('0', 16);
+ is(result.asString(16), expectedResult.asString(16), "a xor a = 0");
+
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value('e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855', 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value('e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b935c a495991b 7852b855', 16);
+ result = value_1.xor(value_2);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('10 00000000 00000000', 16);
+ is(result.asString(16), expectedResult.asString(16), "single bit difference");
+
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("01", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b935ca495991b7852b855', 16);
+ result = value_1.xor(value_2);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b935ca495991b7852b854', 16);
+ is(result.asString(16), expectedResult.asString(16), "01 xor value");
+
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value('f3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 16);
+ result = value_1.xor(value_2);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('1000000000000000000000000000000000000000000000000000000000000000', 16);
+ is(result.asString(16), expectedResult.asString(16), "first bit difference xor");
+
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value('84a2c58a', 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value('38925faf', 16);
+ result = value_1.xor(value_2);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('bc309a25', 16);
+ is(result.asString(16), expectedResult.asString(16), "84a2c58a XOR 38925faf = bc309a25");
+
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("01401ca87b8f144684a2c58ae9308c237789e4bf1f36dd117c150b7d6076dd1da6197fe4c5225a064db0e4222589d5ca50eb6bb6b7147a03f61528438a8767c6a6c4a6883fd6f067", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("0112f5c97e74737b38925fafe22cea3e12b868d4ddea5b3341db8fc2e788cab74f0a7a3cc27087a89365945369938650a99217d566e13f80dc87f08273f7411b6b01ef1d399c772a", 16);
+ result = value_1.xor(value_2);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('0052e96105fb673dbc309a250b1c661d65318c6bc2dc86223dce84bf87fe17aae91305d80752ddaeded570714c1a539af9797c63d1f545832a92d8c1f97026ddcdc54995064a874d', 16);
+ is(result.asString(16), expectedResult.asString(16), "xor");
+
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("01ebcb09fac51945162a0775f42df6151169826efdc55dea5d17c22adb92e6b1a6ae8311545ad7e0f46f09a5b960855e673db1e803a5b94562161213204ca1f24792e81f06a4f816429a492f106cc6d0b0ff4617b736dab590590a8cff9f807a15282544404e6b35841703c9fb00a9cad1d6878d601efc25368bdc51d5ff14a81610f4fe62cb2f452aee520a16", 16);
+ result = value_2.xor(value_1.shiftLeft(value_2.bitSize() - value_1.bitSize()));
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("ebcb09fac51945162a0775f42df6151169826efdc55dea5d17c22adb92e6b1a6ae8311545ad7e0f46f09a5b960855e673db1e803a5b94562161213204ca1f24792e81f06a4f892e29a492f106cc6d0b0ff4617b736dab590590a8cff9f807a15282544404e6b35841703c9fb00a9cad1d6878d601efc25368bdc51d5ff14a81610f4fe62cb2f452aee520a16", 16);
+ is(result.asString(16), expectedResult.asString(16), "xor");
+ is(result.bitSize(), 1120, "xor.bitSize");
+ is(result.wordSize(), 35, "result wordSize");
+ is(expectedResult.bitSize(), 1120, "xor.bitSize");
+ is(expectedResult.wordSize(), 35, "expectedResult wordSize");
+ is(result.compare(expectedResult), 0, "compare");
+
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("ebcb09fac51945162a0775f42df6151169826efdc55dea5d17c22adb92e6b1a6ae8311545ad7e0f46f09a5b960855e673db1e803a5b94562161213204ca1f24792e81f06a4f892e29a492f106cc6d0b0ff4617b736dab590590a8cff9f807a15282544404e6b35841703c9fb00a9cad1d6878d601efc25368bdc51d5ff14a81610f4fe62cb2f452aee520a16", 16);
+ result = value_2.xor(value_1.shiftLeft(value_2.bitSize() - value_1.bitSize()));
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("6bcb09fac51945162a0775f42df6151169826efdc55dea5d17c22adb92e6b1a6ae8311545ad7e0f46f09a5b960855e673db1e803a5b94562161213204ca1f24792e81f06a4f8d0b29a492f106cc6d0b0ff4617b736dab590590a8cff9f807a15282544404e6b35841703c9fb00a9cad1d6878d601efc25368bdc51d5ff14a81610f4fe62cb2f452aee520a16", 16);
+ is(result.asString(16), expectedResult.asString(16), "xor");
+ is(result.bitSize(), 1119, "xor.bitSize");
+ is(expectedResult.bitSize(), 1119, "xor.bitSize");
+ is(result.compare(expectedResult), 0, "compare");
+// value_1 =
+// value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 16);
+
+
+ value_1 = (new Clipperz.Crypto.ECC.BinaryField.Value("10101010 01010101 00000000", 16)).value();
+ value_2 = (new Clipperz.Crypto.ECC.BinaryField.Value("10101010", 16)).value();
+ result = new Clipperz.Crypto.ECC.BinaryField.Value(Clipperz.Crypto.ECC.BinaryField.Value._xor(value_1, value_2, 2));
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("01010101 00000000", 16);
+ is(result.asString(16), expectedResult.asString(16), "xor with offset 2");
+
+ value_1 = (new Clipperz.Crypto.ECC.BinaryField.Value(" 10101010 01010101 00000000", 16)).value();
+ value_2 = (new Clipperz.Crypto.ECC.BinaryField.Value("10101010 10101010", 16)).value();
+ result = new Clipperz.Crypto.ECC.BinaryField.Value(Clipperz.Crypto.ECC.BinaryField.Value._xor(value_1, value_2, 2));
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value("10101010 00000000 01010101 00000000", 16);
+ is(result.asString(16), expectedResult.asString(16), "xor with offset 2 (2)");
+
+ //
+ // isZero
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value('0', 16);
+ is(value_1.isZero(), true, "0.isZero() == true");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value('1', 16);
+ is(value_1.isZero(), false, "1.isZero() == false");
+
+ //
+ // Comparison
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("0", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("0", 16);
+ is (value_1.compare(value_2), 0, "BinaryField.value(0) = BinaryField.value(0)");
+// is (value_1.compare(0), 0, "BinaryField.value(0) = 0");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("000108cbbacda1f03ea9360301045434ec7d82ba150936df08a229cbb4832ce1", 16);
+ is (value_1.compare(value_2), 1, "BinaryField.value(xxxxxx) != BinaryField.value(0)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("000108cbbacda1f03ea9360301045434ec7d82ba150936df08a229cbb4832ce1", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("0", 16);
+ is(value_1.compare(value_2), 1, "BinaryField.value(xxxxxx) > BinaryField.value(0)");
+ is(value_2.compare(value_1), -1, "BinaryField.value(0) < BinaryField.value(xxxx)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("000108cbbacda1f03ea9360301045434ec7d82ba150936df08a229cbb4832ce1", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("05", 16);
+ is(value_1.compare(value_2), 1, "BinaryField.value(xxxxxx) > BinaryField.value(05)");
+ is(value_2.compare(value_1), -1, "BinaryField.value(05) < BinaryField.value(xxxx)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("-10", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("10", 16);
+ is(value_1.compare(value_2), -1, "BinaryField.value(-10) - BinaryField.value(10). No negative number are managed");
+
+ //
+ // more comparison
+ //
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ result = value_1.compare(value_2);
+ is(result, 0, "equal compare");
+
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c442", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("f3b0c442", 16);
+ result = value_1.compare(value_2);
+ is(result, -1, "second term with one more bit at the leftmost - compare (1)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c442 98fc1c14", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("f3b0c442 98fc1c14", 16);
+ result = value_1.compare(value_2);
+ is(result, -1, "second term with one more bit at the leftmost - compare (2)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c442 98fc1c14 9afbf4c8", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("f3b0c442 98fc1c14 9afbf4c8", 16);
+ result = value_1.compare(value_2);
+ is(result, -1, "second term with one more bit at the leftmost - compare (3)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("f3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855", 16);
+ result = value_1.compare(value_2);
+ is(result, -1, "second term with one more bit at the leftmost - compare (n)");
+
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("f3b0c442", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c442", 16);
+ result = value_1.compare(value_2);
+ is(result, 1, "first term with one more bit at the leftmost - compare (1)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("f3b0c442 98fc1c14", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c442 98fc1c14", 16);
+ result = value_1.compare(value_2);
+ is(result, 1, "first term with one more bit at the leftmost - compare (2)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("f3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855", 16);
+ result = value_1.compare(value_2);
+ is(result, 1, "first term with one more bit at the leftmost - compare (n)");
+
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c44298fc1c149afbf4c8996fb92427af41e4649b934ca495991b7852b855", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ result = value_1.compare(value_2);
+ is(result, 1, "first term with one more bit in the middle - compare");
+
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c44298fc1c149afbf4c8996fb92427af41e4649b934ca495991b7852b855", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c44298fc1c149afbf4c8996fb92427aeffffffffffffffffffffffffffff", 16);
+ result = value_1.compare(value_2);
+ is(result, 1, "first term with one more bit in the middle - compare");
+
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ value_2 = new Clipperz.Crypto.ECC.BinaryField.Value("05", 16);
+ result = value_1.compare(value_2);
+ is(result, 1, "equal compare");
+
+
+
+ //
+ // isBitSet
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("ff", 16);
+ result = value_1.isBitSet(1);
+ expectedResult = true;
+ is(result, expectedResult, "'ff'.isBitSet(1)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("f0", 16);
+ result =value_1.isBitSet(1);
+ expectedResult = false;
+ is(result, expectedResult, "'f0'.isBitSet(1)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("f0", 16);
+ result = value_1.isBitSet(3);
+ expectedResult = false;
+ is(result, expectedResult, "'f0'.isBitSet(3)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("f0", 16);
+ result = value_1.isBitSet(4);
+ expectedResult = true;
+ is(result, expectedResult, "'f0'.isBitSet(4)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("ff00", 16);
+ result = value_1.isBitSet(7);
+ expectedResult = false;
+ is(result, expectedResult, "'ff00'.isBitSet(7)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("ff00", 16);
+ result = value_1.isBitSet(8);
+ expectedResult = true;
+ is(result, expectedResult, "'ff00'.isBitSet(8)");
+
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("05000000000000", 16);
+ result = value_1.isBitSet(47);
+ expectedResult = false;
+ is(result, expectedResult, "'05000000000000'.isBitSet(47)");
+
+ result = value_1.isBitSet(48);
+ expectedResult = true;
+ is(result, expectedResult, "'05000000000000'.isBitSet(48)");
+
+ result = value_1.isBitSet(49);
+ expectedResult = false;
+ is(result, expectedResult, "'05000000000000'.isBitSet(49)");
+
+ result = value_1.isBitSet(50);
+ expectedResult = true;
+ is(result, expectedResult, "'05000000000000'.isBitSet(50)");
+
+ result = value_1.isBitSet(51);
+ expectedResult = false;
+ is(result, expectedResult, "'05000000000000'.isBitSet(51)");
+
+ //
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+
+ result = value_1.isBitSet(52);
+ is(result, true, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(52)");
+
+ result = value_1.isBitSet(53);
+ is(result, false, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(53)");
+
+ result = value_1.isBitSet(54);
+ is(result, false, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(54)");
+
+ result = value_1.isBitSet(55);
+ is(result, true, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(55)");
+
+ result = value_1.isBitSet(56);
+ is(result, false, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(56)");
+
+ result = value_1.isBitSet(57);
+ is(result, false, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(57)");
+
+ result = value_1.isBitSet(58);
+ is(result, true, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(58)");
+
+ result = value_1.isBitSet(59);
+ is(result, false, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(59)");
+
+ result = value_1.isBitSet(60);
+ is(result, false, "'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'.isBitSet(60)");
+
+
+ //
+ // shiftLeft
+ //
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("7f", 16);
+ result = value_1.shiftLeft(1);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('fe', 16);
+ is(result.asString(16), expectedResult.asString(16), "'7f'.shiftLeft(1)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("ff", 16);
+ result = value_1.shiftLeft(1);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('01fe', 16);
+ is(result.asString(16), expectedResult.asString(16), "'ff'.shiftLeft(1)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value( 'ffff', 16);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('ffff00', 16);
+ result = value_1.shiftLeft(8);
+ is(result.asString(16), expectedResult.asString(16), "ffff.shiftLeft(8)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value( '80000000', 16);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('1 00000000', 16);
+ result = value_1.shiftLeft(1);
+ is(result.compare(expectedResult) == 0, true, '8000000.shiftLeft(1).compare');
+ is(result.asString(16), expectedResult.asString(16), "80000000.shiftLeft(1)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value('20000000', 16);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('40000000', 16);
+ result = value_1.shiftLeft(1);
+ is(result.compare(expectedResult) == 0, true, '2000000.shiftLeft(1).compare');
+ is(result.asString(16), expectedResult.asString(16), "20000000.shiftLeft(1)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value('40000000', 16);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('80000000', 16);
+ result = value_1.shiftLeft(1);
+ is(result.compare(expectedResult) == 0, true, '4000000.shiftLeft(1).compare');
+ is(result.asString(16), expectedResult.asString(16), "40000000.shiftLeft(1)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value( 'ff7fffff', 16);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('ff 7fffff00', 16);
+ result = value_1.shiftLeft(8);
+ is(result.asString(16), expectedResult.asString(16), "ff7fffff.shiftLeft(8)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value( 'ffffffff', 16);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('ff ffffff00', 16);
+ result = value_1.shiftLeft(8);
+ is(result.asString(16), expectedResult.asString(16), "ffffffff.shiftLeft(8)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value( "e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855", 16);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('3 8ec3110a 63f07052 6befd322 65bee490 9eb90791 926e4d32 9256646d e14ae154', 16);
+ result = value_1.shiftLeft(2);
+ is(result.asString(16), expectedResult.asString(16), "Value.shiftLeft(10)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ result = value_1.shiftLeft(8);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85500', 16);
+ is(result.asString(16), expectedResult.asString(16), "Value.shiftLeft(8)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 16);
+ result = value_1.shiftLeft(10);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('38e c3110a63 f070526b efd32265 bee4909e b9079192 6e4d3292 56646de1 4ae15400', 16);
+ is(result.asString(16), expectedResult.asString(16), "Value.shiftLeft(10)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("ff", 16);
+ result = value_1.shiftLeft(32);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('ff00000000', 16);
+ is(result.asString(16), expectedResult.asString(16), "ff.shiftLeft(32)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("ff", 16);
+ result = value_1.shiftLeft(4096);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('ff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', 16);
+ is(result.asString(16), expectedResult.asString(16), "bigInt.shiftLeft(4096)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("ff", 16);
+ result = value_1.shiftLeft(5000);
+ expectedResult = new Clipperz.Crypto.ECC.BinaryField.Value('ff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', 16);
+ is(result.asString(16), expectedResult.asString(16), "bigInt.shiftLeft(4096)");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("0", 16);
+ is(value_1.bitSize(), 0, "0.bitSize()");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("10", 16);
+ is(value_1.bitSize(), 5, "10.bitSize()");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("80", 16);
+ is(value_1.bitSize(), 8, "80.bitSize()");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("ff", 16);
+ is(value_1.bitSize(), 8, "ff.bitSize()");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("100", 16);
+ is(value_1.bitSize(), 9, "100.bitSize()");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("80000000", 16);
+ is(value_1.bitSize(), 32, "80000000.bitSize()");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("ffffffff", 16);
+ is(value_1.bitSize(), 32, "ffffffff.bitSize()");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("1 00000000", 16);
+ is(value_1.bitSize(), 33, "100000000.bitSize()");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("8000 00000000", 16);
+ is(value_1.bitSize(), 48, "8000 00000000.bitSize()");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("ffff ffffffff", 16);
+ is(value_1.bitSize(), 48, "ffff ffffffff.bitSize()");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("10000 00000000", 16);
+ is(value_1.bitSize(), 49, "10000 00000000.bitSize()");
+
+ value_1 = new Clipperz.Crypto.ECC.BinaryField.Value("6bcb09fac51945162a0775f42df6151169826efdc55dea5d17c22adb92e6b1a6ae8311545ad7e0f46f09a5b960855e673db1e803a5b94562161213204ca1f24792e81f06a4f8d0b29a492f106cc6d0b0ff4617b736dab590590a8cff9f807a15282544404e6b35841703c9fb00a9cad1d6878d601efc25368bdc51d5ff14a81610f4fe62cb2f452aee520a16", 16);
+ is(value_1.bitSize(), 1119, "6bcb09fac51945162a0775f42df6151169826efdc55dea5d17c22adb92e6b1a6ae8311545ad7e0f46f09a5b960855e673db1e803a5b94562161213204ca1f24792e81f06a4f8d0b29a492f106cc6d0b0ff4617b736dab590590a8cff9f807a15282544404e6b35841703c9fb00a9cad1d6878d601efc25368bdc51d5ff14a81610f4fe62cb2f452aee520a16.bitSize()");
+
+ //-------------------------------------------------------------------------
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.K283.deferred.html b/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.K283.deferred.html
new file mode 100644
index 0000000..b53a9a1
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/ECC.K283.deferred.html
@@ -0,0 +1,160 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+<!-- - ->
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+<!- - -->
+<!-- -->
+ <script type="text/javascript" src="../../../../js/MochiKit/Base.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/Async.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/DOM.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/Logging.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/Iter.js"></script>
+<!-- -->
+
+<!-- - ->
+ <script type="text/javascript" src="../../../../js/MochiKit/Style.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/Signal.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/Color.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/Position.js"></script>
+ <script type="text/javascript" src="../../../../js/MochiKit/Visual.js"></script>
+<!- - -->
+
+
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+<!--<script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>-->
+<!--<script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>-->
+<!--<script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>-->
+
+<!--<script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Value.js'></script>-->
+<!--<script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Point.js'></script>-->
+<!--<script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/FiniteField.js'></script>-->
+<!--<script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/BinaryField/Curve.js'></script>-->
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/Koblitz/Value.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/Koblitz/Point.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/Koblitz/FiniteField.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/Koblitz/Curve.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/ECC/StandardCurves.js'></script>
+
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+try {
+
+ var deferredResult;
+
+
+ deferredResult = new MochiKit.Async.Deferred();
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("** 1: " + res); return res;});
+
+ //
+ // ECC.Curve.multiplication
+ //
+ var curve;
+ var f2m;
+ var f2m_improved;
+ var value;
+ var moduledValue;
+ var result;
+ var result_improved;
+ var expectedResul;
+
+ f2m = new Clipperz.Crypto.ECC.Koblitz.FiniteField({modulus:new Clipperz.Crypto.ECC.Koblitz.Value('08000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000010a1', 16)})
+ f2m_improved = Clipperz.Crypto.ECC.StandardCurves.K283().finiteField();
+
+ curve = Clipperz.Crypto.ECC.StandardCurves.K283();
+
+/** /
+ value = new Clipperz.Crypto.ECC.Koblitz.Value("7b", 16);
+ result = curve.multiply(value, curve.G());
+ expectedResult = new Clipperz.Crypto.ECC.Koblitz.Point({
+ x: new Clipperz.Crypto.ECC.Koblitz.Value('29705d23a9cda75e43984bdb9a8fd33304682da0f506a69bdbd5f36657e11b41e35fcdd', 16),
+ y: new Clipperz.Crypto.ECC.Koblitz.Value('59157d2ace16563a905361c5206cc0775c3330f4978bddf8aa9916c451cf9951313623b', 16)
+ });
+ is(result.x().asString(16), expectedResult.x().asString(16), "ECC.Curve.multiplication: result.x does match");
+ is(result.y().asString(16), expectedResult.y().asString(16), "ECC.Curve.multiplication: result.y does match");
+/ **/
+
+ value = new Clipperz.Crypto.ECC.Koblitz.Value("ba35032a24eb81238251d85824998bebae3b3e09f4d3845256c87585cf62416ee43191", 16);
+
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("** 6: " + res); return res;});
+// deferredResult.addCallback(console.time, 'K283.deferred.multiply - moduled value');
+//deferredResult.addBoth(function(res) {MochiKit.Base.logDebug("2 - " + res); return res;});
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("** 7: " + res); return res;});
+ deferredResult.addMethod(curve, 'deferredMultiply', value, curve.G());
+//deferredResult.addBoth(function(res) {MochiKit.Base.logDebug("3 - " + res); return res;});
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("** 8: " + res); return res;});
+// deferredResult.addBoth(function(res) {console.timeEnd('K283.deferred.multiply - moduled value'); return res;});
+//deferredResult.addBoth(function(res) {MochiKit.Base.logDebug("4 - " + res); return res;});
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("** 9: " + res); return res;});
+ deferredResult.addCallback(function(res) {
+ var expectedResult;
+
+ expectedResult = new Clipperz.Crypto.ECC.Koblitz.Point({
+ x: new Clipperz.Crypto.ECC.Koblitz.Value('7cf07c0880d1ae59f567a2ce420e78d1fdfc1249df694a60e5d40d23c6dc631e1501b77', 16),
+ y: new Clipperz.Crypto.ECC.Koblitz.Value('97d1257d5c98cf71cf481bc0a495e0588150ea904526f503cd600f5e971c39700e95f1', 16)
+ });
+
+ is(res.x().asString(16), expectedResult.x().asString(16), "ECC.Curve.multiplication: result.x does match");
+ is(res.y().asString(16), expectedResult.y().asString(16), "ECC.Curve.multiplication: result.y does match");
+ })
+//deferredResult.addBoth(function(res) {MochiKit.Base.logDebug("5 - " + res); return res;});
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("** 10: " + res); return res;});
+ deferredResult.addBoth(function(res) {SimpleTest.finish(); return res;});
+//deferredResult.addBoth(function(res) {MochiKit.Logging.logDebug("** 11: " + res); return res;});
+ deferredResult.callback();
+
+ SimpleTest.waitForExplicitFinish();
+
+ //-------------------------------------------------------------------------
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/JSCrypto_vs_Clipperz.html b/frontend/gamma/tests/tests/Clipperz/Crypto/JSCrypto_vs_Clipperz.html
new file mode 100644
index 0000000..1342349
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/JSCrypto_vs_Clipperz.html
@@ -0,0 +1,70 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.Crypto.JSCrypto_vs_Clipperz - tests</title>
+
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type='text/javascript' src='./jscrypto.js'></script>
+
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.Async.js"></script>
+
+</head>
+<body>
+
+<pre id="test">
+ <script type="text/javascript">
+ var longAsciiText = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nullam ac ipsum. Morbi mauris. Aenean ac elit id metus lobortis elementum. Proin at quam ac ipsum pellentesque adipiscing. Aenean vestibulum, nisl eu suscipit iaculis, quam pede congue mi, sit amet dapibus metus neque eget dui. Suspendisse posuere diam ac sapien. Nulla lobortis dapibus leo. Quisque ornare tortor quis turpis. Aliquam erat volutpat. Ut faucibus lacinia magna. Nunc metus leo, volutpat quis, mollis ac, sagittis ut, turpis. Quisque purus. Mauris ante enim, vehicula eu, suscipit vitae, laoreet vel, nulla. Pellentesque pede leo, aliquam quis, vehicula eget, rhoncus nec, metus. Vestibulum tellus. Suspendisse blandit. Pellentesque vel tellus. Maecenas arcu. Duis eget purus. Curabitur non pede nec odio cursus luctus. In non elit. Nullam eget nunc in nisl elementum commodo. Vivamus sollicitudin pede quis dui. Morbi commodo. Praesent a risus id urna hendrerit fermentum. Nunc ultricies tristique odio. Phasellus imperdiet, sapien eget viverra blandit, tortor risus blandit nisi, et sodales libero dolor quis nisl. Morbi vel enim. Nunc in quam. Vestibulum a magna. Fusce auctor elit in augue. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris tincidunt consectetuer leo. Etiam non turpis. Vestibulum eros. Praesent venenatis adipiscing augue. Pellentesque dapibus odio ac arcu rhoncus sagittis. Nullam vitae augue. Ut magna nulla, congue eu, porta in, egestas quis, ligula. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur malesuada neque non nulla. Nulla facilisi. Fusce viverra magna ut tellus. Sed rutrum pretium sapien. Vivamus dui. Cras fringilla. Nullam lorem. Vestibulum varius, purus at imperdiet fermentum, metus diam ultricies lacus, vitae aliquam ipsum libero sit amet felis. Sed eget eros ac velit commodo sollicitudin. Morbi in metus in mi viverra lacinia. Sed ut urna. Suspendisse imperdiet tellus ac velit. Duis malesuada velit sit amet sapien. Vestibulum a sapien id libero accumsan luctus. Fusce iaculis. Donec pulvinar orci ut pede. Nam placerat sem ut sem. Ut pretium bibendum nisl. Suspendisse potenti. Phasellus mollis neque in neque. Suspendisse augue magna, eleifend et, malesuada at, viverra in, nisl. Donec vel lectus in justo ultrices tristique. Aliquam erat volutpat. Morbi suscipit, risus ac volutpat mollis, risus metus hendrerit sapien, ac scelerisque est orci eu est. Quisque sit amet velit. Sed libero diam, semper id, eleifend ac, iaculis non, nulla. Donec varius tincidunt arcu. Sed quis metus eu erat adipiscing viverra. Donec odio. Aenean sagittis nisl sed purus. Fusce vel nibh quis felis accumsan bibendum. Etiam et risus ac tortor cursus pharetra. Maecenas tellus. Pellentesque nec felis id eros vehicula commodo. Aliquam interdum sagittis odio. Maecenas at lorem eget mi aliquet sagittis. Mauris quis nibh in odio sodales lacinia. Proin augue mauris, placerat a, blandit vel, tincidunt eget, ante. Quisque turpis purus, placerat eget, tempor consectetuer, aliquet ac, enim. Etiam eleifend vestibulum mi. Vivamus gravida. Morbi dolor. In hac habitasse platea dictumst. Nulla commodo lectus faucibus lorem. Phasellus aliquet pede id metus hendrerit tempus. Fusce convallis pede ac neque tempor dignissim. Sed vitae lorem sit amet justo dapibus porta. Ut quam orci, pretium non, sagittis nec, condimentum id, dolor. Sed tempor. Nunc porta rutrum leo. Nunc id sem. Sed nibh tortor, dapibus eget, feugiat a, pretium pretium, purus. Suspendisse suscipit lobortis sem. Praesent pharetra orci. Quisque molestie tristique quam. Maecenas nunc lorem, rhoncus non, venenatis sed, sodales at, felis. Quisque semper. Quisque malesuada est quis lacus. Nullam a justo. Aliquam pellentesque, ante ut congue molestie, nisl sapien posuere nisl, eu cursus nulla ligula vel nisl. Fusce commodo lacinia magna. Aenean rutrum vestibulum lorem. Pellentesque fermentum tristique ipsum. Nulla facilisi. Donec id mi eget ipsum commodo egestas. Mauris iaculis. Nulla vulputate mi at nisl. In condimentum sodales tellus. Donec metus orci, mollis vel, accumsan ac, ornare ac, lacus. Pellentesque accumsan est et tellus. Nam mollis. Aenean accumsan eros sit amet tellus. Praesent eu libero. Sed tempus urna nec dolor. Nulla facilisi. Duis eleifend rhoncus neque. Curabitur consectetuer quam eu justo. Sed metus. Vivamus risus. Aliquam erat volutpat. Aliquam erat volutpat. Nunc semper urna. Praesent molestie libero a lacus. Nullam suscipit lobortis velit. Praesent rhoncus, felis ut interdum dapibus, ipsum lectus vestibulum nulla, in interdum risus dolor eget orci. Nullam venenatis. Suspendisse laoreet, arcu a luctus consectetuer, libero ligula condimentum quam, eget elementum mauris tortor sed enim. Pellentesque leo. Nam interdum malesuada ante. Praesent fermentum nunc et dolor. Donec auctor volutpat odio. Pellentesque volutpat egestas ipsum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras ac ligula eu justo dignissim accumsan. Nullam nisi. Fusce id sem. Fusce et urna. Pellentesque commodo pharetra lorem. Donec erat. Vestibulum elit arcu, commodo et, consequat eget, posuere eget, sem. Morbi sed nulla sed neque commodo commodo. Aliquam erat volutpat. Ut id turpis a enim malesuada vestibulum. In arcu dui, dignissim vitae, blandit eu, egestas ac, arcu. In ultricies sapien vitae nisi. Proin rhoncus magna eget tortor. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In dictum. Sed volutpat pharetra quam. Mauris eget eros. Fusce malesuada dolor id pede. Praesent nec justo sed nisi vehicula varius. In scelerisque convallis nulla. Pellentesque sodales massa vulputate urna. Duis metus urna, imperdiet ac, sodales vel, ullamcorper sed, pede. Vestibulum aliquam mollis metus. Praesent tempus tristique elit. Maecenas tellus tortor, pretium id, mollis id, molestie non, turpis. Vivamus nibh magna, bibendum vitae, a.";
+ var longIsoLatin1Text = "¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ¡¢£¤¥¦§¨©ª«¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùù";
+ var longUtf8Text = "客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之所以能统称为汉语第客家方言简体字危及了对古代文学的研究共有找华语并不被中国政府很好的接受然而汉语之";
+ </script>
+ <script type="text/javascript" src="JSCrypto_vs_Clipperz.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/JSCrypto_vs_Clipperz.test.js b/frontend/gamma/tests/tests/Clipperz/Crypto/JSCrypto_vs_Clipperz.test.js
new file mode 100644
index 0000000..7dc688c
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/JSCrypto_vs_Clipperz.test.js
@@ -0,0 +1,418 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//function logElapsedTime(aDescription, aStartTime, anEndTime) {
+// MochiKit.Logging.logDebug(aDescription + " - took " + (anEndTime - aStartTime) + "ms");
+// SimpleTest.ok(true, aDescription + " - took " + (anEndTime - aStartTime) + "ms");
+//}
+
+var asciiTestString = longAsciiText;
+//asciiTestString = asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString;
+//asciiTestString = asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString;
+//asciiTestString = asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString;
+//asciiTestString = asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString + asciiTestString;
+//asciiTestString = asciiTestString + asciiTestString;
+//asciiTestString = asciiTestString + asciiTestString;
+
+var isoLatin1TestString = longIsoLatin1Text;
+//isoLatin1TestString = isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString;
+//isoLatin1TestString = isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString;
+//isoLatin1TestString = isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString + isoLatin1TestString;
+//isoLatin1TestString = isoLatin1TestString + isoLatin1TestString;
+//isoLatin1TestString = isoLatin1TestString + isoLatin1TestString;
+
+var utf8TestString = longUtf8Text;
+//utf8TestString = utf8TestString + utf8TestString + utf8TestString + utf8TestString + utf8TestString + utf8TestString + utf8TestString + utf8TestString + utf8TestString + utf8TestString;
+//utf8TestString = utf8TestString + utf8TestString + utf8TestString + utf8TestString + utf8TestString + utf8TestString + utf8TestString + utf8TestString + utf8TestString + utf8TestString;
+//utf8TestString = utf8TestString + utf8TestString;
+//utf8TestString = utf8TestString + utf8TestString;
+
+var times = {
+ 'Clipperz': {},
+ 'JSCrypto': {}
+};
+
+function appendResults (aDescription, aTimer) {
+ MochiKit.DOM.appendChildNodes(MochiKit.DOM.getElement('timerTBODY'),
+ MochiKit.DOM.TR(null,
+ MochiKit.DOM.TH({align:'left'}, aDescription),
+ MochiKit.DOM.TH(null, aTimer['ascii']['encrypt'] + ' - ' + aTimer['ascii']['decrypt'])//,
+// MochiKit.DOM.TH(null, aTimer['isoLatin1']['encrypt'] + ' - ' + aTimer['isoLatin1']['decrypt']),
+// MochiKit.DOM.TH(null, aTimer['utf8']['encrypt'] + ' - ' + aTimer['utf8']['decrypt'])
+ )
+ );
+
+}
+
+//=============================================================================
+
+function timeRegularFunction (aDescription, aString, anEncryptFunction, aDecryptFunction, aTimer, aKey) {
+ var start;
+ var end;
+ var encryptTime;
+ var decryptTime;
+ var ciphertext;
+ var plaintext;
+
+
+ start = new Date();
+ ciphertext = anEncryptFunction('trustno1', aString);
+ end = new Date();
+ encryptTime = end - start;
+
+ start = new Date();
+ plaintext = aDecryptFunction('trustno1', ciphertext);
+ end = new Date();
+ decryptTime = end - start;
+ aTimer[aKey] = { 'encrypt': encryptTime, 'decrypt': decryptTime };
+ SimpleTest.is(aString, plaintext, aDescription);
+}
+/*
+function timeRegularFunction (anEncryptFunction, aDecryptFunction, aTimer) {
+ var start;
+ var end;
+ var encryptTime;
+ var decryptTime;
+ var ciphertext;
+ var plaintext;
+
+
+ start = new Date();
+ ciphertext = anEncryptFunction('trustno1', asciiTestString);
+ end = new Date();
+ encryptTime = end - start;
+
+ start = new Date();
+ plaintext = aDecryptFunction('trustno1', ciphertext);
+ end = new Date();
+ decryptTime = end - start;
+ aTimer['ascii'] = { 'encrypt': encryptTime, 'decrypt': decryptTime };
+ SimpleTest.is(asciiTestString, plaintext, "Encrypt/decrypt the ASCII text");
+
+
+ start = new Date();
+ ciphertext = anEncryptFunction('trustno1', isoLatin1TestString);
+ end = new Date();
+ encryptTime = end - start;
+
+ start = new Date();
+ plaintext = aDecryptFunction('trustno1', ciphertext);
+ end = new Date();
+ decryptTime = end - start;
+ aTimer['isoLatin1'] = { 'encrypt': encryptTime, 'decrypt': decryptTime };
+ SimpleTest.is(isoLatin1TestString, plaintext, "Encrypt/decrypt the ISO-Latin 1 text");
+
+
+ start = new Date();
+ ciphertext = anEncryptFunction('trustno1', utf8TestString);
+ end = new Date();
+ encryptTime = end - start;
+
+ start = new Date();
+ plaintext = aDecryptFunction('trustno1', ciphertext);
+ end = new Date();
+ decryptTime = end - start;
+ aTimer['utf8'] = { 'encrypt': encryptTime, 'decrypt': decryptTime };
+ SimpleTest.is(utf8TestString, plaintext, "Encrypt/decrypt the UTF-8 text");
+}
+*/
+function timeDeferredFunction (aDescription, aString, anEncryptFunction, aDecryptFunction, aTimer, aKey, someTestArgs) {
+ var start;
+ var end;
+
+ var deferredResult;
+
+ aTimer[aKey] = {};
+
+ deferredResult = new Clipperz.Async.Deferred("timeDeferredFunction", someTestArgs);
+ deferredResult.addCallback(function (aValue) { start = new Date(); return aValue});
+ deferredResult.addCallback(anEncryptFunction, 'trustno1', aString);
+ deferredResult.addCallback(function (aValue) {
+ end = new Date();
+ aTimer[aKey]['encrypt'] = end-start;
+ return aValue;
+ });
+ deferredResult.addCallback(function (aValue) { start = new Date(); return aValue});
+ deferredResult.addCallback(aDecryptFunction, 'trustno1');
+ deferredResult.addCallback(function (aValue) {
+ end = new Date();
+ aTimer[aKey]['decrypt'] = end-start;
+ return aValue;
+ });
+ deferredResult.addCallback(function (aValue) {
+ SimpleTest.is(aString, aValue, aDescription);
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+}
+
+//=============================================================================
+
+function encryptUsingJSCrypto (aKey, aValue) {
+ var salt;
+ var key;
+ var cipher;
+ var iv;
+ var plaintext;
+ var ciphertext;
+ var tag;
+ var adata;
+
+ salt = [1,2,3,4,5,6,7,8];
+ key = generateKey(aKey, salt);
+
+ cipher = new aes(key, CCM);
+ iv = Random.random_words(4);
+
+ plaintext = aValue;
+ ciphertext = [];
+ tag = [];
+ adata = "";
+
+ cipher.encrypt(iv, plaintext, ciphertext, adata, tag);
+
+ return ciphertext;
+}
+
+//-----------------------------------------------------------------------------
+
+function decryptUsingJSCrypto (aKey, aValue) {
+ var salt;
+ var key;
+ var cipher;
+ var ciphertext;
+ var plaintext;
+ var tag;
+ var adata;
+
+ salt = [1,2,3,4,5,6,7,8];
+ key = generateKey(aKey, salt);
+ tag = [];
+ adata = "";
+
+ cipher = new aes(key, CCM);
+ ciphertext = aValue;
+ plaintext = cipher.decrypt(ciphertext, adata, tag);
+
+ return plaintext;
+}
+
+//=============================================================================
+
+function encryptUsingClipperz (aKey, aValue) {
+ var key;
+ var value;
+ var data;
+ var encryptedData;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ value = aValue;
+ data = new Clipperz.ByteArray(value);
+ encryptedData = Clipperz.Crypto.AES.encrypt(key, data);
+ return encryptedData.toBase64String();
+}
+
+//-----------------------------------------------------------------------------
+
+function decryptUsingClipperz (aKey, aValue) {
+ var key;
+ var value;
+ var decryptedData;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ value = new Clipperz.ByteArray().appendBase64String(aValue);
+
+ decryptedData = Clipperz.Crypto.AES.decrypt(key, value).asString();
+
+ return decryptedData;
+}
+
+//=============================================================================
+
+function encryptUsingClipperzAndJSON (aKey, aValue) {
+ var key;
+ var value;
+ var data;
+ var encryptedData;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ value = Clipperz.Base.serializeJSON(aValue);
+ data = new Clipperz.ByteArray(value);
+ encryptedData = Clipperz.Crypto.AES.encrypt(key, data);
+ return encryptedData.toBase64String();
+}
+
+//-----------------------------------------------------------------------------
+
+function decryptUsingClipperzAndJSON (aKey, aValue) {
+ var key;
+ var value;
+ var decryptedData;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ value = new Clipperz.ByteArray().appendBase64String(aValue);
+
+ decryptedData = Clipperz.Crypto.AES.decrypt(key, value).asString();
+
+ return Clipperz.Base.evalJSON(decryptedData);
+}
+
+//=============================================================================
+
+function deferredEncryptUsingClipperz (aKey, aValue) {
+ var deferredResult;
+ var key;
+ var data;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ data = new Clipperz.ByteArray(aValue);
+
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.deferredEncrypt", {trace:false});
+ deferredResult.addCallback(Clipperz.Crypto.AES.deferredEncrypt, key, data);
+ deferredResult.addCallback(function(aResult) {
+ return aResult.toBase64String();
+ })
+ deferredResult.callback();
+
+ return deferredResult;
+}
+
+//-----------------------------------------------------------------------------
+
+function deferredDecryptUsingClipperz (aKey, aValue) {
+ var key, value;
+
+ key = Clipperz.Crypto.SHA.sha_d256(new Clipperz.ByteArray(aKey));
+ value = new Clipperz.ByteArray().appendBase64String(aValue);
+
+ deferredResult = new Clipperz.Async.Deferred("Clipperz.deferredDecrypt", {trace:false});
+ deferredResult.addCallback(Clipperz.Crypto.AES.deferredDecrypt, key, value);
+ deferredResult.addCallback(function(aResult) {
+ return aResult.asString();
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+}
+
+//=============================================================================
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+
+ 'encryptMultipleStringsUsingClipperzFunctions': function (someTestArgs) {
+// timeRegularFunction(encryptUsingClipperz, decryptUsingClipperz, times['Clipperz']['Regular']);
+ times['Clipperz']['NO JSON'] = {};
+
+ timeRegularFunction("Clipperz - NO JSON - Ascii", asciiTestString, encryptUsingClipperz, decryptUsingClipperz, times['Clipperz']['NO JSON'], 'ascii');
+ timeRegularFunction("Clipperz - NO JSON - ISO Latin 1", isoLatin1TestString, encryptUsingClipperz, decryptUsingClipperz, times['Clipperz']['NO JSON'], 'isoLatin1');
+ timeRegularFunction("Clipperz - NO JSON - UTF-8", utf8TestString, encryptUsingClipperz, decryptUsingClipperz, times['Clipperz']['NO JSON'], 'utf8');
+
+ appendResults("Clipperz - NO JSON", times['Clipperz']['NO JSON']);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'encryptMultipleStringsUsingClipperzAndJSONFunctions': function (someTestArgs) {
+// timeRegularFunction(encryptUsingClipperzAndJSON, decryptUsingClipperzAndJSON, times['Clipperz']['JSON']);
+ times['Clipperz']['JSON'] = {};
+
+ timeRegularFunction("Clipperz - JSON - Ascii", asciiTestString, encryptUsingClipperzAndJSON, decryptUsingClipperzAndJSON, times['Clipperz']['JSON'], 'ascii');
+ timeRegularFunction("Clipperz - JSON - ISO Latin 1", isoLatin1TestString, encryptUsingClipperzAndJSON, decryptUsingClipperzAndJSON, times['Clipperz']['JSON'], 'isoLatin1');
+ timeRegularFunction("Clipperz - JSON - UTF-8", utf8TestString, encryptUsingClipperzAndJSON, decryptUsingClipperzAndJSON, times['Clipperz']['JSON'], 'utf8');
+
+ appendResults("Clipperz - JSON", times['Clipperz']['JSON']);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'encryptMultipleStringsUsingClipperzDeferredFunctions': function (someTestArgs) {
+ times['Clipperz']['Deferred'] = {};
+ times['Clipperz']['Deferred [NO JSON]'] = {};
+
+ return Clipperz.Async.callbacks("encryptMultipleStringsUsingClipperzDeferredFunctions", [
+ MochiKit.Base.partial(timeDeferredFunction, "Deferred Ascii", asciiTestString, deferredEncryptUsingClipperz, deferredDecryptUsingClipperz, times['Clipperz']['Deferred [NO JSON]'], 'ascii', someTestArgs),
+// MochiKit.Base.partial(timeDeferredFunction, "Deferred IsoLatin1", isoLatin1TestString, deferredEncryptUsingClipperz, deferredDecryptUsingClipperz, times['Clipperz']['Deferred [NO JSON]'], 'isoLatin1', someTestArgs),
+// MochiKit.Base.partial(timeDeferredFunction, "Deferred UTF-8", utf8TestString, deferredEncryptUsingClipperz, deferredDecryptUsingClipperz, times['Clipperz']['Deferred [NO JSON]'], 'utf8', someTestArgs),
+
+ MochiKit.Base.partial(appendResults, "Clipperz - deferred [NO JSON]", times['Clipperz']['Deferred [NO JSON]']),
+
+ MochiKit.Base.partial(timeDeferredFunction, "Deferred Ascii", asciiTestString, Clipperz.PM.Crypto.encryptingFunctions.versions['0.3'].deferredEncrypt, Clipperz.PM.Crypto.encryptingFunctions.versions['0.3'].deferredDecrypt, times['Clipperz']['Deferred'], 'ascii', someTestArgs),
+// MochiKit.Base.partial(timeDeferredFunction, "Deferred IsoLatin1", isoLatin1TestString, Clipperz.PM.Crypto.encryptingFunctions.versions['0.3'].deferredEncrypt, Clipperz.PM.Crypto.encryptingFunctions.versions['0.3'].deferredDecrypt, times['Clipperz']['Deferred'], 'isoLatin1', someTestArgs),
+// MochiKit.Base.partial(timeDeferredFunction, "Deferred UTF-8", utf8TestString, Clipperz.PM.Crypto.encryptingFunctions.versions['0.3'].deferredEncrypt, Clipperz.PM.Crypto.encryptingFunctions.versions['0.3'].deferredDecrypt, times['Clipperz']['Deferred'], 'utf8', someTestArgs),
+
+ MochiKit.Base.partial(appendResults, "Clipperz - PM", times['Clipperz']['Deferred'])
+ ], someTestArgs);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'encryptMultipleStringsUsingJSCryptoFunctions': function (someTestArgs) {
+ timeRegularFunction("JSCrypto - Ascii", asciiTestString, encryptUsingJSCrypto, decryptUsingJSCrypto, times['JSCrypto'], 'ascii');
+ timeRegularFunction("JSCrypto - ISO Latin 1", isoLatin1TestString, encryptUsingJSCrypto, decryptUsingJSCrypto, times['JSCrypto'], 'isoLatin1');
+ timeRegularFunction("JSCrypto - UTF-8", utf8TestString, encryptUsingJSCrypto, decryptUsingJSCrypto, times['JSCrypto'], 'utf8');
+
+ appendResults("JSCrypto", times['JSCrypto']);
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+//#############################################################################
+
+SimpleTest.waitForExplicitFinish();
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+Random.set_default_paranoia(0);
+
+//Random.addEventListener("seeded", MochiKit.Base.partial(SimpleTest.runDeferredTests, "Clipperz.Crypto.JSCrypto_vs_Clipperz", tests, {trace:false}));
+//Random.addEventListener("seeded", function () { console.log("SEEDED!")});
+
+
+MochiKit.DOM.appendChildNodes(MochiKit.DOM.currentDocument().body,
+ MochiKit.DOM.TABLE({border:'1', cellpadding:'4', cellspacing:'0'},
+ MochiKit.DOM.THEAD(),
+ MochiKit.DOM.TBODY({id:'timerTBODY'},
+ MochiKit.DOM.TR(null,
+ MochiKit.DOM.TH(null, "algorithm"),
+ MochiKit.DOM.TH(null, "ascii [" + asciiTestString.length + "]"),
+ MochiKit.DOM.TH(null, "ISO Latin 1 [" + isoLatin1TestString.length * 2 + "]"),
+ MochiKit.DOM.TH(null, "UTF 8 [" + utf8TestString.length * 3 + "]")
+ )
+ ),
+ MochiKit.DOM.TFOOT()
+ )//,
+// MochiKit.DOM.H4(null, "AES chunkSize: " + Clipperz.Crypto.AES.DeferredExecution.chunkSize),
+// MochiKit.DOM.H4(null, "AES pauseTime: " + Clipperz.Crypto.AES.DeferredExecution.pauseTime)
+);
+
+
+SimpleTest.runDeferredTests("Clipperz.Crypto.JSCrypto_vs_Clipperz", tests, {trace:false}); \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/PRNG.html b/frontend/gamma/tests/tests/Clipperz/Crypto/PRNG.html
new file mode 100644
index 0000000..7ffd691
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/PRNG.html
@@ -0,0 +1,117 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <script> jslog_config_enabled = true; </script>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/DOM.js'></script>
+
+<!--<script type='text/javascript' src='../../../../js/Clipperz/Crypto/Statistics.js'></script>-->
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+test_PRNG = function() {
+ var rand1, rand2;
+ var i,c;
+
+ c = 10;
+ for (i=0; i<c; i++) {
+// jslog.debug(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString());
+ }
+
+ rand1 = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(1);
+ is(rand1.byteAtIndex(0) <= 255, true, "getRandomByte returns always a single byte");
+
+ rand2 = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(1);
+ is(rand1.equals(rand2), false, "getRandomByte should almost always return two different values when called into sequence");
+
+
+ rand1 = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32);
+ rand2 = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32);
+ is(rand1.equals(rand2), false, "getRandomByte should almost always return two different values when called into sequence");
+ is(rand1.split(0,1).equals(rand2.split(0,1)), false, "getRandomByte should almost always return two different values when called into sequence");
+// is(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(10000).toHexString(), "rand 1", "Value for random test");
+// is(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(10000).toHexString(), "rand 2", "Value for random test");
+// is(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(10000).toHexString(), "rand 3", "Value for random test");
+// is(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(10000).toHexString(), "rand 4", "Value for random test");
+// is(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(10000).toHexString(), "rand 5", "Value for random test");
+// is(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(10000).toHexString(), "rand 6", "Value for random test");
+// is(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(10000).toHexString(), "rand 7", "Value for random test");
+// is(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(10000).toHexString(), "rand 8", "Value for random test");
+// is(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(10000).toHexString(), "rand 9", "Value for random test");
+// is(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(10000).toHexString(), "rand 10", "Value for random test");
+// is(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(10000).toHexString(), "rand 11", "Value for random test");
+// is(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(10000).toHexString(), "rand 12", "Value for random test");
+// is(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(10000).toHexString(), "rand 13", "Value for random test");
+// is(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(10000).toHexString(), "rand 14", "Value for random test");
+//jslog.debug(rand1.toHexString());
+//jslog.debug(rand2.toHexString());
+
+ SimpleTest.finish();
+}
+
+try {
+ MochiKit.Signal.connect(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'readyToGenerateRandomBytes', test_PRNG);
+ Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+ SimpleTest.waitForExplicitFinish();
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/RSA.html b/frontend/gamma/tests/tests/Clipperz/Crypto/RSA.html
new file mode 100644
index 0000000..468a987
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/RSA.html
@@ -0,0 +1,90 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/DOM.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/RSA.js'></script>
+
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+try {
+ var rsaPublicKey;
+ var randomValue;
+ var publicEncryptedValue;
+ var privateEncryptedValue;
+
+ var startTime;
+ var endTime;
+
+
+startTime=new Date();
+ rsaPublicKey = Clipperz.Crypto.RSA.generatePublicKey(512);
+
+endTime=new Date();
+is(true, true, 'Time to generate the RSA public key (size 512 bit): '+(endTime.getTime()-startTime.getTime())/1000.0);
+
+ randomValue = Clipperz.Crypto.Base.generateRandomSeed();
+ publicEncryptedValue = Clipperz.Crypto.RSA.encryptUsingPublicKey(rsaPublicKey, randomValue);
+ privateEncryptedValue = Clipperz.Crypto.RSA.encryptUsingPrivateKey(rsaPublicKey, randomValue);
+
+ is(publicEncryptedValue == privateEncryptedValue, false);
+ is(Clipperz.Crypto.RSA.decryptUsingPrivateKey(rsaPublicKey, publicEncryptedValue), randomValue);
+ is(Clipperz.Crypto.RSA.decryptUsingPublicKey(rsaPublicKey, privateEncryptedValue), randomValue);
+
+ //-------------------------------------------------------------------------
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/SHA.html b/frontend/gamma/tests/tests/Clipperz/Crypto/SHA.html
new file mode 100644
index 0000000..1c88213
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/SHA.html
@@ -0,0 +1,175 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.Crypto.SHA - TEST</title>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+
+
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.Async.js"></script>
+
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript" src="SHA.test.js"></script>
+</pre>
+</body>
+</html>
+
+
+
+<!-- html>
+<head>
+ <script>
+ jslog_config_enabled = true;
+ clipperz_profiling_enabled = true;
+ </script>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+
+try {
+ var byteArray;
+ var hash;
+ var longText;
+ var startTime, endTime;
+
+ longText = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec nunc sapien, condimentum vitae, varius vel, pharetra in, augue. Mauris quam magna, pretium sit amet, accumsan id, volutpat lobortis, nibh. Fusce sagittis. Aenean justo. Curabitur euismod pede. Morbi at ante. Proin nisl leo, ultrices sed, facilisis et, nonummy sit amet, lorem. Praesent mauris tellus, pulvinar sed, nonummy vitae, rhoncus non, nunc. Proin placerat malesuada nisl. Nunc id enim. Maecenas commodo enim ac nibh. Sed condimentum, urna sit amet euismod gravida, mi urna varius odio, luctus pretium lectus justo nec felis. Ut in augue et est malesuada rhoncus. Sed vel orci. Mauris suscipit. Praesent cursus velit non turpis. Donec tristique dolor ac est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla est sapien, vulputate eget, bibendum id, pharetra nec, mauris. Aliquam faucibus tincidunt dui. Proin iaculis. Maecenas sagittis. Integer et augue. Donec vitae urna in orci aliquet commodo. Vestibulum lorem sem, suscipit ac, placerat nec, mollis in, felis. Donec laoreet odio a mauris. Integer rutrum, sapien id varius molestie, mauris odio egestas orci, non bibendum sem felis in metus. Phasellus consectetuer lectus adipiscing mauris. Ut magna tellus, euismod ac, suscipit tincidunt, ullamcorper adipiscing, massa. Etiam orci. Phasellus a urna. Cras neque quam, laoreet at, tempus eget, euismod nec, nibh. Etiam hendrerit. Aenean vel lorem. Ut ligula lacus, congue eu, lobortis sit amet, venenatis in, magna. Nullam cursus felis quis est. Sed sem est, condimentum eu, vestibulum a, mattis vel, diam. Curabitur tincidunt pede quis pede. Sed neque diam, convallis vel, luctus at, porta id, nisl. Suspendisse potenti. Sed volutpat lobortis orci. Praesent mi. In interdum. Suspendisse suscipit ipsum eget dolor. Curabitur et tellus sed velit hendrerit varius. Cras sit amet est. Donec arcu nulla, vehicula et, pretium in, placerat id, felis. Integer mollis auctor lectus. Integer ultrices elementum sapien. Nam et erat. Nam pulvinar porta tortor. Nam at risus. Quisque nulla. Integer vestibulum, lacus id bibendum laoreet, ligula mi pharetra lorem, sit amet pharetra felis mauris quis justo. Aliquam ultricies. Duis a pede eget lorem dapibus rhoncus. Aenean eu elit non libero consectetuer viverra. Maecenas velit mi, eleifend vel, malesuada vel, condimentum quis, odio. Mauris tempus augue sed turpis. Pellentesque condimentum, lacus vitae pellentesque ultricies, risus tellus posuere nisi, et dictum turpis pede nec elit. Sed eu lectus eu justo sagittis euismod. Vestibulum lobortis, urna id mollis rhoncus, orci quam euismod ligula, at malesuada lacus magna vitae massa. Phasellus mattis fermentum velit. Nulla vulputate consequat enim. Maecenas quis neque. Curabitur sagittis facilisis neque. In elementum, eros non porttitor rhoncus, libero turpis sodales odio, vitae porta tellus purus et ante. Nullam molestie sollicitudin metus. Donec a elit. Morbi ut lacus. Donec at arcu. Quisque velit diam, interdum a, lacinia at, varius et, odio. Cras neque magna, ornare id, sollicitudin id, consequat a, est. Phasellus vestibulum est at leo. Nam facilisis, nulla dapibus condimentum pellentesque, est magna viverra ligula, at sollicitudin urna augue ut sapien. Fusce justo.";
+
+ //-------------------------------------------------------------------------
+ //
+ // Test of SHA-256 algorithm
+ //
+ //-------------------------------------------------------------------------
+
+ byteArray = new Clipperz.ByteArray();
+ hash = Clipperz.Crypto.SHA.sha256(byteArray);
+ is(hash.toHexString(), "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "sha256('')");
+
+ byteArray = new Clipperz.ByteArray("0xbd");
+ hash = Clipperz.Crypto.SHA.sha256(byteArray);
+ is(hash.toHexString(), "0x68325720aabd7c82f30f554b313d0570c95accbb7dc4b5aae11204c08ffe732b", "sha256('0xbd')");
+
+ byteArray = new Clipperz.ByteArray("0x5fd4");
+ hash = Clipperz.Crypto.SHA.sha256(byteArray);
+ is(hash.toHexString(), "0x7c4fbf484498d21b487b9d61de8914b2eadaf2698712936d47c3ada2558f6788", "sha256('0x5fd4')");
+
+ byteArray = new Clipperz.ByteArray("0xc98c8e55");
+ hash = Clipperz.Crypto.SHA.sha256(byteArray);
+ is(hash.toHexString(), "0x7abc22c0ae5af26ce93dbb94433a0e0b2e119d014f8e7f65bd56c61ccccd9504", "sha256('0xc98c8e55')");
+
+ byteArray = new Clipperz.ByteArray("0x0df1cd526b5a4edd");
+ hash = Clipperz.Crypto.SHA.sha256(byteArray);
+ is(hash.toHexString(), "0x47f527210d6e8f940b5082fec01b7305908fa2b49ea3ae597c19a3986097153c", "sha256('0x0df1cd526b5a4edd')");
+
+ byteArray = new Clipperz.ByteArray("0xfdf4700984ee11b70af1880d0e0fefd4");
+ hash = Clipperz.Crypto.SHA.sha256(byteArray);
+ is( hash.toHexString(),
+ "0xb01ae16eed3b4a770f127b98469ba26fe3d8e9f59d8a2983214afe6cff0e6b6c",
+ "sha256('0xfdf4700984ee11b70af1880d0e0fefd4')");
+
+ byteArray = new Clipperz.ByteArray("0x8cf53d90077df9a043bf8d10b470b144784411c93a4d504556834dae3ea4a5bb");
+ hash = Clipperz.Crypto.SHA.sha256(byteArray);
+ is( hash.toHexString(),
+ "0x56059e8cb3c2978b198208bf5ca1e1ea5659b737a506324b7cec75b5ebaf057d",
+ "sha256('0x8cf53d90077df9a043bf8d10b470b144784411c93a4d504556834dae3ea4a5bb')");
+
+ byteArray = new Clipperz.ByteArray("0xeebcf5cd6b12c90db64ff71a0e08ccd956e170a50dad769480d6b1fb3eff4934cde90f9e9b930ee637a66285c10f4e8a");
+ hash = Clipperz.Crypto.SHA.sha256(byteArray);
+ is( hash.toHexString(),
+ "0xc117b9dce689c399ec99008788cd5d24d8396fab7d96315c4f3fe6d56da63bb3",
+ "sha256('0xeebcf5cd6b12c90db64ff71a0e08ccd956e170a50dad769480d6b1fb3eff4934cde90f9e9b930ee637a66285c10f4e8a')");
+
+ byteArray = new Clipperz.ByteArray("0x3592ecfd1eac618fd390e7a9c24b656532509367c21a0eac1212ac83c0b20cd896eb72b801c4d212c5452bbbf09317b50c5c9fb1997553d2bbc29bb42f5748ad");
+ hash = Clipperz.Crypto.SHA.sha256(byteArray);
+ is( hash.toHexString(),
+ "0x105a60865830ac3a371d3843324d4bb5fa8ec0e02ddaa389ad8da4f10215c454",
+ "sha256('0x3592ecfd1eac618fd390e7a9c24b656532509367c21a0eac1212ac83c0b20cd896eb72b801c4d212c5452bbbf09317b50c5c9fb1997553d2bbc29bb42f5748ad')");
+
+
+ byteArray = new Clipperz.ByteArray(longText);
+startTime = new Date();
+//console.profile("SHA256");
+ hash = Clipperz.Crypto.SHA.sha256(byteArray);
+//console.profileEnd("SHA256");
+endTime = new Date();
+ is( hash.toHexString(),
+ "0xf6fac13c06784e0fbc61a3d25c41c9984840a8b617a2beb57cf6fa3e5e4a8949",
+ "sha256(longText)");
+ is((endTime - startTime) < 500, true, "Long text hash performance (" + (endTime - startTime) + ")");
+ MochiKit.Logging.logDebug("elapsed time: " + (endTime - startTime));
+
+//#############################################################################
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html -->
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/SHA.test.js b/frontend/gamma/tests/tests/Clipperz/Crypto/SHA.test.js
new file mode 100644
index 0000000..c9f1f3b
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/SHA.test.js
@@ -0,0 +1,84 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+var testSHA = function (aValue, anExpectedResult) {
+ var byteArrayValue;
+
+ byteArrayValue = new Clipperz.ByteArray(aValue);
+ hash = Clipperz.Crypto.SHA.sha256(byteArrayValue);
+ is(hash.toHexString(), anExpectedResult, "sha256(' " + byteArrayValue.toHexString() + "')");
+
+}
+
+
+var tests = {
+
+ 'basic_tests': function (someTestArgs) {
+ testSHA('', '0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855');
+ testSHA('0xbd', '0x68325720aabd7c82f30f554b313d0570c95accbb7dc4b5aae11204c08ffe732b');
+ testSHA('0x5fd4', '0x7c4fbf484498d21b487b9d61de8914b2eadaf2698712936d47c3ada2558f6788');
+ testSHA('0xc98c8e55', '0x7abc22c0ae5af26ce93dbb94433a0e0b2e119d014f8e7f65bd56c61ccccd9504');
+ testSHA('0x0df1cd526b5a4edd', '0x47f527210d6e8f940b5082fec01b7305908fa2b49ea3ae597c19a3986097153c');
+ testSHA('0xfdf4700984ee11b70af1880d0e0fefd4', '0xb01ae16eed3b4a770f127b98469ba26fe3d8e9f59d8a2983214afe6cff0e6b6c');
+ testSHA('0x8cf53d90077df9a043bf8d10b470b144784411c93a4d504556834dae3ea4a5bb', '0x56059e8cb3c2978b198208bf5ca1e1ea5659b737a506324b7cec75b5ebaf057d');
+ testSHA('0xeebcf5cd6b12c90db64ff71a0e08ccd956e170a50dad769480d6b1fb3eff4934cde90f9e9b930ee637a66285c10f4e8a', '0xc117b9dce689c399ec99008788cd5d24d8396fab7d96315c4f3fe6d56da63bb3');
+ testSHA('0x3592ecfd1eac618fd390e7a9c24b656532509367c21a0eac1212ac83c0b20cd896eb72b801c4d212c5452bbbf09317b50c5c9fb1997553d2bbc29bb42f5748ad', '0x105a60865830ac3a371d3843324d4bb5fa8ec0e02ddaa389ad8da4f10215c454');
+
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'aldo_cortesi_tests': function (someTestArgs) {
+ testSHA('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', '0xa3f01b6939256127582ac8ae9fb47a382a244680806a3f613a118851c1ca1d47');
+ testSHA('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', '0xb35439a4ac6f0948b6d6f9e3c6af0f5f590ce20f1bde7090ef7970686ec6738a');
+ testSHA('0x79', '0xa1fce4363854ff888cff4b8e7875d600c2682390412a8cf79b37d0b11148b0fa');
+ testSHA('0x80', '0x76be8b528d0075f7aae98d6fa57a6d3c83ae480a8469e668d7b0af968995ac71');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'longTextPerformance_test': function (someTestArgs) {
+ var longText;
+ var startTime;
+ var endTime;
+
+ longText = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec nunc sapien, condimentum vitae, varius vel, pharetra in, augue. Mauris quam magna, pretium sit amet, accumsan id, volutpat lobortis, nibh. Fusce sagittis. Aenean justo. Curabitur euismod pede. Morbi at ante. Proin nisl leo, ultrices sed, facilisis et, nonummy sit amet, lorem. Praesent mauris tellus, pulvinar sed, nonummy vitae, rhoncus non, nunc. Proin placerat malesuada nisl. Nunc id enim. Maecenas commodo enim ac nibh. Sed condimentum, urna sit amet euismod gravida, mi urna varius odio, luctus pretium lectus justo nec felis. Ut in augue et est malesuada rhoncus. Sed vel orci. Mauris suscipit. Praesent cursus velit non turpis. Donec tristique dolor ac est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla est sapien, vulputate eget, bibendum id, pharetra nec, mauris. Aliquam faucibus tincidunt dui. Proin iaculis. Maecenas sagittis. Integer et augue. Donec vitae urna in orci aliquet commodo. Vestibulum lorem sem, suscipit ac, placerat nec, mollis in, felis. Donec laoreet odio a mauris. Integer rutrum, sapien id varius molestie, mauris odio egestas orci, non bibendum sem felis in metus. Phasellus consectetuer lectus adipiscing mauris. Ut magna tellus, euismod ac, suscipit tincidunt, ullamcorper adipiscing, massa. Etiam orci. Phasellus a urna. Cras neque quam, laoreet at, tempus eget, euismod nec, nibh. Etiam hendrerit. Aenean vel lorem. Ut ligula lacus, congue eu, lobortis sit amet, venenatis in, magna. Nullam cursus felis quis est. Sed sem est, condimentum eu, vestibulum a, mattis vel, diam. Curabitur tincidunt pede quis pede. Sed neque diam, convallis vel, luctus at, porta id, nisl. Suspendisse potenti. Sed volutpat lobortis orci. Praesent mi. In interdum. Suspendisse suscipit ipsum eget dolor. Curabitur et tellus sed velit hendrerit varius. Cras sit amet est. Donec arcu nulla, vehicula et, pretium in, placerat id, felis. Integer mollis auctor lectus. Integer ultrices elementum sapien. Nam et erat. Nam pulvinar porta tortor. Nam at risus. Quisque nulla. Integer vestibulum, lacus id bibendum laoreet, ligula mi pharetra lorem, sit amet pharetra felis mauris quis justo. Aliquam ultricies. Duis a pede eget lorem dapibus rhoncus. Aenean eu elit non libero consectetuer viverra. Maecenas velit mi, eleifend vel, malesuada vel, condimentum quis, odio. Mauris tempus augue sed turpis. Pellentesque condimentum, lacus vitae pellentesque ultricies, risus tellus posuere nisi, et dictum turpis pede nec elit. Sed eu lectus eu justo sagittis euismod. Vestibulum lobortis, urna id mollis rhoncus, orci quam euismod ligula, at malesuada lacus magna vitae massa. Phasellus mattis fermentum velit. Nulla vulputate consequat enim. Maecenas quis neque. Curabitur sagittis facilisis neque. In elementum, eros non porttitor rhoncus, libero turpis sodales odio, vitae porta tellus purus et ante. Nullam molestie sollicitudin metus. Donec a elit. Morbi ut lacus. Donec at arcu. Quisque velit diam, interdum a, lacinia at, varius et, odio. Cras neque magna, ornare id, sollicitudin id, consequat a, est. Phasellus vestibulum est at leo. Nam facilisis, nulla dapibus condimentum pellentesque, est magna viverra ligula, at sollicitudin urna augue ut sapien. Fusce justo.";
+ startTime = new Date();
+ testSHA(longText, '0xf6fac13c06784e0fbc61a3d25c41c9984840a8b617a2beb57cf6fa3e5e4a8949');
+ endTime = new Date();
+
+ is((endTime - startTime) < 100, true, "Long text hash performance (" + (endTime - startTime) + ")");
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+}
+
+//=============================================================================
+
+SimpleTest.runDeferredTests("Clipperz.Crypto.SHA", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/SRP.html b/frontend/gamma/tests/tests/Clipperz/Crypto/SRP.html
new file mode 100644
index 0000000..63278c4
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/SRP.html
@@ -0,0 +1,161 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+hashString = function(aValue) {
+ return Clipperz.Crypto.SHA.sha256(new Clipperz.ByteArray(aValue)).toHexString().substring(2)
+}
+try {
+ var username;
+ var passphrase;
+
+ var C;
+ var P;
+ var encryptedText_1;
+ var encryptedText_2;
+ var salt;
+ var x;
+ var v;
+ var v1;
+
+ username = "giulio.cesare";
+ passphrase = "trustno1";
+
+ C = hashString(username);
+ is (C, "bde3c7b5fdcd9d6ce72782ca1ae912fc4397d668fcb3a73a04e5d47852670c4a", "C");
+
+ P = hashString(passphrase + username);
+ is (P, "d79f5c5a04e91e1c85fb64cb6ee9481cb52c181047f69da02cd6c3ce6d058a76", "P");
+
+ salt = "cf1fa93393ade60318b8276f1f39420098419445005a7dc9117975fe1f8d9988";
+
+ x = hashString(salt + P);
+ is(x, "21fe88a158e420aade86e00b5eb12a4c19bf15482fa34c542c90b1afdbd5b5fd", "x");
+
+ v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n());
+ is(v.asString(10), "33816467430011076413789931449607305355248467973000153409872503376381719918118", "v");
+ is(v.asString(16), "4ac37139dbf32ebabd2c43f91dd085066d3c457d059efd5902d32ed247fcb626", "v (base 16)");
+
+// encryptedText_1 = Clipperz.Crypto.Base.encryptUsingSecretKey(passphrase, username);
+// encryptedText_2 = Clipperz.Crypto.Base.encryptUsingSecretKey(passphrase, username);
+// is (encryptedText_1 != encryptedText_2, true, "Two round of encryption (with random padding bits) should NOT produce the same result");
+
+ //-------------------------------------------------------------------------
+
+ username = "giulio.cesare.debug";
+ passphrase = "trustno1";
+
+ C = hashString(username);
+ is (C, "fa1af609123b97a10d676158ed538d4657a89ac33a102b22bd9a66712039e208", "C");
+
+ P = hashString(passphrase + username);
+ is (P, "e1bfba03dd626b12f29458a6ad63fb2c01b4765548504e1e2f6b1503c82e4253", "P");
+
+ salt = "cf1fa93393ade60318b8276f1f39420098419445005a7dc9117975fe1f8d9988";
+
+ x = hashString(salt + P);
+ is(x, "93d4af3cdcd2447a745d309826dff3161feed4b15f32db8e909ff032a2bc8fb8", "x");
+
+ v = Clipperz.Crypto.SRP.g().powerModule(new Clipperz.Crypto.BigInt(x, 16), Clipperz.Crypto.SRP.n());
+ is(v.asString(10), "115049747015252903452664067168789229427785288458366249918596663144588656606556", "v");
+
+// encryptedText_1 = Clipperz.Crypto.Base.encryptUsingSecretKey(passphrase, username);
+// encryptedText_2 = Clipperz.Crypto.Base.encryptUsingSecretKey(passphrase, username);
+// is (encryptedText_1 != encryptedText_2, true, "Two round of encryption (with random padding bits) should NOT produce the same result");
+
+ //-------------------------------------------------------------------------
+
+ var srpConnection;
+ var C, P, salt;
+
+ C = "da8602c2f847306f4eb9acdaad925277d1fad1408f173f128a078aea15e60b1e";
+ P = "77643559beca49dd21c1c31db10bb0a9009662cb504413dc3fa3b7303c7e02ba";
+ salt = "000108cbbacda1f03ea9360301045434ec7d82ba150936df08a229cbb4832ce1";
+
+ srpConnection = new Clipperz.Crypto.SRP.Connection({C:C, P:P, hash:Clipperz.Crypto.SHA.sha_d256});
+ srpConnection._a = new Clipperz.Crypto.BigInt("37532428169486597638072888476611365392249575518156687476805936694442691012367", 10);
+ srpConnection.set_s(new Clipperz.Crypto.BigInt(salt, 16));
+ is (srpConnection.s().asString(16, 64), salt, "salt read/write is coherent");
+ srpConnection.set_B(new Clipperz.Crypto.BigInt("123541032067854367017620977654446651448957899464139861291542193929199957895435", 10));
+
+ is( srpConnection.serverSideCredentialsWithSalt(salt).v,
+ "c73169c8236d37bf9ef11a2349e3064b7dc6e883a58d64443ea9235677520030",
+ "server side credentials - v"
+ )
+ is(srpConnection.S(), "84134227508133659832466942692590826994401065200828529664948840490489960952050", "Server side 'S'");
+//MochiKit.Logging.logDebug("=== serverSideCredentials: " + MochiKit.Base.serializeJSON(srpConnection.serverSideCredentialsWithSalt(salt)));
+
+ srpConnection = new Clipperz.Crypto.SRP.Connection({C:C, P:P, hash:Clipperz.Crypto.SHA.sha_d256});
+ try {
+ srpConnection.set_B(new Clipperz.Crypto.BigInt("0", 10));
+ ok(false, "Setting B to 0 should raise an exception");
+ } catch(e) {
+ ok(true, "Setting B to 0 should raise an exception");
+ }
+ //-------------------------------------------------------------------------
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/Usage.html b/frontend/gamma/tests/tests/Clipperz/Crypto/Usage.html
new file mode 100644
index 0000000..63f7610
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/Usage.html
@@ -0,0 +1,122 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.Crypto.Usage - TEST</title>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+
+MochiKit.Base.update(Clipperz, {
+ 'PM': {
+ 'Crypto': {
+ 'passwordEntropy': function(aValue) {
+ var result;
+ var bitPerChar;
+
+ bitPerChar = 4;
+ if (/[a-z]/.test(aValue)) {
+ bitPerChar ++;
+ }
+ if (/[A-Z]/.test(aValue)) {
+ bitPerChar ++;
+ }
+ if (/[^a-zA-Z0-9]/.test(aValue)) {
+ bitPerChar ++;
+ }
+ //MochiKit.Logging.logDebug("--- bitPerChar: " + bitPerChar);
+
+ result = aValue.length * bitPerChar;
+
+ return result;
+ }
+ }
+ }
+})
+
+try {
+ var keyValue;
+ var keyEntropy;
+ var key;
+ var plainText;
+ var cypherText;
+ var randomBytes;
+ var hashedValue;
+
+ key = Clipperz.Crypto.SHA.sha256(new Clipperz.ByteArray("This is my long and complex passphrase"));
+ keyEntropy = Clipperz.PM.Crypto.passwordEntropy(key);
+
+ cypherText = Clipperz.Crypto.AES.encrypt(key, new Clipperz.ByteArray("some text to encrypt"));
+ plainText = Clipperz.Crypto.AES.decrypt(key, cypherText).asString();
+ is(plainText, "some text to encrypt");
+
+ randomBytes = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(256/8);
+ hashedValue = Clipperz.Crypto.SHA.sha256(new Clipperz.ByteArray("text to hash"));
+
+//#############################################################################
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/index.html b/frontend/gamma/tests/tests/Clipperz/Crypto/index.html
new file mode 100644
index 0000000..67487ac
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/index.html
@@ -0,0 +1,58 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.Crypto.* - tests</title>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/TestRunner.js"></script>
+</head>
+<body>
+<script>
+TestRunner.runTests(
+ 'AES.html',
+ 'AES.performance.html',
+ 'Base.html',
+ 'BigInt.html',
+
+// 'ECC.B283.deferred.html',
+// 'ECC.BinaryField.FiniteField.html',
+// 'ECC.BinaryField.FiniteField.B283.html',
+// 'ECC.BinaryField.Value.html',
+//# 'ECC.K283.deferred.html',
+
+ 'PRNG.html',
+// 'RSA.html',
+ 'SHA.html',
+ 'SRP.html',
+ 'Usage.html'
+);
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Clipperz/Crypto/jscrypto.js b/frontend/gamma/tests/tests/Clipperz/Crypto/jscrypto.js
new file mode 100644
index 0000000..e9db091
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Crypto/jscrypto.js
@@ -0,0 +1,1577 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+/* jsCrypto
+Core AES
+
+Emily Stark (estark@stanford.edu)
+Mike Hamburg (mhamburg@stanford.edu)
+Dan Boneh (dabo@cs.stanford.edu)
+
+Symmetric AES in Javascript using precomputed lookup tables for round transformations rather for speed improvements
+and code size reduction. Provides authenticated encryption in OCB and CCM modes.
+Parts of this code are based on the OpenSSL implementation of AES: http://www.openssl.org
+
+Public domain, 2009.
+
+*/
+
+
+// CCM mode is the default
+var CCM = 1, OCB = 2;
+
+/* aes object constructor. Takes as arguments:
+- 16-byte key, or an array of 4 32-bit words
+- Optionally specify a mode (aes.OCB or aes.CCM). Defaults to CCM
+- Optionally specify a MAC tag length for integrity. Defaults to 16 bytes
+*/
+function aes(key, mode, Tlen) {
+ // initialize objects for CCM and OCB modes
+ this._CCM = new cipherCCM(this);
+ this._OCB = new cipherOCB(this);
+
+ this._decryptScheduled = false;
+
+ if (mode) this._mode = mode;
+ else this._mode = OCB;
+
+ // AES round constants
+ this._RCON = [
+ [0x00, 0x00, 0x00, 0x00],
+ [0x01, 0x00, 0x00, 0x00],
+ [0x02, 0x00, 0x00, 0x00],
+ [0x04, 0x00, 0x00, 0x00],
+ [0x08, 0x00, 0x00, 0x00],
+ [0x10, 0x00, 0x00, 0x00],
+ [0x20, 0x00, 0x00, 0x00],
+ [0x40, 0x00, 0x00, 0x00],
+ [0x80, 0x00, 0x00, 0x00],
+ [0x1b, 0x00, 0x00, 0x00],
+ [0x36, 0x00, 0x00, 0x00]
+ ];
+
+ this._key_len = 16;
+ if (key.length == 4) {
+ this._key = [];
+ aes.wordsToBytes(key, this._key);
+ }
+ else
+ this._key = key;
+
+ if (Tlen) this._Tlen = Tlen;
+ else this._Tlen = 16; // tag length in bytes
+
+ this._nr = 10;
+
+ // initialize tables that will be precomputed
+ this._SBOX = [];
+ this._INV_SBOX = [];
+ this._T = new Array(4);
+ this._Tin = new Array(4);
+ for (var i=0; i < 4; i++) {
+ this._T[i] = [];
+ this._Tin[i] = [];
+ }
+
+ this._precompute();
+ this.scheduleEncrypt();
+
+ // initialize encryption and decryption buffers
+ this._ctBuffer = [];
+ this._ptBuffer = [];
+}
+
+
+//////////////////
+// KEY SCHEDULING
+//////////////////
+
+aes.prototype.scheduleEncrypt = function () {
+ this._decryptScheduled = false;
+
+ this._w = new Array(this._nr+1);
+ this._w[0] = new Array(4);
+ for (var i=0; i < 4; i++)
+ this._w[0][i] = this._key[i];
+ var temp = new Array(4);
+ for (var i=1; i < this._nr+1; i++) {
+ temp[0] = this._w[i-1][3];
+ this._w[i] = new Array(4);
+ temp[0] = (this._T[2][(temp[0]>>>16)&0xff] & 0xff000000) ^ (this._T[3][(temp[0]>>>8)&0xff]&0x00ff0000) ^ (this._T[0][(temp[0]&0xff)]&0x0000ff00) ^ (this._T[1][(temp[0]>>>24)]&0x000000ff) ^ (this._RCON[i][0]<<24);
+ this._w[i][0] = this._w[i-1][0] ^ temp[0];
+ for (var j=1; j < 4; j++) {
+ temp[j] = this._w[i][j-1];
+ this._w[i][j] = this._w[i-1][j] ^ temp[j];
+ }
+ }
+};
+
+aes.prototype.scheduleDecrypt = function() {
+
+ if (!this._w) this.scheduleEncrypt();
+ this._decryptScheduled = true;
+ var temp = [];
+ var j = this._w.length-1;
+ for (var i=0; i<j; i++) {
+ temp[0] = this._w[i][0];
+ temp[1] = this._w[i][1];
+ temp[2] = this._w[i][2];
+ temp[3] = this._w[i][3];
+ this._w[i][0] = this._w[j][0];
+ this._w[i][1] = this._w[j][1];
+ this._w[i][2] = this._w[j][2];
+ this._w[i][3] = this._w[j][3];
+ this._w[j][0] = temp[0];
+ this._w[j][1] = temp[1];
+ this._w[j][2] = temp[2];
+ this._w[j][3] = temp[3];
+ j--;
+ }
+
+ var td0 = this._Tin[0], td1 = this._Tin[1], td2 = this._Tin[2], td3 = this._Tin[3], te1 = this._T[1];
+ for (var i=1; i < this._w.length-1; i++) {
+ this._w[i][0] = td0[te1[(this._w[i][0] >>> 24) ] & 0xff] ^
+ td1[te1[(this._w[i][0] >>> 16) & 0xff] & 0xff] ^
+ td2[te1[(this._w[i][0] >>> 8) & 0xff] & 0xff] ^
+ td3[te1[(this._w[i][0] ) & 0xff] & 0xff];
+ this._w[i][1] = td0[te1[(this._w[i][1] >>> 24) ] & 0xff] ^
+ td1[te1[(this._w[i][1] >>> 16) & 0xff] & 0xff] ^
+ td2[te1[(this._w[i][1] >>> 8) & 0xff] & 0xff] ^
+ td3[te1[(this._w[i][1] ) & 0xff] & 0xff];
+ this._w[i][2] = td0[te1[(this._w[i][2] >>> 24) ] & 0xff] ^
+ td1[te1[(this._w[i][2] >>> 16) & 0xff] & 0xff] ^
+ td2[te1[(this._w[i][2] >>> 8) & 0xff] & 0xff] ^
+ td3[te1[(this._w[i][2] ) & 0xff] & 0xff];
+ this._w[i][3] = td0[te1[(this._w[i][3] >>> 24) ] & 0xff] ^
+ td1[te1[(this._w[i][3] >>> 16) & 0xff] & 0xff] ^
+ td2[te1[(this._w[i][3] >>> 8) & 0xff] & 0xff] ^
+ td3[te1[(this._w[i][3] ) & 0xff] & 0xff];
+ }
+};
+
+
+/////////////////////////
+// ENCRYPTION/DECRYPTION
+/////////////////////////
+
+
+/* Authenticated encryption on a multi-block message in OCB or CCM mode.
+iv should be an array of 32-bit words - either 4 words for OCB mode or 1, 2, or 3 words for CCM.
+Use a unique IV for every message encrypted.
+The plaintext argument will be encrypted and MACed; adata will be sent in plaintext but MACed.
+Plaintext and adata are strings.
+ciphertext is an array of bytes. tag is an array of 32-bit words.
+*/
+aes.prototype.encrypt = function(iv, plaintext, ciphertext, adata, tag) {
+ var plaintextBytes = [], adataBytes = [];
+ aes.asciiToBytes(plaintext, plaintextBytes);
+ aes.asciiToBytes(adata, adataBytes);
+
+ this._iv = iv;
+ if (this._mode == CCM)
+ this._CCM.encrypt(plaintextBytes, ciphertext, adataBytes, tag);
+ else if (this._mode == OCB) {
+ this._OCB.encrypt(plaintextBytes, ciphertext, adataBytes, tag);
+ }
+
+ // prepend to the ciphertext the length of the iv (in bytes) and the iv
+ var ivbytes=[];
+ aes.wordsToBytes(iv, ivbytes);
+ var ct = [iv.length*4].concat(ivbytes, ciphertext);
+ for (var i=0; i < ct.length; i++) ciphertext[i] = ct[i];
+
+ for (var i=0; i < ciphertext.length; i++)
+ this._ctBuffer[this._ctBuffer.length] = ciphertext[i];
+
+};
+
+/* Authenticated decryption on a multi-block ciphertext in OCB or CCM mode.
+ciphertext is an array of bytes. tag is an array of 32-bit words.
+plaintext and adata are strings.
+*/
+aes.prototype.decrypt = function(ciphertext, adata, tag) {
+ var ivlen = ciphertext[0];
+ var ivbytes = ciphertext.slice(1, ivlen+1);
+ var iv = [];
+ aes.bytesToWords(ivbytes, iv);
+ this._iv = iv;
+ var ct = ciphertext.slice(ivlen+1);
+
+ var valid = false;
+ var plaintextBytes = [], adataBytes = [];
+ aes.asciiToBytes(adata, adataBytes);
+ if (this._mode == CCM)
+ valid = this._CCM.decrypt(ct, plaintextBytes, adataBytes);
+ else if (this._mode == OCB)
+ valid = this._OCB.decrypt(ct, plaintextBytes, adataBytes, tag);
+ if (valid) {
+ var plaintext = aes.bytesToAscii(plaintextBytes);
+ for (var i=0; i < plaintext.length; i++)
+ this._ptBuffer[this._ptBuffer.length] = plaintext.charAt(i);
+ return plaintext;
+ }
+ return "";
+};
+
+// MACs (but doesn't encrypt) data using CMAC (in CCM mode) or PMAC (in OCB mode)
+aes.prototype.sign = function(data, tag) {
+ if (this._mode == CCM)
+ this._CCM.CMAC(data, "", tag, this._Tlen, false);
+ else if (this._mode == OCB) {
+ this._OCB.PMAC(data, tag);
+ }
+};
+
+// Verifies a CMAC or PMAC tag
+aes.prototype.verify = function(data, tag) {
+ var validTag = [];
+ if (this._mode == CCM)
+ this._CCM.CMAC(data, "", validTag, this._Tlen, false);
+ else if (this._mode == OCB) {
+ this._OCB.PMAC(data, validTag);
+ }
+ if (validTag.length != tag.length) return false;
+ for (var i=0; i < tag.length; i++) {
+ if (tag[i] != validTag[i]) return false;
+ }
+ return true;
+};
+
+/* Encrypts a single block message in AES. Takes the plaintext, an array in which to dump
+the ciphertext, and a boolean decrypt argument. If set to true, this function acts as
+a decryption function.
+block and ciphertext are both arrays of 4 32-bit words.
+*/
+aes.prototype.encryptBlock = function(block, ciphertext, decrypt) {
+ if (!decrypt && this._decryptScheduled) this.scheduleEncrypt();
+
+ // get key schedule
+ var w = this._w;
+ // load round transformation tables
+ var te0, te1, te2, te3;
+ if (decrypt) {
+ te0 = this._Tin[0];
+ te1 = this._Tin[1];
+ te2 = this._Tin[2];
+ te3 = this._Tin[3];
+ } else {
+ te0 = this._T[0];
+ te1 = this._T[1];
+ te2 = this._T[2];
+ te3 = this._T[3];
+ }
+
+ // perform rounds
+ var rk = w[0];
+ var s0 = block[0] ^ rk[0];
+ var s1 = block[1] ^ rk[1];
+ var s2 = block[2] ^ rk[2];
+ var s3 = block[3] ^ rk[3];
+ var t0,t1,t2,t3;
+ rk = w[1];
+ var order = [];
+ for (var round = 1; round < w.length-1; round++) {
+ order = [s1, s2, s3, s0];
+ if (decrypt) order = [s3, s0, s1, s2];
+ t0 = te0[(s0>>>24)] ^ te1[(order[0]>>>16) & 0xff]^ te2[(s2>>>8)&0xff] ^ te3[order[2]&0xff] ^ rk[0];
+ t1 = te0[(s1>>>24)] ^ te1[(order[1]>>>16) & 0xff]^ te2[(s3>>>8)&0xff] ^ te3[order[3]&0xff] ^ rk[1];
+ t2 = te0[(s2>>>24)] ^ te1[(order[2]>>>16) & 0xff]^ te2[(s0>>>8)&0xff] ^ te3[order[0]&0xff] ^ rk[2];
+ t3 = te0[(s3>>>24)] ^ te1[(order[3]>>>16) & 0xff]^ te2[(s1>>>8)&0xff] ^ te3[order[1]&0xff] ^ rk[3];
+ s0 = t0;
+ s1 = t1;
+ s2 = t2;
+ s3 = t3;
+ rk = w[round+1];
+ }
+ if (decrypt) {
+ s0 = ((this._INV_SBOX[(t0>>>24)])<<24) ^ ((this._INV_SBOX[(t3>>>16)&0xff])<<16) ^ ((this._INV_SBOX[(t2>>>8)&0xff])<<8) ^ (this._INV_SBOX[(t1)&0xff]) ^ rk[0];
+ s1 = ((this._INV_SBOX[(t1>>>24)])<<24) ^ ((this._INV_SBOX[(t0>>>16)&0xff])<<16) ^ ((this._INV_SBOX[(t3>>>8)&0xff])<<8) ^ (this._INV_SBOX[(t2)&0xff]) ^ rk[1]
+ s2 = ((this._INV_SBOX[(t2>>>24)])<<24) ^ ((this._INV_SBOX[(t1>>>16)&0xff])<<16) ^ ((this._INV_SBOX[(t0>>>8)&0xff])<<8) ^ (this._INV_SBOX[(t3)&0xff]) ^ rk[2];
+ s3 = (this._INV_SBOX[(t3>>>24)]<<24) ^ (this._INV_SBOX[(t2>>>16)&0xff]<<16) ^ (this._INV_SBOX[(t1>>>8)&0xff]<<8) ^ (this._INV_SBOX[(t0)&0xff]) ^ rk[3];
+ } else {
+ s0 = (te2[t0>>>24]&0xff000000) ^ (te3[(t1>>>16)&0xff]&0x00ff0000) ^ (te0[(t2>>>8)&0xff]&0x0000ff00) ^ (te1[(t3)&0xff]&0x000000ff) ^ rk[0];
+ s1 = (te2[t1>>>24]&0xff000000) ^ (te3[(t2>>>16)&0xff]&0x00ff0000) ^ (te0[(t3>>>8)&0xff]&0x0000ff00) ^ (te1[(t0)&0xff]&0x000000ff) ^ rk[1];
+ s2 = (te2[t2>>>24]&0xff000000) ^ (te3[(t3>>>16)&0xff]&0x00ff0000) ^ (te0[(t0>>>8)&0xff]&0x0000ff00) ^ (te1[(t1)&0xff]&0x000000ff) ^ rk[2];
+ s3 = (te2[t3>>>24]&0xff000000) ^ (te3[(t0>>>16)&0xff]&0x00ff0000) ^ (te0[(t1>>>8)&0xff]&0x0000ff00) ^ (te1[(t2)&0xff]&0x000000ff) ^ rk[3];
+ }
+ ciphertext[0] = s0;
+ ciphertext[1] = s1;
+ ciphertext[2] = s2;
+ ciphertext[3] = s3;
+};
+
+// As above, block and plaintext are arrays of 4 32-bit words.
+aes.prototype.decryptBlock = function(block, plaintext) {
+ if (!this._decryptScheduled) this.scheduleDecrypt();
+
+ this.encryptBlock(block, plaintext, true);
+};
+
+
+////////////////////
+// HELPER FUNCTIONS
+////////////////////
+
+aes._hex = function(n) {
+ var out = "",i,digits="0123456789ABCDEF";
+ for (i=0; i<8; i++) {
+ var digit = n&0xF;
+ out = digits.substring(digit,digit+1) + out;
+ n = n >>> 4;
+ }
+ return out;
+}
+
+aes._hexall = function(nn) {
+ var out = "",i;
+ for (i=0;i<nn.length;i++) {
+ if (i%4 == 0) out+= "<br/>\n";
+ else if (i) out += " ";
+ out += aes._hex(nn[i]);
+ }
+ return out;
+}
+
+aes.bytesToAscii = function(bytes) {
+ var ascii = "";
+ var len = bytes.length;
+ for (var i=0; i < len; i++) {
+ ascii = ascii + String.fromCharCode(bytes[i]);
+ }
+ return ascii;
+};
+
+aes.asciiToBytes = function(ascii, bytes) {
+ var len = ascii.length;
+ for (var i=0; i < len; i++)
+ bytes[i] = ascii.charCodeAt(i);
+};
+
+aes.wordsToBytes = function(words, bytes) {
+ var bitmask = 1;
+ for (var i=0; i < 7; i++) bitmask = (bitmask << 1) | 1;
+ for (var i=0; i < words.length; i++) {
+ var bstart = i*4;
+ for (var j=0; j < 4; j++) {
+ bytes[bstart+j] = (words[i] & (bitmask << (8*(3-j)))) >>> (8*(3-j));
+ }
+ }
+};
+
+aes.bytesToWords = function(bytes, words) {
+ var paddedBytes = bytes.slice();
+ while (paddedBytes.length % 4 != 0) paddedBytes.push(0);
+ var num_words = Math.floor(paddedBytes.length/4);
+ for (var j=0; j < num_words; j++)
+ words[j] = ((paddedBytes[(j<<2)+3]) | (paddedBytes[(j<<2)+2] << 8) | (paddedBytes[(j<<2)+1] << 16) | (paddedBytes[j<<2] << 24));
+};
+
+
+///////////////////////////////////////
+// KEY DERIVATION
+//////////////////////////////////////
+
+// password is a string, presumably a password entered by the user.
+// salt is eight random bytes associated with each user
+// This function returns an array of bytes of length 16
+function generateKey(password, salt) {
+ var pwBytes = [];
+ aes.asciiToBytes(password, pwBytes);
+ var pwWords = [], saltWords = [];
+ aes.bytesToWords(pwBytes, pwWords);
+ aes.bytesToWords(salt, saltWords);
+
+ var iterations = 1000;
+
+ var derivedKey = [];
+ var blockIndex = 1;
+
+ var xorHashes = function(h1, h2) {
+ var xor = [];
+ var i;
+ for (i=0; i < h1.length; i++) xor.push(h1[i] ^ h2[i]);
+ return xor;
+ };
+
+ while (derivedKey.length < 16) {
+ var hashBytes = pwWords.concat(saltWords);
+ hashBytes.push(blockIndex);
+ var T = SHA256.hash_words_big_endian(hashBytes);
+ var u = T;
+ for (var i=2; i < iterations; i++) {
+ var hash = SHA256.hash_words_big_endian(pwWords.concat(u));
+ u = xorHashes(T, hash);
+ }
+ var block = [];
+ aes.wordsToBytes(T, block);
+ for (var i=0; i < block.length; i++) derivedKey.push(block[i]);
+ }
+
+ if (derivedKey.length > 16) derivedKey.length = 16;
+ return derivedKey;
+}
+
+///////////////////////////////////////
+// ROUND TRANSFORMATION PRECOMPUTATION
+///////////////////////////////////////
+
+
+// Precomputation code by Mike Hamburg
+
+aes.prototype._precompute = function() {
+ var x,xi,sx,tx,tisx,i;
+ var d=[];
+
+ /* compute double table */
+ for (x=0;x<256;x++) {
+ d[x]= x&128 ? x<<1 ^ 0x11b : x<<1;
+ //d[x] = x<<1 ^ (x>>7)*0x11b; //but I think that's less clear.
+ }
+
+ /* Compute the round tables.
+ *
+ * We'll need access to x and x^-1, which we'll get by walking
+ * GF(2^8) as generated by (82,5).
+ */
+ for(x=xi=0;;) {
+ // compute sx := sbox(x)
+ sx = xi^ xi<<1 ^ xi<<2 ^ xi<<3 ^ xi<<4;
+ sx = sx>>8 ^ sx&0xFF ^ 0x63;
+
+ var dsx = d[sx], x2=d[x],x4=d[x2],x8=d[x4];
+
+ // te(x) = rotations of (2,1,1,3) * sx
+ tx = dsx<<24 ^ sx<<16 ^ sx<<8 ^ sx^dsx;
+
+ // similarly, td(sx) = (E,9,D,B) * x
+ tisx = (x8^x4^x2) <<24 ^
+ (x8^x ) <<16 ^
+ (x8^x4^x ) << 8 ^
+ (x8^x2^x );
+
+ // This can be done by multiplication instead but I think that's less clear
+ // tisx = x8*0x1010101 ^ x4*0x1000100 ^ x2*0x1000001 ^ x*0x10101;
+ // tx = dsx*0x1000001^sx*0x10101;
+
+ // rotate and load
+ for (i=0;i<4;i++) {
+ this._T[i][x] = tx;
+ this._Tin[i][sx] = tisx;
+ tx = tx<<24 | tx>>>8;
+ tisx = tisx<<24 | tisx>>>8;
+ }
+
+ // te[4] is the sbox; td[4] is its inverse
+ this._SBOX[ x] = sx;
+ this._INV_SBOX[sx] = x;
+
+
+ // wonky iteration goes through 0
+ if (x==5) {
+ break;
+ } else if (x) {
+ x = x2^d[d[d[x8^x2]]]; // x *= 82 = 0b1010010
+ xi ^= d[d[xi]]; // xi *= 5 = 0b101
+ } else {
+ x=xi=1;
+ }
+ }
+
+ // We computed the arrays out of order. On Firefox, this matters.
+ // Compact them.
+ for (i=0; i<4; i++) {
+ this._T[i] = this._T[i].slice(0);
+ this._Tin[i] = this._Tin[i].slice(0);
+ }
+ this._SBOX = this._SBOX.slice(0);
+ this._INV_SBOX = this._INV_SBOX.slice(0);
+
+
+};
+
+
+
+
+
+/* jsCrypto
+CCM mode
+
+Emily Stark (estark@stanford.edu)
+Mike Hamburg (mhamburg@stanford.edu)
+Dan Boneh (dabo@cs.stanford.edu)
+
+CCM mode for authenticated encryption of multiple 16-byte blocks. Uses AES as core cipher.
+
+Public domain, 2009.
+
+*/
+
+// Constructor takes an aes object as its core cipher
+function cipherCCM(cipher) {
+ this._cipher = cipher;
+}
+
+/* Formats plaintext and adata for MACing and encryption.
+adata and plaintext are arrays of bytes, B will be an array of arrays of 16 bytes
+Tlen specifies the number of bytes in the tag.
+Formatted according to the CCM specification.
+ */
+cipherCCM.prototype._formatInput = function(adata, plaintext, Tlen, B) {
+ // compute B[0]
+ var flags, nbytes=[];
+ aes.wordsToBytes(this._cipher._iv, nbytes);
+ if (adata) flags = 0x01<<6;
+ else flags = 0x00<<6;
+ flags = flags | (((Tlen-2)/2)<<3); // (t-2)/2
+ var q = 15-this._cipher._iv.length*4;
+ flags = flags | (q-1);
+ B[0] = new Array(16);
+ B[0][0] = flags;
+ for (var i=1; i <= 15-q; i++) B[0][i] = nbytes[i-1];
+ var Q = plaintext.length;
+
+ // make some bitmasks
+ var bitmask = 1;
+ for (var i=0; i < 7; i++) bitmask = (bitmask<<1) | 1;
+ for (var i=15; i > 15-q; i--) {
+ B[0][i] = Q & bitmask;
+ Q = Q>>>8;
+ }
+
+ // compute the blocks which identify adata
+ if (adata) {
+ var a = adata.length, Bind=1, BIind = 0, aind=0;
+ B[1] = new Array(16);
+ if (a < (2<<16 - 2<<8)) {
+ B[1][0] = a>>>8;
+ B[1][1] = a & bitmask;
+ BIind = 2;
+ } else if (a < (2<<32)) {
+ B[1][0] = 0xff;
+ B[1][1] = 0xfe;
+ for (var i=5; i >= 0; i--) {
+ B[1][2+i] = a & bitmask;
+ a = a>>>8;
+ }
+ BIind=8;
+ } else {
+ B[1][0] = 0xff;
+ B[1][0] = 0xff;
+ for (i=9; i >= 0; i--) {
+ B[1][2+i] = a & bitmask;
+ a = a >>> 8;
+ }
+ BIind = 12;
+ }
+ }
+
+ while (aind < adata.length) {
+ B[Bind][BIind] = adata[aind];
+ aind++;
+ if (BIind == 15) {
+ Bind++;
+ BIind = 0;
+ if (aind != adata.length) B[Bind] = new Array(16);
+ } else BIind++;
+ }
+ if (BIind != 0) {
+ while (BIind <= 15) {
+ B[Bind][BIind] = 0x00;
+ BIind++;
+ }
+ }
+
+ Bind++;
+ BIind=0;
+ B[Bind] = new Array(16);
+
+ // compute the payload blocks
+ var pind = 0;
+ while (pind < plaintext.length) {
+ B[Bind][BIind] = plaintext[pind];
+ pind++;
+ if (BIind == 15) {
+ Bind++;
+ BIind = 0;
+ if (pind != plaintext.length) B[Bind] = new Array(16);
+ } else BIind++;
+ }
+ if (BIind != 0) {
+ while (BIind <= 15) {
+ B[Bind][BIind] = 0x00;
+ BIind++;
+ }
+ }
+
+};
+
+/* Generate the blocks that will be used as counters.
+ctr will be an array of m+1 arrays of 16 bytes. */
+cipherCCM.prototype._generateCtrBlocks = function(m, ctr) {
+ var nbytes = [];
+ aes.wordsToBytes(this._cipher._iv, nbytes);
+ var flags = 15 - (this._cipher._iv.length*4) - 1;
+ var bitmask = 1;
+ for (var i=0; i < 7; i++) bitmask = (bitmask<<1) | 1;
+ for (var i=0; i <= m; i++) {
+ ctr[i] = new Array(16);
+ ctr[i][0] = flags;
+ for (var j=0; j < nbytes.length; j++) {
+ ctr[i][j+1] = nbytes[j];
+ }
+ for (var j=15; j > nbytes.length; j--) {
+ ctr[i][j] = (i>>>(8*(15-j))) & bitmask;
+ }
+ }
+
+};
+
+
+/* CBC-MAC adata and plaintext, and store the tag in tag.
+adata and plaintext are arrays of bytes
+tag will be an array of Tlen/4 32-bit words
+Tlen is an integer divisible by 4 that specifies the number of bytes in the tag.
+*/
+cipherCCM.prototype.CBCMAC = function(adata, plaintext, tag, Tlen, formatInput) {
+ var B = [];
+ if (formatInput)
+ this._formatInput(adata,plaintext,Tlen,B);
+ else {
+ var Sind = 0, SIind = 0, aind = 0, alen = adata.length;
+ B[0] = [];
+ while (aind < alen) {
+ B[Sind][SIind] = adata[aind];
+ SIind++;
+ if (SIind == 16) {
+ SIind = 0;
+ Sind++;
+ if (aind != alen-1) B[Sind] = [];
+ }
+ aind++;
+ }
+ }
+ var words = [];
+ var Yprev = [], Y = [];
+ aes.bytesToWords(B[0],words);
+ this._cipher.encryptBlock(words, Y);
+ var r = B.length, t = new Array(4);
+
+ for (var i=1; i < r; i++) {
+ for (var j=0; j < 4; j++) {
+ var bstart = j*4;
+ t[j] = Y[j] ^ ((B[i][bstart++]<<24) | (B[i][bstart++]<<16) | (B[i][bstart++]<<8) | (B[i][bstart++]));
+ Yprev[j] = Y[j];
+ }
+ this._cipher.encryptBlock(t, Y);
+ }
+ for (var i=0; i < Tlen/4; i++)
+ tag[i] = Y[i];
+};
+
+
+/* Provides authenticated encryption using CBCMAC and CTR-mode encryption on plaintext.
+adata is MACed but not encrypted.
+plaintext, adata, and tag are arrays of bytes
+Tlen is the number of bytes in the tag
+ciphertext will be an array of bytes. */
+cipherCCM.prototype.encrypt = function(plaintext, ciphertext, adata, tag) {
+ var Tlen = this._cipher._Tlen;
+ this.CBCMAC(adata, plaintext, tag, Tlen, true);
+ var ctr = [], m = Math.ceil(plaintext.length/16);
+ this._generateCtrBlocks(m, ctr);
+ var cblocks = [], S=[], t = new Array(4);
+ for (var i=0; i <= m; i++) {
+ S[i] = new Array(16);
+ aes.bytesToWords(ctr[i], cblocks);
+ this._cipher.encryptBlock(cblocks, t);
+ aes.wordsToBytes(t, S[i]);
+ }
+ var Sind = 1, SIind = 0;
+ for (var i=0; i < plaintext.length; i++) {
+ ciphertext[i] = plaintext[i] ^ S[Sind][SIind];
+ SIind++;
+ if (SIind == 16) {
+ Sind++;
+ SIind = 0;
+ }
+ }
+ var tbytes = [];
+ aes.wordsToBytes(tag, tbytes);
+ var cstart = plaintext.length;
+ for (var i=0; i < Tlen; i++)
+ ciphertext[cstart+i] = tbytes[i] ^ S[0][i];
+};
+
+
+/* Decrypt and verify the MAC on ciphertext and adata. The integrity of adata is verified, but isn't decrypted.
+ciphertext, adata are arrays of bytes
+plaintext will be an array of bytes
+Returns true if tag is valid, false otherwise.
+*/
+cipherCCM.prototype.decrypt = function(ciphertext, plaintext, adata) {
+ var Tlen = this._cipher._Tlen;
+ if (ciphertext.length <= Tlen) return false;
+ var ctr = [], tag = new Array(Tlen), m = Math.ceil(ciphertext.length/16);
+ this._generateCtrBlocks(m, ctr);
+ var S = [], t = new Array(4), cblocks=[];
+
+ for (var i=0; i <= m; i++) {
+ S[i] = new Array(16);
+ aes.bytesToWords(ctr[i], cblocks);
+ this._cipher.encryptBlock(cblocks, t);
+ aes.wordsToBytes(t, S[i]);
+ }
+
+ var Sind = 1, SIind = 0;
+ for (var i=0; i < (ciphertext.length-Tlen); i++) {
+ plaintext[i] = ciphertext[i] ^ S[Sind][SIind];
+ SIind++;
+ if (SIind == 16) {
+ SIind = 0;
+ Sind++;
+ }
+ }
+
+ for (var i=0; i < Tlen; i++)
+ tag[i] = ciphertext[ciphertext.length-Tlen+i] ^ S[0][i];
+
+ // verify integrity
+ var validTag = [], vtbytes = [];
+ this.CBCMAC(adata, plaintext, validTag, Tlen, true);
+ aes.wordsToBytes(validTag, vtbytes);
+ for (var i=0; i < Tlen; i++) {
+ if (vtbytes[i] != tag[i])
+ return false;
+ }
+ return true;
+
+};
+
+// Generate subkeys according to the CCM specification. */
+cipherCCM.prototype._generateSubkeys = function(k1,k2) {
+ var t = [0x00000000,0x00000000,0x00000000,0x00000000], t2 = new Array(4);
+ this._cipher.encryptBlock(t, t2);
+ for (var i=0; i < 3; i++)
+ k1[i] = t2[i]<<1 | t2[i+1]>>>31;
+ k1[3] = t2[3]<<1;
+ if (t2[0]>>>31 != 0)
+ k1[3] = k1[3] ^ 135;
+ for (var i=0; i < 3; i++)
+ k2[i] = k1[i]<<1 | k1[i+1]>>>31;
+ k2[3] = k1[3]<<1;
+ if (k1[0]>>>31 != 0)
+ k2[3] = k2[3] ^ 135;
+};
+
+
+/* CMAC used for integrity only (no encryption). */
+cipherCCM.prototype.CMAC = function(adata, plaintext, tag, Tlen, formatInput) {
+ var B = [], t = new Array(4); // will be an array of arrays of 16 bytes
+ if (formatInput)
+ this._formatInput(adata,plaintext,Tlen,B);
+ else {
+ var Sind = 0, SIind = 0, aind = 0, alen = adata.length;
+ B[0] = [];
+ while (aind < alen) {
+ B[Sind][SIind] = adata[aind];
+ SIind++;
+ if (SIind == 16) {
+ SIind = 0;
+ Sind++;
+ if (aind != alen-1) B[Sind] = [];
+ }
+ aind++;
+ }
+ }
+ var k1 = new Array(4), k2 = new Array(4);
+ this._generateSubkeys(k1,k2);
+ var last = B.length-1, kbytes = [];
+ if (alen % 16 == 0) {
+ aes.wordsToBytes(k1, kbytes);
+ } else {
+ aes.wordsToBytes(k2, kbytes);
+ B[last][B[last].length] = 1<<7;
+ while (B[last].length % 16 != 0)
+ B[last][B[last].length] = 0x00;
+ }
+ for (var i=0; i < 16; i++) B[last][i] = B[last][i] ^ kbytes[i];
+ var C = [0x00000000,0x00000000,0x00000000,0x00000000], Cprev = new Array(4), words = new Array(4);
+ for (var i=0; i < B.length; i++) {
+ aes.bytesToWords(B[i], words);
+ for (var j=0; j < 4; j++) {
+ Cprev[j] = C[j];
+ t[j] = C[j] ^ words[j];
+ }
+ this._cipher.encryptBlock(t, C);
+ }
+ var cbytes=[];
+ aes.wordsToBytes(C, cbytes);
+ for (var i=0; i < Tlen; i++)
+ tag[i] = cbytes[i];
+
+};
+
+
+
+/* jsCrypto
+OCB mode
+
+Emily Stark (estark@stanford.edu)
+Mike Hamburg (mhamburg@stanford.edu)
+Dan Boneh (dabo@cs.stanford.edu)
+
+OCB mode for authenticated encryption of multiple 16-byte blocks. Uses AES as core cipher.
+
+Public domain, 2009.
+*/
+
+/* Constructor takes an aes object as the core cipher. */
+function cipherOCB(cipher) {
+ this._cipher = cipher;
+}
+
+
+/* Provides integrity only, no encryption.
+header is an array of bytes, tag will be an array of 4 32-bit words */
+cipherOCB.prototype.PMAC = function(header, tag) {
+ var carry, t = new Array(4), t2 = new Array(4), Checksum = [0x00000000,0x00000000,0x00000000,0x00000000];
+ var Offset = new Array(4);
+ this._cipher.encryptBlock(Checksum, Offset);
+ this._times2(t, Offset);
+ for (var i=0; i < 4; i++) Offset[i] = t[i] ^ Offset[i];
+ this._times2(t, Offset);
+ for (var i=0; i < 4; i++) Offset[i] = t[i] ^ Offset[i];
+
+ // accumulate all but the last block
+ var num_blocks = Math.floor((header.length-1)/16);
+ for (var i=0; i < num_blocks; i++) {
+ this._times2(Offset,Offset);
+ var bstart = i*16; // start-of-block index
+ for (var j=0; j < 4; j++)
+ t[j] = Offset[j] ^ ((header[bstart+(j<<2)+3]) | (header[bstart+(j<<2)+2] << 8) | (header[bstart+(j<<2)+1] << 16) | (header[bstart+(j<<2)] << 24));
+ this._cipher.encryptBlock(t, t2);
+ for (var j=0; j < 4; j++) Checksum[j] = Checksum[j] ^ t2[j];
+ }
+
+ // accumulate the last block
+ this._times2(Offset,Offset);
+
+ if (header.length%16 == 0) {
+ var bstart = header.length-16;
+ for (var j=0; j < 4; j++)
+ Checksum[j] = Checksum[j] ^ ((header[bstart+(j<<2)+3]) | (header[bstart+(j<<2)+2] << 8) | (header[bstart+(j<<2)+1] << 16) | (header[bstart+(j<<2)] << 24));
+ this._times2(t, Offset);
+ for (var i=0; i < 4; i++) Offset[i] = Offset[i] ^ t[i];
+ } else {
+ var block_bytes = [], block = new Array(4), len = header.length, ind=0;
+ for (var i=(header.length-(header.length%16)); i < len; i++) {
+ block_bytes[ind] = header[i];
+ ind++;
+ }
+ block_bytes[ind] = 0x80;
+ ind++;
+ while (block_bytes.length%16 != 0) {
+ block_bytes[ind] = 0x00;
+ ind++;
+ }
+ aes.bytesToWords(block_bytes,block);
+ for (var j=0; j < 4; j++) {
+ var bstart = 4*j;
+ Checksum[j] = Checksum[j] ^ ((block_bytes[bstart++]<<24) | (block_bytes[bstart++]<<16) | (block_bytes[bstart++]<<8) | (block_bytes[bstart++]));
+ }
+ this._times2(t, Offset);
+ for (var i=0; i < 4; i++) Offset[i] = Offset[i] ^ t[i];
+ this._times2(t, Offset);
+ for (var i=0; i < 4; i++) Offset[i] = Offset[i] ^ t[i];
+ }
+
+ // compute result
+ for (var i=0; i < 4; i++) t[i] = Offset[i] ^ Checksum[i];
+ this._cipher.encryptBlock(t, tag);
+};
+
+
+/* Encrypts and MACs plaintext, only MACS header.
+plaintext, ciphertext and header are arrays of bytes. tag will be an array of 4 32-bit words. */
+cipherOCB.prototype.encrypt = function(plaintext, ciphertext, header, tag) {
+ var Checksum = [0x00000000,0x00000000,0x00000000,0x00000000];
+ var t = [0x00000000,0x00000000,0x00000000,0x00000000], t2 = new Array(4);
+ var Offset = new Array(4);
+ this._cipher.encryptBlock(this._cipher._iv, Offset);
+ var cbytes = [];
+
+ // encrypt and accumulate all but last block
+ var num_blocks = Math.floor((plaintext.length-1)/16), bstart=0, block = new Array(4);
+ for (var i=0; i < num_blocks; i++) {
+ this._times2(Offset,Offset);
+ bstart = 16*i;
+ for (var j=0; j < 4; j++)
+ block[j] = ((plaintext[bstart+(j<<2)+3]) | (plaintext[bstart+(j<<2)+2] << 8) | (plaintext[bstart+(j<<2)+1] << 16) | (plaintext[bstart+(j<<2)] << 24));
+ for (var j=0; j < 4; j++)
+ t[j] = Offset[j] ^ block[j];
+ this._cipher.encryptBlock(t,t2);
+ for (var j=0; j < 4; j++) t[j] = Offset[j] ^ t2[j];
+ aes.wordsToBytes(t, cbytes);
+ for (var j=0; j < 16; j++) ciphertext[bstart+j] = cbytes[j];
+ for (var j=0; j < 4; j++) Checksum[j] = Checksum[j] ^ block[j];
+ }
+
+ // encrypt and accumulate last block
+ var num_bytes = plaintext.length%16;
+ if ((num_bytes == 0) && (plaintext.length > 0)) num_bytes=16;
+ this._times2(Offset,Offset);
+ t = [0x00000000,0x00000000,0x00000000,0x00000000];
+ t[3] = num_bytes*8;
+ for (var i=0; i < 4; i++) t[i] = Offset[i] ^ t[i];
+ var Pad = new Array(4);
+ this._cipher.encryptBlock(t, Pad);
+ var pad_bytes = new Array(16);
+ aes.wordsToBytes(Pad, pad_bytes);
+ var tempbytes = [];
+ bstart = plaintext.length-num_bytes;
+ for (var i=0; i < num_bytes; i++) {
+ ciphertext[bstart+i] = plaintext[bstart+i] ^ pad_bytes[i];
+ tempbytes[tempbytes.length] = plaintext[bstart+i];
+ }
+ for (var i=num_bytes; i < 16; i++)
+ tempbytes[tempbytes.length] = pad_bytes[i];
+ aes.bytesToWords(tempbytes, t);
+ for (var i=0; i < 4; i++) Checksum[i] = Checksum[i] ^ t[i];
+
+ // compute authentication tag
+ this._times2(t,Offset);
+ for (var i=0; i < 4; i++) {
+ Offset[i] = t[i] ^ Offset[i];
+ t[i] = Checksum[i] ^ Offset[i];
+ }
+ this._cipher.encryptBlock(t,t2);
+ if (header.length > 0) {
+ this.PMAC(header, t);
+ for (var i=0; i < 4; i++) tag[i] = t[i] ^ t2[i];
+ } else {
+ for (var i=0; i < 4; i++) tag[i] = t2[i];
+ }
+};
+
+
+/* Decrypts and verifies integrity of ciphertext, only verifies integrity of header.
+ciphertext, plaintext, and header are arrays of bytes. tag is an array of 4 32-bit words.
+Returns true if tag is valid, false otherwise. */
+cipherOCB.prototype.decrypt = function(ciphertext, plaintext, header, tag) {
+ var Offset = new Array(4), Checksum = [0x00000000,0x00000000,0x00000000,0x00000000];
+ this._cipher.encryptBlock(this._cipher._iv, Offset);
+
+ var t = new Array(4), t2 = new Array(4), block = new Array(4);
+
+ // decrypt and accumulate first m-1 blocks
+ var num_blocks = Math.floor((ciphertext.length-1)/16);
+ var bstart = 0, pbytes = new Array(16);
+ this._cipher.scheduleDecrypt();
+ for (var i=0; i < num_blocks; i++) {
+ this._times2(Offset,Offset);
+ bstart = i*16;
+ for (var j=0; j < 4; j++)
+ t[j] = Offset[j] ^ ((ciphertext[bstart+(j<<2)+3]) | (ciphertext[bstart+(j<<2)+2] << 8) | (ciphertext[bstart+(j<<2)+1] << 16) | (ciphertext[bstart+(j<<2)] << 24));
+ this._cipher.decryptBlock(t,t2);
+ for (var j=0; j < 4; j++) {
+ block[j] = Offset[j] ^ t2[j];
+ Checksum[j] = block[j] ^ Checksum[j];
+ }
+ aes.wordsToBytes(block,pbytes);
+ for (var j=0; j < 16; j++)
+ plaintext[bstart+j] = pbytes[j];
+ }
+
+ // decrypt and accumulate final block
+ var Pad = new Array(4), padbytes=[];
+ this._cipher.scheduleEncrypt()
+ this._times2(Offset,Offset);
+ var num_bytes = ciphertext.length%16;
+ if ((num_bytes == 0) && (ciphertext.length > 0)) num_bytes=16;
+ t = [0x00000000,0x00000000,0x00000000,0x00000000];
+ t[3] = num_bytes*8;
+ for (var i=0; i < 4; i++) t[i] = t[i] ^ Offset[i]
+ this._cipher.encryptBlock(t,Pad);
+ aes.wordsToBytes(Pad, padbytes);
+ bstart = ciphertext.length - num_bytes;
+ for (var i=0; i < num_bytes; i++) {
+ plaintext[bstart+i] = ciphertext[bstart+i] ^ padbytes[i];
+ t[i] = plaintext[bstart+i];
+ }
+ for (var i = num_bytes; i < 16; i++)
+ t[i] = padbytes[i];
+ aes.bytesToWords(t,t2);
+ for (var i=0; i < 4; i++) Checksum[i] = Checksum[i] ^ t2[i];
+
+ // compute valid authentication tag
+ this._times2(t, Offset);
+ for (var i=0; i < 4; i++) {
+ Offset[i] = Offset[i] ^ t[i];
+ t[i] = Offset[i] ^ Checksum[i];
+ }
+ var validTag = new Array(4);
+ this._cipher.encryptBlock(t,validTag);
+ t = new Array(4);
+ if (header.length > 0) {
+ this.PMAC(header, t);
+ for (var i=0; i < 4; i++) validTag[i] = validTag[i] ^ t[i];
+ }
+ // compute results
+ for (var i=0; i < 4; i++) {
+ if (aes._hex(tag[i]) != aes._hex(validTag[i])) {
+ return false;
+ }
+ }
+ return true;
+};
+
+
+
+cipherOCB.prototype._times2 = function(dst, src) {
+ var carry = src[0]>>>31;
+ for (var i=0; i < 3; i++)
+ dst[i] = (src[i]<<1) | (src[i+1]>>>31);
+ dst[3] = (src[3]<<1) ^ (carry * 0x87);
+};
+
+
+
+
+
+
+
+
+/*
+jsCrypto
+
+sha256.js
+Mike Hamburg, 2008. Public domain.
+ */
+
+
+function SHA256() {
+ if (!this.k[0])
+ this.precompute();
+ this.initialize();
+}
+
+SHA256.prototype = {
+ /*
+ init:[0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19],
+
+ k:[0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+ 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+ 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+ 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+ 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+ 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2],
+ */
+
+ init:[], k:[],
+
+ precompute: function() {
+ var p=2,i=0,j;
+
+ function frac(x) { return (x-Math.floor(x)) * 4294967296 | 0 }
+
+ outer: for (;i<64;p++) {
+ for (j=2;j*j<=p;j++)
+ if (p % j == 0)
+ continue outer;
+
+ if (i<8) this.init[i] = frac(Math.pow(p,1/2));
+ this.k[i] = frac(Math.pow(p,1/3));
+ i++;
+ }
+ },
+
+ initialize:function() {
+ this.h = this.init.slice(0);
+ this.word_buffer = [];
+ this.bit_buffer = 0;
+ this.bits_buffered = 0;
+ this.length = 0;
+ this.length_upper = 0;
+ },
+
+ // one cycle of SHA256
+ block:function(words) {
+ var w=words.slice(0),i,h=this.h,tmp,k=this.k;
+
+ var h0=h[0],h1=h[1],h2=h[2],h3=h[3],h4=h[4],h5=h[5],h6=h[6],h7=h[7];
+
+ for (i=0;i<64;i++) {
+ if (i<16) {
+ tmp=w[i];
+ } else {
+ var a=w[(i+1)&15], b=w[(i+14)&15];
+ tmp=w[i&15]=((a>>>7^a>>>18^a>>>3^a<<25^a<<14) + (b>>>17^b>>>19^b>>>10^b<<15^b<<13) + w[i&15] + w[(i+9)&15]) | 0;
+ }
+
+ tmp += h7 + (h4>>>6^h4>>>11^h4>>>25^h4<<26^h4<<21^h4<<7) + (h6 ^ h4&(h5^h6)) + k[i];
+
+ h7=h6; h6=h5; h5=h4;
+ h4 = h3 + tmp | 0;
+
+ h3=h2; h2=h1; h1=h0;
+
+ h0 = (tmp + ((h1&h2)^(h3&(h1^h2))) + (h1>>>2^h1>>>13^h1>>>22^h1<<30^h1<<19^h1<<10)) | 0;
+ }
+
+ h[0]+=h0; h[1]+=h1; h[2]+=h2; h[3]+=h3;
+ h[4]+=h4; h[5]+=h5; h[6]+=h6; h[7]+=h7;
+ },
+
+ update_word_big_endian:function(word) {
+ var bb;
+ if ((bb = this.bits_buffered)) {
+ this.word_buffer.push(word>>>(32-bb) ^ this.bit_buffer);
+ this.bit_buffer = word << bb;
+ } else {
+ this.word_buffer.push(word);
+ }
+ this.length += 32;
+ if (this.length == 0) this.length_upper ++; // mmhm..
+ if (this.word_buffer.length == 16) {
+ this.block(this.word_buffer);
+ this.word_buffer = [];
+ }
+ },
+
+ update_word_little_endian:function(word) {
+ word = word >>> 16 ^ word << 16;
+ word = ((word>>>8) & 0xFF00FF) ^ ((word<<8) & 0xFF00FF00);
+ this.update_word_big_endian(word);
+ },
+
+ update_words_big_endian: function(words) {
+ for (var i=0; i<words.length; i++) this.update_word_big_endian(words[i]);
+ },
+
+ update_words_little_endian: function(words) {
+ for (var i=0; i<words.length; i++) this.update_word_little_endian(words[i]);
+ },
+
+ update_byte:function(byte) {
+ this.bit_buffer ^= (byte & 0xff) << (24 - (this.bits_buffered));
+ this.bits_buffered += 8;
+ if (this.bits_buffered == 32) {
+ this.bits_buffered = 0;
+ this.update_word_big_endian(this.bit_buffer);
+ this.bit_buffer = 0;
+ }
+ },
+
+ update_string:function(string) {
+ throw "not yet implemented";
+ },
+
+ finalize:function() {
+ var i, wb = this.word_buffer;
+
+ wb.push(this.bit_buffer ^ (0x1 << (31 - this.bits_buffered)));
+ for (i = (wb.length + 2) & 15; i<16; i++) {
+ wb.push(0);
+ }
+
+ wb.push(this.length_upper);
+ wb.push(this.length + this.bits_buffered);
+
+ this.block(wb.slice(0,16));
+ if (wb.length > 16) {
+ this.block(wb.slice(0,16));
+ }
+
+ var h = this.h;
+ this.initialize();
+ return h;
+ }
+}
+
+SHA256.hash_words_big_endian = function(words) {
+ var s = new SHA256();
+ for (var i=0; i<=words.length-16; i+=16) {
+ s.block(words.slice(i,i+16));
+ }
+ s.length = i << 5; // so don't pass this function more than 128M words
+ if (i<words.length)
+ s.update_words_little_endian(words.slice(i));
+ return s.finalize();
+}
+
+SHA256.hash_words_little_endian = function(words) {
+ var w = words.slice(0);
+ for (var i=0; i<w.length; i++) {
+ w[i] = w[i] >>> 16 ^ w[i] << 16;
+ w[i] = ((w[i]>>>8) & 0xFF00FF) ^ ((w[i]<<8) & 0xFF00FF00);
+ }
+ return SHA256.hash_words_big_endian(w);
+}
+
+
+
+
+
+
+
+/*
+
+ jsCrypto
+
+ * Random.js -- cryptographic random number generator
+ * Mike Hamburg, 2008. Public domain.
+ *
+ * This generator uses a modified version of Fortuna. Fortuna has
+ * excellent resilience to compromise, relies on a state file, and is
+ * intended to run for a long time. As such, it does not need an
+ * entropy estimator. Unfortunately, Fortuna's startup in low-entropy
+ * conditions leaves much to be desired.
+ *
+ * This generator features the following modifications. First, the
+ * generator does not create the n-th entropy pool until it exhausts
+ * the n-1-st. This means that entropy doesn't get "stuck" in pools
+ * 10-31, which will never be used on a typical webpage. It also
+ * means that the entropy will all go into a single pool until the
+ * generator is seeded.
+ *
+ * Second, there is a very crude entropy estimator. The primary goal
+ * of this estimator is to prevent the generator from being used in
+ * low-entropy situations. Corresponding to this entropy estimator,
+ * there is a "paranoia control". This controls how many bits of
+ * estimated entropy must be present before the generator is used.
+ * The generator cannot have more than 256 bits of actual entropy in
+ * the main pool; rather, the paranoia control is designed to deal
+ * with the fact that the entropy estimator is probably horrible.
+ *
+ * Third, the "statefile" is optional and stored in a cookie. As
+ * such, it is not protected from multiple simultaneous usage, and so
+ * is treated conservatively.
+ */
+
+Random = {
+ /* public */
+NOT_READY: 0,
+READY: 1,
+REQUIRES_RESEED: 2,
+
+ /* generate one random word */
+random_word: function(paranoia) {
+ return this.random_words(1, paranoia)[0];
+},
+
+ /* generate nwords random words, and return them in an array */
+random_words: function(nwords, paranoia) {
+ var out = [], i, readiness = this.is_ready(paranoia);
+
+ if (readiness == this.NOT_READY)
+ throw("Random: generator isn't seeded!");
+
+ else if (readiness && this.REQUIRES_RESEED)
+ this._reseed_from_pools(!(readiness & this.READY));
+
+ for (i=0; i<nwords; i+= 4) {
+ if ((i+1) % this._max_words_per_burst == 0)
+ this._gate();
+
+ var g = this._gen_4_words();
+ out.push(g[0],g[1],g[2],g[3]);
+ }
+ this._gate();
+
+ return out.slice(0,nwords);
+},
+
+set_default_paranoia: function(paranoia) {
+ this._default_paranoia = paranoia;
+},
+
+ /* Add entropy to the pools. Pass data as an array, number or
+ * string. Pass estimated_entropy in bits. Pass the source as a
+ * number or string.
+ */
+add_entropy: function(data, estimated_entropy, source) {
+ source = source || "user";
+
+ var id = this._collector_ids[source] ||
+ (this._collector_ids[source] = this._collector_id_next ++);
+
+ var i, ty = 0;
+
+ var t = new Date().valueOf();
+
+ var robin = this._robins[source];
+ if (robin == undefined) robin = this._robins[source] = 0;
+ this._robins[source] = ( this._robins[source] + 1 ) % this._pools.length;
+
+ switch(typeof(data)) {
+
+ case "number":
+ data=[data];
+ ty=1;
+ break;
+
+ case "object":
+ if (!estimated_entropy) {
+ /* horrible entropy estimator */
+ estimated_entropy = 0;
+ for (i=0; i<data.length; i++) {
+ var x = data[i];
+ while (x>0) {
+ estimated_entropy++;
+ x = x >>> 1;
+ }
+ }
+ }
+ this._pools[robin].update_words_big_endian([id,this._event_id++,ty||2,estimated_entropy,t,data.length].concat(data));
+ break;
+
+ case "string":
+ if (!estimated_entropy) {
+ /* English text has just over 1 bit per character of entropy.
+ * But this might be HTML or something, and have far less
+ * entropy than English... Oh well, let's just say one bit.
+ */
+ estimated_entropy = data.length;
+ }
+ this._pools[robin].update_words_big_endian([id,this._event_id++,3,estimated_entropy,t,data.length])
+ this._pools[robin].update_string(data);
+ break;
+
+ default:
+ throw "add_entropy: must give an array, number or string"
+ }
+
+ var old_ready = this.is_ready();
+
+ /* record the new strength */
+ this._pool_entropy[robin] += estimated_entropy;
+ this._pool_strength += estimated_entropy;
+
+ /* fire off events */
+ if (!old_ready && this.is_ready())
+ this._fire_event("seeded", Math.max(this._strength, this._pool_strength));
+
+ if (!old_ready)
+ this._fire_event("progress", this.get_progress());
+},
+
+ /* is the generator ready? */
+is_ready: function(paranoia) {
+ var entropy_required = this._PARANOIA_LEVELS[ paranoia ? paranoia : this._default_paranoia ];
+
+ if (this._strength >= entropy_required) {
+ return (this._pool_entropy[0] > this._BITS_PER_RESEED && new Date.valueOf() > this._next_reseed) ?
+ this.REQUIRES_RESEED | this.READY :
+ this.READY;
+ } else {
+ return (this._pool_strength > entropy_required) ?
+ this.REQUIRES_RESEED | this.NOT_READY :
+ this.NOT_READY;
+ }
+},
+
+ /* how close to ready is it? */
+get_progress: function(paranoia) {
+ var entropy_required = this._PARANOIA_LEVELS[ paranoia ? paranoia : this._default_paranoia ];
+
+ if (this._strength >= entropy_required) {
+ return 1.0;
+ } else {
+ return (this._pool_strength > entropy_required) ?
+ 1.0 :
+ this._pool_strength / entropy_required;
+ }
+},
+
+ /* start the built-in entropy collectors */
+start_collectors: function() {
+ if (this._collectors_started) return;
+
+ if (window.addEventListener) {
+ window.addEventListener("load", this._load_time_collector, false);
+ window.addEventListener("mousemove", this._mouse_collector, false);
+ } else if (document.attachEvent) {
+ document.attachEvent("onload", this._load_time_collector);
+ document.attachEvent("onmousemove", this._mouse_collector);
+ }
+ else throw("can't attach event");
+
+ this._collectors_started = true;
+},
+
+ /* stop the built-in entropy collectors */
+stop_collectors: function() {
+ if (!this._collectors_started) return;
+
+ if (window.removeEventListener) {
+ window.removeEventListener("load", this._load_time_collector);
+ window.removeEventListener("mousemove", this._mouse_collector);
+ } else if (window.detachEvent) {
+ window.detachEvent("onload", this._load_time_collector);
+ window.detachEvent("onmousemove", this._mouse_collector)
+ }
+ this._collectors_started = false;
+},
+
+use_cookie: function(all_cookies) {
+ throw "TODO: implement use_cookie";
+},
+
+ /* add an event listener for progress or seeded-ness */
+addEventListener: function(name, callback) {
+ this._callbacks[name][this._callback_i++] = callback;
+},
+
+ /* remove an event listener for progress or seeded-ness */
+removeEventListener: function(name, cb) {
+ var i, j, cbs=this._callbacks[name], js_temp=[];
+
+ /* I'm not sure if this is necessary; in C++, iterating over a
+ * collection and modifying it at the same time is a no-no.
+ */
+
+ for (j in cbs)
+ if (cbs.hasOwnProperty[j] && cbs[j] === cb)
+ js_temp.push(j);
+
+ for (i=0; i<js_temp.length; i++) {
+ j = js[i];
+ delete cbs[j];
+ }
+},
+
+ /* private */
+ _pools : [new SHA256()],
+ _pool_entropy : [0],
+ _reseed_count : 0,
+ _robins : {},
+ _event_id : 0,
+
+ _collector_ids : {},
+ _collector_id_next : 0,
+
+ _strength : 0,
+ _pool_strength : 0,
+ _next_reseed : 0,
+ _key : [0,0,0,0,0,0,0,0],
+ _counter : [0,0,0,0],
+ _cipher : undefined,
+ _default_paranoia : 6,
+
+ /* event listener stuff */
+ _collectors_started : false,
+ _callbacks : {progress: {}, seeded: {}},
+ _callback_i : 0,
+
+ /* constants */
+ _MAX_WORDS_PER_BURST : 65536,
+ _PARANOIA_LEVELS : [0,48,64,96,128,192,256,384,512,768,1024],
+ _MILLISECONDS_PER_RESEED : 100,
+ _BITS_PER_RESEED : 80,
+
+ /* generate 4 random words, no reseed, no gate */
+_gen_4_words: function() {
+ var words = [];
+ for (var i=0; i<3; i++) if (++this._counter[i]) break;
+ this._cipher.encryptBlock(this._counter, words);
+ return words;
+},
+
+ /* rekey the AES instance with itself after a request, or every _MAX_WORDS_PER_BURST words */
+_gate: function() {
+ this._key = this._gen_4_words().concat(this._gen_4_words());
+ this._cipher = new aes(this._key);
+},
+
+ /* reseed the generator with the given words */
+_reseed: function(seedWords) {
+ this._key = SHA256.hash_words_big_endian(this._key.concat(seedWords));
+ this._cipher = new aes(this._key);
+ for (var i=0; i<3; i++) if (++this._counter[i]) break;
+},
+
+ /* reseed the data from the entropy pools */
+_reseed_from_pools: function(full) {
+ var reseed_data = [], strength = 0;
+
+ this._next_reseed = new Date().valueOf() + this._MILLISECONDS_PER_RESEED;
+
+ for (i=0; i<this._pools.length; i++) {
+ reseed_data = reseed_data.concat(this._pools[i].finalize());
+ strength += this._pool_entropy[i];
+ this._pool_entropy[i] = 0;
+
+ if (!full && (this._reseed_count & (1<<i))) break;
+ }
+
+ /* if we used the last pool, push a new one onto the stack */
+ if (this._reseed_count >= 1 << this._pools.length) {
+ this._pools.push(new SHA256());
+ this._pool_entropy.push(0);
+ }
+
+ /* how strong was this reseed? */
+ this._pool_strength -= strength;
+ if (strength > this._strength) this._strength = strength;
+
+ this._reseed_count ++;
+ this._reseed(reseed_data);
+},
+
+_mouse_collector: function(ev) {
+ var x = ev.x || ev.clientX || ev.offsetX;
+ var y = ev.y || ev.clientY || ev.offsetY;
+ Random.add_entropy([x,y], 2, "mouse");
+},
+
+_load_time_collector: function(ev) {
+ var d = new Date();
+ Random.add_entropy(d, 2, "loadtime");
+},
+
+_fire_event: function(name, arg) {
+ var j, cbs=Random._callbacks[name], cbs_temp=[];
+
+ /* I'm not sure if this is necessary; in C++, iterating over a
+ * collection and modifying it at the same time is a no-no.
+ */
+
+ for (j in cbs) {
+ if (cbs.hasOwnProperty(j)) {
+ cbs_temp.push(cbs[j]);
+ }
+ }
+
+ for (j=0; j<cbs_temp.length; j++) {
+ cbs_temp[j](arg);
+ }
+}
+};
+
diff --git a/frontend/gamma/tests/tests/Clipperz/DOM.html b/frontend/gamma/tests/tests/Clipperz/DOM.html
new file mode 100644
index 0000000..2060215
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/DOM.html
@@ -0,0 +1,58 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/DOM.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Logging.js'></script>
+
+ <script type='text/javascript' src='../../../js/Clipperz/Crypto/Base.js'></script>
+</head>
+<body>
+
+<pre id="test">
+<script>
+ Clipperz_IEisBroken = false;
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+</script><![endif]-->
+<script type="text/javascript" src="DOM.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/DOM.test.js b/frontend/gamma/tests/tests/Clipperz/DOM.test.js
new file mode 100644
index 0000000..a2aafc5
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/DOM.test.js
@@ -0,0 +1,82 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+try {
+ var template;
+ var templateArgs;
+ var element;
+ var rowElement;
+ var tdElement;
+
+ template = Clipperz.DOM.Helper.createTemplate(
+ [
+ {tag:'td', children:[{tag:'img', cls:'favicon', src:'{faviconUrl}'}]},
+ {tag:'td', children:[{tag:'a', href:'#', cls:'title', html:'{cardTitle}'}]},
+ {tag:'td', children:[{tag:'span', cls:'directLogins', id:'{directLoginsID}'}]},
+ {tag:'td', children:[{tag:'span', cls:'latestUpdate', html:'{latestUpdate}'}]},
+ {tag:'td'}
+ ]
+ );
+
+ templateArgs = {
+ cardTitle: "Amazon.com",
+ directLoginsID: "Clipperz_PM_Components_directLogins_58",
+ faviconUrl: "http://www.amazon.com/favicon.ico",
+ latestUpdate: "",
+ reference: "13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551"
+ }
+
+ element = Clipperz.DOM.Helper.append(document.body, {tag:'table', children:[
+ {tag:'theader'},
+ {tag:'tbody', children:[
+ {tag:'tr', id:'testRow'}
+ ]},
+ {tag:'tfooter'}
+ ]});
+ ok(element != null, "created the TABLE");
+
+ rowElement = Clipperz.DOM.get('testRow');
+ ok(testRow != null, "created the ROW");
+
+ template.append(rowElement, templateArgs);
+ tdElement = Clipperz.DOM.get(templateArgs['directLoginsID']);
+ ok(tdElement != null, "created the TD");
+
+} catch (err) {
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
diff --git a/frontend/gamma/tests/tests/Clipperz/Date.html b/frontend/gamma/tests/tests/Clipperz/Date.html
new file mode 100644
index 0000000..5712a52
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Date.html
@@ -0,0 +1,54 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.Date - TEST</title>
+
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Async.js'></script>
+
+
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.Async.js"></script>
+
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript" src="Date.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Date.test.js b/frontend/gamma/tests/tests/Clipperz/Date.test.js
new file mode 100644
index 0000000..06f7dc8
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Date.test.js
@@ -0,0 +1,66 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+var tests = {
+
+ '001_test': function () {
+ var date;
+ var locale;
+
+// date = new Date(0);
+// date.setMilliseconds(Date.parse("Fri, 21 Sep 2007 10:04:24 UTC"));
+
+ date = new Date(Date.parse("Fri, 21 Sep 2007 10:04:24 UTC"));
+
+ locale = {
+ 'amDesignation': "am",
+ 'pmDesignation': "pm",
+// 'shortDateFormat': "d/m/y",
+// 'longDateFormat': "",
+ 'months': ["January", "February", "March", "April",
+ "May", "June", "July", "August",
+ "September", "October", "November", "December" ],
+ 'shortMonths': ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
+ 'days': ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" ],
+ 'shortDays': ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ]
+ }
+
+ is(Clipperz.Date.formatDateWithPHPLikeTemplateAndLocale(date, "d/m/y", locale), '21/09/07', "formatDate - 1");
+ is(Clipperz.Date.formatDateWithPHPLikeTemplateAndLocale(date, "D M Y", locale), 'Fri Sep 2007', "formatDate - 2");
+ is(Clipperz.Date.formatDateWithPHPLikeTemplateAndLocale(date, "D, d M Y", locale), 'Fri, 21 Sep 2007', "formatDate - 3");
+ is(Clipperz.Date.formatDateWithPHPLikeTemplateAndLocale(date, "D, d M Y H:i:s", locale), 'Fri, 21 Sep 2007 12:04:24', "formatDate - 4");
+// is(Clipperz.Date.formatDateWithPHPLikeTemplateAndLocale(date, "D, d M Y H:i:s (T)", locale), 'Fri, 21 Sep 2007 11:04:24 (CEST)', "formatDate - 5");
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+}
+
+//=============================================================================
+
+SimpleTest.runDeferredTests("Clipperz.Date", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/KeePassExportProcessor.data.js b/frontend/gamma/tests/tests/Clipperz/KeePassExportProcessor.data.js
new file mode 100644
index 0000000..5bfb8c7
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/KeePassExportProcessor.data.js
@@ -0,0 +1,910 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+var testData = {}
+
+testData['Barb_Newman_data'] = "";
+testData['Barb_Newman_data'] = testData['Barb_Newman_data'] +
+ "[Domain Administration Account]" + "\n" +
+ "Group: Windows" + "\n" +
+ "User Name: _ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[Enquiro Domain]" + "\n" +
+ "Group: Windows" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: This is an Exchange Mailbox checked by IT/Programming" + "\n" +
+ "" + "\n" +
+ "[Enquiro Domain Administrator Account]" + "\n" +
+ "Group: Windows" + "\n" +
+ "User Name: ENQUIRO\ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Obsolete" + "\n" +
+ "" + "\n" +
+ "[Enquiro Domain Administrator Account]" + "\n" +
+ "Group: Windows" + "\n" +
+ "User Name: ENQUIRO\ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Changed on 07 Sep 2007 by Randy Kissick" + "\n" +
+ "" + "\n" +
+ "[Enquiro Domain Previous Administrator Account]" + "\n" +
+ "Group: Windows" + "\n" +
+ "User Name: ENQUIRO\ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSQL1" + "\n" +
+ "" + "\n" +
+ "[Local Administrator Account for most Machines]" + "\n" +
+ "Group: Windows" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[Local Administrator Account for some Machines]" + "\n" +
+ "Group: Windows" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[Bugzilla]" + "\n" +
+ "Group: Hardware" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: BUGZILLA" + "\n" +
+ "" + "\n" +
+ "[Client Services Linux Box]" + "\n" +
+ "Group: Hardware" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: 192.168.1.141" + "\n" +
+ "" + "\n" +
+ "[ENSQL2 BIOS]" + "\n" +
+ "Group: Hardware" + "\n" +
+ "User Name: " + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[Eye Tracking PC]" + "\n" +
+ "Group: Hardware" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[IT Linux Box (Brainiac)]" + "\n" +
+ "Group: Hardware" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[Maizal - Contract Developer Machine]" + "\n" +
+ "Group: Hardware" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: 199.185.139.69:3399" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Software Development Contractors use remote access to access this machine.\r\n\r\nTested August 08.\r\n\r\nBe sure to send the info via two different delivery methods." + "\n" +
+ "" + "\n" +
+ "[NETGEAR WGR614v3]" + "\n" +
+ "Group: Hardware" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: (192.168.1.11)" + "\n" +
+ "" + "\n" +
+ "[SEP Firewall (192.168.1.1)]" + "\n" +
+ "Group: Hardware" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Changed to this on 2007/01/31" + "\n" +
+ "" + "\n" +
+ "[SEP Firewall (192.168.1.1)]" + "\n" +
+ "Group: Hardware" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: 192.168.1.1" + "\n" +
+ "" + "\n" +
+ "[UPS]" + "\n" +
+ "Group: Hardware" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[Wireless WPA-PSK]" + "\n" +
+ "Group: Hardware" + "\n" +
+ "User Name: " + "\n" +
+ "URL: " + "\n" +
+ "Password: synergize" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[Gord's Laptop Adminstrator 123456" + "\n" +
+ "Group: Hardware" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[Wireless Access Point]" + "\n" +
+ "Group: Hardware" + "\n" +
+ "User Name: SSID: ENWRLSS" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: WPA (TKIP) key is in password 123456" + "\n" +
+ "" + "\n" +
+ "[Adobe Account]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[APC UPS Website]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Web site for UPS Drivers/Manuals" + "\n" +
+ "" + "\n" +
+ "[ask.enquiro.com admin]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: ask.enquiro.com" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Jody is the admin\r\nChris is the editor" + "\n" +
+ "" + "\n" +
+ "[ask.enquiro.com ftp]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: ask.enquiro.com" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ftp.ask.enquiro.com\r\nchanged 02 Jun 08" + "\n" +
+ "" + "\n" +
+ "[BulkRegister]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC " + "\n" +
+ "URL: https://www.bulkregister.com/Login.asp?" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Used for domain registrations" + "\n" +
+ "" + "\n" +
+ "[controlpanel.provisiondata.com]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: SEIReports.com Email address management" + "\n" +
+ "" + "\n" +
+ "[controlpanel.provisiondata.com]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: " + "\n" +
+ "URL: " + "\n" +
+ "Password: " + "\n" +
+ "Notes: Searchengineposition.com Email address management" + "\n" +
+ "" + "\n" +
+ "[Dell Canada]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Used to order equirpment from Dell\r\nCredit Card information is Tracy Kalancha AmEx" + "\n" +
+ "" + "\n" +
+ "[Feedback Server]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: http://www.nsurvey.org/members/login.aspx" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[ftp.enquiro.com]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: TYRANUS (199.60.252.157)\r\nchanged 25 Jun 08" + "\n" +
+ "" + "\n" +
+ "[ftp.enquirolabs.com]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: enquirolabs.com" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Changed 04 Jun 08" + "\n" +
+ "" + "\n" +
+ "[ftp://ftp.b2bexpertseries.com]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: b2bexpertseries.com" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Changed 02 Jun 08" + "\n" +
+ "" + "\n" +
+ "[HSBC Bank Account]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: hsbc.ca" + "\n" +
+ "Password: " + "\n" +
+ "Notes: What is my Mother's Name: BARBARA\r\nSecurity Code is generated by the Security Device - you have 10 seconds to enter it." + "\n" +
+ "" + "\n" +
+ "[HSBC Fx Trading]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: https://fxtrading.hsbc.ca/fx-canada/login.html" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Doug to advise when he changes the password. Software requests change on a regular basis." + "\n" +
+ "" + "\n" +
+ "[Industry Canada - Canadian Company Capabilities (CCC)]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: http://www.ic.gc.ca" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Our listing: http://www.ic.gc.ca/app/ccc/srch/nvgt.do;jsessionid=0000RKFbMEOs2xvyRNoCF4pH3Ym:1247nks53?lang=eng&prtl=1&profile=cmpltPrfl&V_TOKEN=1203707557897&V_SEARCH.command=navigate&V_SEARCH.docsStart=1&V_SEARCH.resultsJSP=/prfl.do&V_DOCUMENT.docRank=1&V_SEARCH.docsCount=3&estblmntNo=234567061957&profileId=\r\n\r\nAndrew is responsible to update" + "\n" +
+ "" + "\n" +
+ "[Internet Secure CAD 1086]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: https://www.internetsecure.com/merchants/" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Doug to advise when he changes the password. Software requests change on a regular basis." + "\n" +
+ "" + "\n" +
+ "[Internet Secure USD 1087]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: https://www.internetsecure.com/merchants/" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Doug to advise when he changes the password. Software requests change on a regular basis." + "\n" +
+ "" + "\n" +
+ "[louisville.net-radar.com]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: FTP/FrontPage" + "\n" +
+ "" + "\n" +
+ "[Microsoft Licensing Program eOpen]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: https://eOpen.microsoft.com" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Used to record all Microsoft licensing information" + "\n" +
+ "" + "\n" +
+ "[OSTEC Job Site]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[OutOfMyGord.com Blog Login]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: VADER" + "\n" +
+ "" + "\n" +
+ "[OutOfMyGord.com Web Site]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: VADER" + "\n" +
+ "" + "\n" +
+ "[Paypal@enquiro.com]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[PRWeb]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: shermantracy" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[ScanMail Logon]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Scanmail Logon (Anti-Spam)" + "\n" +
+ "" + "\n" +
+ "[secure.searchengineposition.com]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: " + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: TYRANUS (199.60.252.237)" + "\n" +
+ "" + "\n" +
+ "[seireports.com]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: http://www.seireports.com/" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[sepreports.com]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: http://www.sepreports.com" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Used for monthly client reporting" + "\n" +
+ "" + "\n" +
+ "[septraffic.com]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[Spiceworks]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: http://endc3:9675/dashboard" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Is installed on endc3. \r\nIt's used to inventory the hardware attached to the network. \r\nIt's scheduled to run daily at 10:00am. \r\nMachine's must be on to be detected.\r\n\r\nNote: first character of password is a zero\r\n\r\n\r\nhttp://www.spiceworks.com" + "\n" +
+ "" + "\n" +
+ "[SurveyMonkey Enquiro]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: http://www.surveymonkey.com" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Used for small Enquiro surveys that aren't research related" + "\n" +
+ "" + "\n" +
+ "[SwishZone]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[Tobii.com]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: " + "\n" +
+ "URL: " + "\n" +
+ "Password: " + "\n" +
+ "Notes: Tobii Website Logon" + "\n" +
+ "" + "\n" +
+ "[Trend Micro]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: https://olr.trendmicro.com/registration/" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: 23 Jan 08 - I logged a bug with Trend to merge the DougWilson account with this account. /bn\r\n\r\n31 Jan 07 - Done!" + "\n" +
+ "" + "\n" +
+ "[Watchguard VPN Administrator]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: https://10.99.50.254" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Log on here to adminster the VPN, create wgx files and user passphrase\r\n\r\n\r\n\r\n" + "\n" +
+ "" + "\n" +
+ "[Watchguard VPN hardware support website]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: https://www.watchguard.com/" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Enquiro's VPN hardware support website\r\n\r\n\r\n\r\n\r\n" + "\n" +
+ "" + "\n" +
+ "[Webtrain]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: http://www.webtrain.com/" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Used to set up webinars. \r\nOwner username can give permisions to share with other users, and those users can create login's.\r\n\r\nHours are associated with the gord@searchengineposition.com account" + "\n" +
+ "" + "\n" +
+ "[Whitelist & Spam Trainer (Jeremy's)]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: http://my.email-as.net" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Used to:\r\n- add email addresses for clients, prospects or other contacts to the email whitelist\r\n- train Jeremy's system as spam or not spam.\r\n\r\nJeremy uses SpamAssassin " + "\n" +
+ "" + "\n" +
+ "[www.amazon.com]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[www.digitalriver.com]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: " + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[www.kelownarockets.com/store/ssl/admin/menu.asp]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: GEONOSIS" + "\n" +
+ "" + "\n";
+
+testData['Barb_Newman_data'] = testData['Barb_Newman_data'] +
+ "[www.webnames.ca]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: 27 Mar 08 - Logged on but site has no domains listed. We no longer use this service, as I have been managing all domains on bulkregister for over a year. /bn" + "\n" +
+ "" + "\n" +
+ "[Yahooligans]" + "\n" +
+ "Group: Websites" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Webtrends Server" + "\n" +
+ "" + "\n" +
+ "[Anti-Virus]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: " + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSQL1" + "\n" +
+ "" + "\n" +
+ "[ENDEV1 SQL Server Service Account]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENDEV1" + "\n" +
+ "" + "\n" +
+ "[ENDEV2]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENDEV2" + "\n" +
+ "" + "\n" +
+ "[Enquiro Domain - BackUpExec]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSQL1" + "\n" +
+ "" + "\n" +
+ "[Enquiro Domain - SEIService Account]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENAPP1" + "\n" +
+ "" + "\n" +
+ "[Enquiro Domain - SQLServer]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSQL1/ENSQL2" + "\n" +
+ "" + "\n" +
+ "[Enquiro Domain - SQLServer]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSQL1" + "\n" +
+ "" + "\n" +
+ "[ENQUIRO/SEIService User Account]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[ENSPS1 Anonymous User]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSPS1" + "\n" +
+ "" + "\n" +
+ "[Exchange Email Archive]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Cory changed this on 2007/01/31 to 123456" + "\n" +
+ "" + "\n" +
+ "[MySQL]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: BUGZILLA" + "\n" +
+ "" + "\n" +
+ "[SEIWEB1/SEIWEB2 Anonymous User]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: BLENDER" + "\n" +
+ "" + "\n" +
+ "[SEIWEB1/SEIWEB2 Anonymous User]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: BLENDER" + "\n" +
+ "" + "\n" +
+ "[SEIWEB1/SEIWEB2 Anonymous User]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: BLENDER" + "\n" +
+ "" + "\n" +
+ "[SEIWEB1/SEIWEB2 Anonymous User]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: BLENDER" + "\n" +
+ "" + "\n" +
+ "[SEIWEB1/SEIWEB2 Anonymous User]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: BLENDER" + "\n" +
+ "" + "\n" +
+ "[SEIWEB1/SEIWEB2 Anonymous User]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: BLENDER" + "\n" +
+ "" + "\n" +
+ "[SEIWEB1/SEIWEB2 Anonymous User]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: BLENDER" + "\n" +
+ "" + "\n" +
+ "[Sharepoint Single Sign On Acct]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[SourceSafe on ENDEV1]" + "\n" +
+ "Group: Services" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENDEV1" + "\n" +
+ "" + "\n" +
+ "[Bugzilla Database]" + "\n" +
+ "Group: Database Passwords" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: BUGZILLA" + "\n" +
+ "" + "\n" +
+ "[Bugzilla Database]" + "\n" +
+ "Group: Database Passwords" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENDEV1" + "\n" +
+ "" + "\n" +
+ "[ENDOC1 Goldmine SQL2005]" + "\n" +
+ "Group: Database Passwords" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: added 19 Oct 2007 with the Goldmine upgrade." + "\n" +
+ "" + "\n" +
+ "[Enquiro Survey Database Account]" + "\n" +
+ "Group: Database Passwords" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[Enquiro Survey Development Account]" + "\n" +
+ "Group: Database Passwords" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[ENSQL1]" + "\n" +
+ "Group: Database Passwords" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSQL1" + "\n" +
+ "" + "\n" +
+ "[ENSQL1]" + "\n" +
+ "Group: Database Passwords" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSQL1" + "\n" +
+ "" + "\n" +
+ "[ENSQL1]" + "\n" +
+ "Group: Database Passwords" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSQL1" + "\n" +
+ "" + "\n" +
+ "[ENSQL1]" + "\n" +
+ "Group: Database Passwords" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[ENSQL2]" + "\n" +
+ "Group: Database Passwords" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[OutOfMyGord.com Database]" + "\n" +
+ "Group: Database Passwords" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: VADER" + "\n" +
+ "" + "\n" +
+ "[Sharepoint Services Database]" + "\n" +
+ "Group: Database Passwords" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[Anti-Virus (Trend)]" + "\n" +
+ "Group: Miscellaneous" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: http://ensql1.enquiro.net/officescan/console/cgi/cgiChkMasterPwd.exe" + "\n" +
+ "" + "\n" +
+ "[Anti-Virus Uninstall]" + "\n" +
+ "Group: Miscellaneous" + "\n" +
+ "User Name: " + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[Anti-Virus Unload]" + "\n" +
+ "Group: Miscellaneous" + "\n" +
+ "User Name: " + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[ENEXC1 Security Certificate]" + "\n" +
+ "Group: Miscellaneous" + "\n" +
+ "User Name: " + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Required for using Outlook over HTTP" + "\n" +
+ "" + "\n" +
+ "[Eye Tracking Study PDF]" + "\n" +
+ "Group: Miscellaneous" + "\n" +
+ "User Name: " + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: PDF Password" + "\n" +
+ "" + "\n" +
+ "[Google Account - Research Department]" + "\n" +
+ "Group: Miscellaneous" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Used to track web history for personalization" + "\n" +
+ "" + "\n" +
+ "[Google Account - Research Department]" + "\n" +
+ "Group: Miscellaneous" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Used to track web history for personalization" + "\n" +
+ "" + "\n" +
+ "[Goldmine Administrator]" + "\n" +
+ "Group: Miscellaneous" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Adding users to Goldmine" + "\n" +
+ "" + "\n" +
+ "[AIG Insurance]" + "\n" +
+ "Group: Clients" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSPS1" + "\n" +
+ "" + "\n" +
+ "[Allstate Insurance Company]" + "\n" +
+ "Group: Clients" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSPS1" + "\n" +
+ "" + "\n" +
+ "[Babyzone]" + "\n" +
+ "Group: Clients" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Babyzone Google Sitemaps Login" + "\n" +
+ "" + "\n" +
+ "[Habeas]" + "\n" +
+ "Group: Clients" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSPS1" + "\n" +
+ "" + "\n" +
+ "[Hanley Wood]" + "\n" +
+ "Group: Clients" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSPS1" + "\n" +
+ "" + "\n" +
+ "[Kaboose Inc.]" + "\n" +
+ "Group: Clients" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSPS1" + "\n" +
+ "" + "\n" +
+ "[Lesley University]" + "\n" +
+ "Group: Clients" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSPS1" + "\n" +
+ "" + "\n" +
+ "[Plastic Products Mfg]" + "\n" +
+ "Group: Clients" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSPS1" + "\n" +
+ "" + "\n" +
+ "[Project Server Extranet User]" + "\n" +
+ "Group: Clients" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[Rent Chalets]" + "\n" +
+ "Group: Clients" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSPS1" + "\n" +
+ "" + "\n" +
+ "[Siemens Communications]" + "\n" +
+ "Group: Clients" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSPS1" + "\n" +
+ "" + "\n" +
+ "[Sterling Commerce]" + "\n" +
+ "Group: Clients" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: ENSPS1" + "\n" +
+ "" + "\n" +
+ "[Enquiro]" + "\n" +
+ "Group: FTP" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: " + "\n" +
+ "" + "\n" +
+ "[clientlogs.enquiro.net]" + "\n" +
+ "Group: FTP" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: 199.60.252.152" + "\n" +
+ "" + "\n" +
+ "[HrHero]" + "\n" +
+ "Group: FTP" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: 199.60.252.152" + "\n" +
+ "" + "\n" +
+ "[Kaboose]" + "\n" +
+ "Group: FTP" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: 199.60.252.152" + "\n" +
+ "" + "\n" +
+ "[Royal Roads University]" + "\n" +
+ "Group: FTP" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: 199.60.252.152" + "\n" +
+ "" + "\n" +
+ "[ftp.enquiro.com]" + "\n" +
+ "Group: FTP" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: " + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: TYRANUS (199.60.252.157)" + "\n" +
+ "" + "\n" +
+ "[Gene6 FTP Admistrator]" + "\n" +
+ "Group: FTP" + "\n" +
+ "User Name: ABC" + "\n" +
+ "URL: ensql2" + "\n" +
+ "Password: 123456" + "\n" +
+ "Notes: Used to create FTP folders for client use" + "\n" +
+ "" + "\n";
+
+
+//-------------------------------------------------------------------------
+//
+// This data is probably in the KeePassX export format that is not supported right now
+//
+testData['Jordan_Curzon_data'] = "" +
+ "*** Group: Financial ***" + "\n" +
+ "" + "\n" +
+ " Title: Allstate" + "\n" +
+ " Username: jones" + "\n" +
+ " Url: allstate.com" + "\n" +
+ " Password: bobfred" + "\n" +
+ " Comment:" + "\n" +
+ "" + "\n" +
+ " Title: NW Natural" + "\n" +
+ " Username: jones@gmail.com" + "\n" +
+ " Url: nwnatural.com" + "\n" +
+ " Password: bobfred" + "\n" +
+ " Comment: Account number: 097oe9u0098098" + "\n" +
+ "" + "\n";
+
diff --git a/frontend/gamma/tests/tests/Clipperz/KeePassExportProcessor.html b/frontend/gamma/tests/tests/Clipperz/KeePassExportProcessor.html
new file mode 100644
index 0000000..a8a1317
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/KeePassExportProcessor.html
@@ -0,0 +1,59 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.KeePassExportProcessor - test</title>
+
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/KeePassExportProcessor.js'></script>
+
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.Async.js"></script>
+
+ <!-- script type="text/javascript" src="./KeePassExportProcessor.data.js"></script>
+ <script type="text/javascript" src="./KeePassExportProcessor.test.js"></script -->
+
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript" src="./KeePassExportProcessor.data.js"></script>
+<script type="text/javascript" src="./KeePassExportProcessor.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/KeePassExportProcessor.test.js b/frontend/gamma/tests/tests/Clipperz/KeePassExportProcessor.test.js
new file mode 100644
index 0000000..0ce4c91
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/KeePassExportProcessor.test.js
@@ -0,0 +1,141 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+
+ 'test1_test': function (someTestArgs) {
+ var deferredResult;
+ var keePassProcessor;
+
+ keePassProcessor = new Clipperz.KeePassExportProcessor();
+
+ deferredResult = new Clipperz.Async.Deferred("test1_test", someTestArgs);
+ deferredResult.addCallback(function(aResult) { return "[Gmail]\nGroup: General\nUserName: joe.clipperz\nURL: http://www.gmail.com\nPassword: NHy08ZCMYsqUeLQCawR7\n\n[del.icio.us]\nGroup: General\nUserName: joe69\nURL: http://del.icio.us\nPassword: tS1cIEeqp5y0wkU\n\n[Amazon]\nGroup: General\nUserName: jclipperz\nURL: http://www.amazon.com\nPassword: wvpkqNPIsqlI5g6XE9Tz\n\n[Paypal]\nGroup: General\nUserName: joeclipperz\nURL: http://www.paypal.com\nPassword: 24T4wIcvHnM28T3L\n\n[Technorati]\nGroup: General\nUserName: jclipperz\nURL: http://www.technorati.com\nPassword: UcVeNqF\n\n[American Airlines]\nGroup: General\nUserName: joe.clipperz\nURL: http://www.aa.com\nPassword: AtrYbmi7lmSjR\n" });
+ deferredResult.addMethod(keePassProcessor, 'deferredParse');
+ deferredResult.addCallback(function(aResult) { is(MochiKit.Base.serializeJSON(aResult), "[{\"Title\":\"Gmail\", \"Group\":\"General\", \"UserName\":\"joe.clipperz\", \"URL\":\"http://www.gmail.com\", \"Password\":\"NHy08ZCMYsqUeLQCawR7\"}, {\"Title\":\"del.icio.us\", \"Group\":\"General\", \"UserName\":\"joe69\", \"URL\":\"http://del.icio.us\", \"Password\":\"tS1cIEeqp5y0wkU\"}, {\"Title\":\"Amazon\", \"Group\":\"General\", \"UserName\":\"jclipperz\", \"URL\":\"http://www.amazon.com\", \"Password\":\"wvpkqNPIsqlI5g6XE9Tz\"}, {\"Title\":\"Paypal\", \"Group\":\"General\", \"UserName\":\"joeclipperz\", \"URL\":\"http://www.paypal.com\", \"Password\":\"24T4wIcvHnM28T3L\"}, {\"Title\":\"Technorati\", \"Group\":\"General\", \"UserName\":\"jclipperz\", \"URL\":\"http://www.technorati.com\", \"Password\":\"UcVeNqF\"}, {\"Title\":\"American Airlines\", \"Group\":\"General\", \"UserName\":\"joe.clipperz\", \"URL\":\"http://www.aa.com\", \"Password\":\"AtrYbmi7lmSjR\"}]", "first test"); });
+ deferredResult.addErrback(function(anError) { is("ERROR", anError) });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ 'test2_test': function (someTestArgs) {
+ var deferredResult;
+ var keePassProcessor;
+
+ keePassProcessor = new Clipperz.KeePassExportProcessor();
+
+ deferredResult = new Clipperz.Async.Deferred("test2_test", someTestArgs);
+ deferredResult.addCallback(function(aResult) { return "[Gmail]\nGroup: General\nUserName: joe.clipperz\nURL: http://www.gmail.com\nPassword: NHy08ZCMYsqUeLQCawR7\nNotes: Personal account\n\n[del.icio.us]\nGroup: General\nUserName: joe69\nURL: http://del.icio.us\nPassword: tS1cIEeqp5y0wkU\nNotes: social bookmarking site\n\n[Amazon]\nGroup: General\nUserName: jclipperz\nURL: http://www.amazon.com\nPassword: wvpkqNPIsqlI5g6XE9Tz\nNotes: The US online store\n\n[Paypal]\nGroup: General\nUserName: joeclipperz\nURL: http://www.paypal.com\nPassword: 24T4wIcvHnM28T3L\nNotes: Linked to my savings account\n\n[Technorati]\nGroup: General\nUserName: jclipperz\nURL: http://www.technorati.com\nPassword: UcVeNqF\nNotes: Blog ranking and searching\n\n[American Airlines]\nGroup: General\nUserName: joe.clipperz\nURL: http://www.aa.com\nPassword: AtrYbmi7lmSjR\nNotes: Adavantages card n. 795495\n" });
+ deferredResult.addMethod(keePassProcessor, 'deferredParse');
+ deferredResult.addCallback(function(aResult) { is(MochiKit.Base.serializeJSON(aResult), "[{\"Title\":\"Gmail\", \"Group\":\"General\", \"UserName\":\"joe.clipperz\", \"URL\":\"http://www.gmail.com\", \"Password\":\"NHy08ZCMYsqUeLQCawR7\", \"Notes\":\"Personal account\"}, {\"Title\":\"del.icio.us\", \"Group\":\"General\", \"UserName\":\"joe69\", \"URL\":\"http://del.icio.us\", \"Password\":\"tS1cIEeqp5y0wkU\", \"Notes\":\"social bookmarking site\"}, {\"Title\":\"Amazon\", \"Group\":\"General\", \"UserName\":\"jclipperz\", \"URL\":\"http://www.amazon.com\", \"Password\":\"wvpkqNPIsqlI5g6XE9Tz\", \"Notes\":\"The US online store\"}, {\"Title\":\"Paypal\", \"Group\":\"General\", \"UserName\":\"joeclipperz\", \"URL\":\"http://www.paypal.com\", \"Password\":\"24T4wIcvHnM28T3L\", \"Notes\":\"Linked to my savings account\"}, {\"Title\":\"Technorati\", \"Group\":\"General\", \"UserName\":\"jclipperz\", \"URL\":\"http://www.technorati.com\", \"Password\":\"UcVeNqF\", \"Notes\":\"Blog ranking and searching\"}, {\"Title\":\"American Airlines\", \"Group\":\"General\", \"UserName\":\"joe.clipperz\", \"URL\":\"http://www.aa.com\", \"Password\":\"AtrYbmi7lmSjR\", \"Notes\":\"Adavantages card n. 795495\"}]", "second test"); });
+ deferredResult.addErrback(function(anError) { is("ERROR", anError) });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ 'test3_test': function (someTestArgs) {
+ var deferredResult;
+ var keePassProcessor;
+
+ keePassProcessor = new Clipperz.KeePassExportProcessor();
+
+ deferredResult = new Clipperz.Async.Deferred("test3_test", someTestArgs);
+ deferredResult.addCallback(function(aResult) { return "[Gmail]\nGroup: General\nUserName: joe.clipperz\nURL: http://www.gmail.com\nPassword: NHy08ZCMYsqUeLQCawR7\nNotes: Personal account\nwith some notes stored\non multiple lines\n\n[del.icio.us]\nGroup: General\nUserName: joe69\nURL: http://del.icio.us\nPassword: tS1cIEeqp5y0wkU\nNotes: social bookmarking site\n\n[Amazon]\nGroup: General\nUserName: jclipperz\nURL: http://www.amazon.com\nPassword: wvpkqNPIsqlI5g6XE9Tz\nNotes: The US online store\n\n[Paypal]\nGroup: General\nUserName: joeclipperz\nURL: http://www.paypal.com\nPassword: 24T4wIcvHnM28T3L\nNotes: Linked to my savings account\n\n[Technorati]\nGroup: General\nUserName: jclipperz\nURL: http://www.technorati.com\nPassword: UcVeNqF\nNotes: Blog ranking and searching\n\n[American Airlines]\nGroup: General\nUserName: joe.clipperz\nURL: http://www.aa.com\nPassword: AtrYbmi7lmSjR\nNotes: Adavantages card n. 795495\n" });
+ deferredResult.addMethod(keePassProcessor, 'deferredParse');
+ deferredResult.addCallback(function(aResult) { is(MochiKit.Base.serializeJSON(aResult), "[{\"Title\":\"Gmail\", \"Group\":\"General\", \"UserName\":\"joe.clipperz\", \"URL\":\"http://www.gmail.com\", \"Password\":\"NHy08ZCMYsqUeLQCawR7\", \"Notes\":\"Personal account\\nwith some notes stored\\non multiple lines\\n\"}, {\"Title\":\"del.icio.us\", \"Group\":\"General\", \"UserName\":\"joe69\", \"URL\":\"http://del.icio.us\", \"Password\":\"tS1cIEeqp5y0wkU\", \"Notes\":\"social bookmarking site\"}, {\"Title\":\"Amazon\", \"Group\":\"General\", \"UserName\":\"jclipperz\", \"URL\":\"http://www.amazon.com\", \"Password\":\"wvpkqNPIsqlI5g6XE9Tz\", \"Notes\":\"The US online store\"}, {\"Title\":\"Paypal\", \"Group\":\"General\", \"UserName\":\"joeclipperz\", \"URL\":\"http://www.paypal.com\", \"Password\":\"24T4wIcvHnM28T3L\", \"Notes\":\"Linked to my savings account\"}, {\"Title\":\"Technorati\", \"Group\":\"General\", \"UserName\":\"jclipperz\", \"URL\":\"http://www.technorati.com\", \"Password\":\"UcVeNqF\", \"Notes\":\"Blog ranking and searching\"}, {\"Title\":\"American Airlines\", \"Group\":\"General\", \"UserName\":\"joe.clipperz\", \"URL\":\"http://www.aa.com\", \"Password\":\"AtrYbmi7lmSjR\", \"Notes\":\"Adavantages card n. 795495\"}]", "third test"); });
+ deferredResult.addErrback(function(anError) { is("ERROR", anError) });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'Barb_Newman_test': function (someTestArgs) {
+ var deferredResult;
+ var keePassProcessor;
+
+ keePassProcessor = new Clipperz.KeePassExportProcessor();
+
+ deferredResult = new Clipperz.Async.Deferred("Barb_Newman_test", someTestArgs);
+// deferredResult.addCallback(function () { return testData['Barb_Newman_data']; });
+ deferredResult.addMethod(keePassProcessor, 'deferredParse');
+ deferredResult.addBoth(function(aResult) {
+ SimpleTest.is(aResult.length, 121, "Barb's data contains 121 records");
+ return aResult;
+ });
+ deferredResult.addBoth(function(aResult) {
+ SimpleTest.is(MochiKit.Base.serializeJSON(aResult[0]), "{\"Title\":\"Domain Administration Account\", \"Group\":\"Windows\", \"User Name\":\"_ABC\", \"URL\":\"\", \"Password\":\"123456\", \"Notes\":\"\"}", "Barb's first record data matches");
+ return aResult;
+ });
+// deferredResult.callback();
+ deferredResult.callback(testData['Barb_Newman_data']);
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'Jordan_Curzon_test': function (someTestArgs) {
+ var deferredResult;
+ var keePassProcessor;
+
+ keePassProcessor = new Clipperz.KeePassExportProcessor();
+
+ deferredResult = new Clipperz.Async.Deferred("Jordan_Curzon_test", someTestArgs);
+ deferredResult.addCallback(function () { return testData['Jordan_Curzon_data']; });
+ deferredResult.addMethod(keePassProcessor, 'deferredParse');
+ deferredResult.addBoth(function(aResult) {
+ SimpleTest.is(aResult.length, 2, "Jordarn's data contains 2 records");
+ return aResult;
+ });
+ deferredResult.addBoth(function(aResult) {
+ SimpleTest.is(MochiKit.Base.serializeJSON(aResult[0]), "{\"Title\":\"Allstate\", \"Username\":\"jones\", \"Url\":\"allstate.com\", \"Password\":\"bobfred\", \"Comment\":\"\"}", "Barb's first record data matches");
+ return aResult;
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+*/
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+
+
+//#############################################################################
+
+SimpleTest.runDeferredTests("Clipperz.KeyPassExportProcessor", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/KeyValueObjectStore.html b/frontend/gamma/tests/tests/Clipperz/KeyValueObjectStore.html
new file mode 100644
index 0000000..f856f98
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/KeyValueObjectStore.html
@@ -0,0 +1,52 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Async.js'></script>
+
+ <script type='text/javascript' src='../../../js/Clipperz/KeyValueObjectStore.js'></script>
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.Async.js"></script>
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript" src="KeyValueObjectStore.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/KeyValueObjectStore.test.js b/frontend/gamma/tests/tests/Clipperz/KeyValueObjectStore.test.js
new file mode 100644
index 0000000..53cf5d3
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/KeyValueObjectStore.test.js
@@ -0,0 +1,255 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+
+ 'simple_tests': function() {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("simple_tests", {trace:false});
+ deferredResult.addCallback(function() {
+ var objectStore;
+
+ objectStore = new Clipperz.KeyValueObjectStore();
+
+ ok(objectStore != null, "created an object store");
+
+ objectStore.setValue('key', "value");
+ is(objectStore.getValue('key'), "value", "can store and read a value to a simple key");
+
+ objectStore.setValue('key', "overwritten value");
+ is(objectStore.getValue('key'), "overwritten value", "using the same key overwrites the previous value");
+
+ objectStore.setValue('record.keys', [1, 2, 3]);
+ is(
+ MochiKit.Base.compare(objectStore.getValue('record'), {'keys': [1,2,3]}),
+ 0,
+ "getting a partial key returns the whole content associate with that key"
+ );
+ is(
+ MochiKit.Base.compare(objectStore.getValue('record.keys'), [1,2,3]),
+ 0,
+ "accessing data using a key.path return the matching content"
+ );
+ is(
+ MochiKit.Base.compare(objectStore.getValue('record.keys.1'), 2),
+ 0,
+ "accessing data using a key.path return the matching content, even inside an array"
+ );
+
+ is(
+ objectStore.setValue('key', "value"),
+ "value",
+ "setting a value return the value itself, as a convenience to chain deferred methods"
+ );
+
+ is(
+ objectStore.getValue('not_set_key'),
+ null,
+ "accessing a previously undefined key will return null"
+ );
+ is(
+ objectStore.getValue('record.not_set_key'),
+ null,
+ "accessing a previously undefined key will return null, even if part of the path is defined"
+ );
+ is(
+ objectStore.getValue('not_set_path.not_set_key'),
+ null,
+ "accessing a previously undefined key will return null, even if using a completely undefined path"
+ );
+
+ objectStore.removeAllData();
+ is(
+ objectStore.getValue('key'),
+ null,
+ "getting a value after a 'removeAllData' return no value"
+ );
+
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'simple_deferredGetOrSet_test': function () {
+ var deferredResult;
+ var objectStore;
+ var testValue;
+
+ objectStore = new Clipperz.KeyValueObjectStore();
+ testValue = "nifty test value";
+
+ deferredResult = new Clipperz.Async.Deferred("simple_deferredGetOrSet_test", {trace:false});
+ deferredResult.addMethod(objectStore, 'setValue', 'key', testValue);
+ deferredResult.addMethod(objectStore, 'deferredGetOrSet', 'key', function() {return testValue});
+ deferredResult.addCallback(function(aResult) {
+ SimpleTest.is(aResult, testValue, "deferredGetOrSet works when accessing data already present on the object store");
+ })
+ deferredResult.callback();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredGetOrSet_test': function () {
+ var deferredResult;
+ var objectStore;
+ var testValue;
+
+ objectStore = new Clipperz.KeyValueObjectStore();
+ testValue = "nifty test value";
+
+ deferredResult = new Clipperz.Async.Deferred("deferredGetOrSet_test", {trace:false});
+ deferredResult.addMethod(objectStore, 'setValue', 'key.path', testValue);
+ deferredResult.addMethod(objectStore, 'deferredGetOrSet', 'key', function() {return {'path': testValue}; });
+ deferredResult.addCallback(function(aResult) {
+ SimpleTest.is(aResult['path'], testValue, "deferredGetOrSet works when accessing data already present on the object store");
+ })
+ deferredResult.callback();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'simple_deferredGetOrSet_withMissingValue_test': function () {
+ var deferredResult;
+ var objectStore;
+ var testValue;
+
+ objectStore = new Clipperz.KeyValueObjectStore();
+ testValue = "nifty test value";
+
+ deferredResult = new Clipperz.Async.Deferred("simple_deferredGetOrSet_withMissingValue_test", {trace:false});
+ deferredResult.addMethod(objectStore, 'deferredGetOrSet', 'key', function() {return testValue});
+ deferredResult.addCallback(function(aResult) {
+ SimpleTest.is(aResult, testValue, "deferredGetOrSet works when accessing data already present on the object store");
+ })
+ deferredResult.callback();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deferredGetOrSet_withMissingValue_test': function () {
+ var deferredResult;
+ var objectStore;
+ var testValue;
+
+ objectStore = new Clipperz.KeyValueObjectStore();
+ testValue = "nifty test value";
+
+ deferredResult = new Clipperz.Async.Deferred("deferredGetOrSet_withMissingValue_test", {trace:false});
+ deferredResult.addMethod(objectStore, 'deferredGetOrSet', 'key', function() {return {'path': testValue}; });
+ deferredResult.addCallback(function(aResult) {
+ SimpleTest.is(aResult['path'], testValue, "deferredGetOrSet works when accessing data already present on the object store");
+ })
+ deferredResult.callback();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deleteObjectKey': function () {
+ var someValues;
+ var objectStore;
+
+ someValues = {
+ 'key1': {
+ 'key1_1': "value 1.1",
+ 'key1_2': "value 1.2"
+ },
+ 'key2': {
+ 'key2_1': {
+ 'key2.1.1': "value 2.1.1",
+ 'key2.1.2': "value 2.1.2"
+ },
+ 'key2_2': "value 2.2"
+ }
+ }
+
+ objectStore = new Clipperz.KeyValueObjectStore();
+ objectStore.initWithValues(someValues);
+ objectStore.removeValue('key2.key2_1');
+
+ SimpleTest.is(objectStore.getValue('key1.key1_1'), "value 1.1", "The first element is still there");
+ SimpleTest.is(objectStore.getValue('key1.key1_2'), "value 1.2", "The second element is still there");
+ SimpleTest.is(objectStore.getValue('key2.key2_1'), null, "The deleted element is actually gone");
+ SimpleTest.is(MochiKit.Base.keys(objectStore.getValue('key2')).length, 1, "Even the key is not stored anylonger");
+ SimpleTest.is(objectStore.getValue('key2.key2_2'), "value 2.2", "The sibling of the deleted element is still there");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'accessDataUsingANumericKey': function () {
+ var someValues;
+ var objectStore;
+
+ someValues = {
+ '1': "value 1",
+ '2': "value 2"
+ }
+
+ objectStore = new Clipperz.KeyValueObjectStore();
+ objectStore.initWithValues(someValues);
+
+ SimpleTest.is(objectStore.getValue(1), "value 1", "The first element is accessed even using a numeric key");
+
+ objectStore.setValue(3, "value 3");
+ SimpleTest.is(objectStore.getValue('3'), "value 3", "I can set the value using a numeric key and get it with a string key");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'isEmpty_test': function () {
+ var someValues;
+ var objectStore;
+
+ someValues = {
+ '1': "value 1",
+ '2': "value 2"
+ }
+
+ objectStore = new Clipperz.KeyValueObjectStore();
+ SimpleTest.is(objectStore.isEmpty(), true, "A newly initialized KeyValueStore is empty");
+
+ objectStore.initWithValues(someValues);
+ SimpleTest.is(objectStore.isEmpty(), false, "Once the KeyValueStore is initialized with some values, it is no logner empty");
+
+ objectStore.removeAllData();
+ SimpleTest.is(objectStore.isEmpty(), true, "A KeyValueStore is empty after invoking the 'removeAllData' method");
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+//#############################################################################
+
+SimpleTest.runDeferredTests("Clipperz.KeyValueObjectStore", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/BookmarkletProcessor.html b/frontend/gamma/tests/tests/Clipperz/PM/BookmarkletProcessor.html
new file mode 100644
index 0000000..9bd344e
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/BookmarkletProcessor.html
@@ -0,0 +1,59 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.BookmarkletProcessor - test</title>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/BookmarkletProcessor.js'></script>
+
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.Async.js"></script>
+
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript" src="BookmarkletProcessor.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/BookmarkletProcessor.test.js b/frontend/gamma/tests/tests/Clipperz/PM/BookmarkletProcessor.test.js
new file mode 100644
index 0000000..21776a3
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/BookmarkletProcessor.test.js
@@ -0,0 +1,132 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+function testBookmarkletConfigurationString (aConfiguration, shouldFail, aMessage) {
+// var configuration;
+
+//try {
+// configuration = Clipperz.Base.evalJSON(aConfiguration);
+//} catch (exception) {
+// console.log("EXCEPTION", exception);
+// throw exception;
+//}
+
+//console.log("configuration", configuration);
+
+ if (shouldFail == true) {
+ try {
+ Clipperz.PM.BookmarkletProcessor.checkBookmarkletConfiguration(aConfiguration);
+ SimpleTest.ok(false, "vulnerability not caught - " + aMessage);
+ } catch(exception) {
+ SimpleTest.ok(true, "vulnerability correctly caught - " + aMessage);
+ }
+ } else {
+ try {
+ Clipperz.PM.BookmarkletProcessor.checkBookmarkletConfiguration(aConfiguration);
+ SimpleTest.ok(true, "configuration correctly checked - " + aMessage);
+ } catch(exception) {
+ SimpleTest.ok(false, "configuration wrongly caught as malicious - " + aMessage);
+// console.log(exception);
+ }
+ }
+}
+
+//#############################################################################
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+
+ 'simpleAmazonConfiguration_test': function () {
+ var bookmarkletConfigurationString;
+
+ bookmarkletConfigurationString = "{"+
+ "\"page\": {\"title\": \"Sign In\"},\n" +
+ "\"form\": {" +
+ "\"attributes\": {" +
+ "\"action\": \"https://www.amazon.com/gp/flex/sign-in/select.html\",\n" +
+ "\"method\": \"post\"" +
+ "},\n" +
+ "\"inputs\": [" +
+ "{\"type\": \"hidden\",\n\"name\": \"path\",\n\"value\": \"/gp/yourstore\"},\n" +
+ "{\"type\": \"hidden\",\n\"name\": \"useRedirectOnSuccess\",\n\"value\": \"1\"},\n" +
+ "{\"type\": \"hidden\",\n\"name\": \"query\",\n\"value\": \"signIn=1&action=sign-out&useRedirectOnSuccess=1&path=/gp/yourstore&ref_=pd_irl_gw_r\"},\n" +
+ "{\"type\": \"hidden\",\n\"name\": \"mode\",\n\"value\": \"\"},\n" +
+ "{\"type\": \"hidden\",\n\"name\": \"redirectProtocol\",\n\"value\": \"\"},\n" +
+ "{\"type\": \"hidden\",\n\"name\": \"pageAction\",\n\"value\": \"/gp/yourstore\"},\n" +
+ "{\"type\": \"hidden\",\n\"name\": \"disableCorpSignUp\",\n\"value\": \"\"},\n" +
+ "{\"type\": \"hidden\",\n\"name\": \"protocol\",\n\"value\": \"https\"},\n" +
+ "{\"type\": \"hidden\",\n\"name\": \"sessionId\",\n\"value\": \"105-1479357-7902864\"},\n" +
+ "{\"type\": \"hidden\",\n\"name\": \"referer\",\n\"value\": \"flex\"},\n" +
+ "{\"type\": \"text\",\n\"name\": \"email\",\n\"value\": \"\"},\n" +
+ "{\"type\": \"password\",\n\"name\": \"password\",\n\"value\": \"\"},\n" +
+ "{\"type\": \"hidden\",\n\"name\": \"metadata1\",\n\"value\": \"Firefox 3.0.3 Mac\"},\n" +
+ "{\"type\": \"hidden\",\n\"name\": \"metadataf1\",\n\"value\": \"\"},\n" +
+ "{\"type\": \"hidden\",\n\"name\": \"metadata2\",\n\"value\": \"Default Plug-in Java Embedding Plugin 0.9.6.4 Shockwave Flash 90124RealPlayer Plugin QuickTime Plug-in 7.5.5 Flip4Mac Windows Media Plugin 2.2 4||1440-900-878-24-*-*-*\"},\n" +
+ "{\"type\": \"hidden\",\n\"name\": \"metadata3\",\n\"value\": \"timezone: -1 execution time: 3\"},\n" +
+ "{\"name\": \"action\",\n\"type\": \"radio\",\n\"options\": [" +
+ "{\"value\": \"new-user\",\n\"checked\": false},\n" +
+ "{\"value\": \"sign-in\",\n\"checked\": true}" +
+ "]}" +
+ "]" +
+ "},\n" +
+ "\"version\": \"0.2.3\"" +
+ "}";
+ testBookmarkletConfigurationString(bookmarkletConfigurationString, false, "regular Amazon.com configuration");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hackedConfigurationWithXSSAttackVectorReadyToBeTriggeredWhenActivatingTheDirectLogin_test': function () {
+ var bookmarkletConfigurationString;
+
+ bookmarkletConfigurationString = "{" +
+ "\"page\": {\"title\": \"Example Attack\"}," +
+ "\"form\": { " +
+ "\"attributes\": { " +
+ "\"action\": \"javascript:opener.document.body.innerHTML = 'hacked!';close();\", " +
+ "\"style\": \"-moz-binding:url('http://ha.ckers.org/xssmoz.xml#xss')\", " +
+ "\"method\": null " +
+ "}, " +
+ "\"inputs\": [" +
+ "{\"type\": \"text\", \"name\": \"username\", \"value\": \"\"}, " +
+ "{\"type\": \"password\", \"name\": \"password\", \"value\": \"\"}" +
+ "]" +
+ "}," +
+ "\"version\": \"0.2.3\" " +
+ "}";
+ testBookmarkletConfigurationString(bookmarkletConfigurationString, false, "hacked configuration that is trying to inject a XSS attack vector. It should not fail, as it is responsability of the direct login to avoid triggering such attack vector");
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+}
+
+//#############################################################################
+
+SimpleTest.runDeferredTests("Clipperz.PM.BookmarkletProcessor", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/Connection.data.js b/frontend/gamma/tests/tests/Clipperz/PM/Connection.data.js
new file mode 100644
index 0000000..9dec232
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/Connection.data.js
@@ -0,0 +1,841 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+testData = {
+
+ //-------------------------------------------------------------------------
+
+ 'joe_clipperz_offline_copy_data': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ 'f527cdd90d0d47f8524b4e165398ad1455eba515d04abd101d1e93b3c6ae0674': {
+ s: '186f0c40bf73f2af236eaa6c429df225efa933050c9aae65240e93b7b362e3ee',
+ v: 'ac61a6e325ecf329926a86084f591d8852d0ad3e4a6080f2adc901b82395ecaf',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5":"0","13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551":"1","062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80":"2","ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c":"3","507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a":"4","d5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d":"5","de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4":"6","d620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045":"7","f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732":"8","36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113":"9","fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6":"10","6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18":"11","9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291":"12","6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a":"13","6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728":"14","8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39":"15","084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d":"16","7bb69b6366a8012f181c01e368ba18d4f7a82bcabb4959189736ad124c4bbfbb":"17","5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4":"18","c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065":"19"},"data":"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"},"directLogins":{"index":{"61e87fdc4f1d9112e3b30c1f6812d095dcdb24f014c83319091eb6c9899ec348":"0","989593d4c48929f0c8f1581aa96969c622807e99619ed4732026e967530a68ad":"1","9f7979368fa29f66c44bd97ecaf6c545abc800b1c7bb21b7655a68e1514c3906":"2","dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496":"3","aa18149164302d5dbe7e2d3724565b9550e00887b49978559783b2e38c625584":"4","1f9bfd677b531a03168d3f8bd8afabb5357244a7bc355dff50bd6c0a072114a6":"5","a48e38845713462ecc9f827149eeaae87da882031f98ef8ebbf9ee9537b63468":"6","6f7bbc4e42ea462b5246e6f51c3f86056bec50601ce2de6067c8c1d26f21c07f":"7","2df54059e78f5771f23bd285cce19595b38331b73d67020424d9a1b2257db09c":"8","065cd0c270e5e8ce50e4ea8e3828dccdae18c01ab030813d756a87d03fe68784":"9","ddbc8d01300a4f10631cbde09e1246332eade3a877a2205209f9eb9e5bc9da0b":"10","9b7a30e667afc9f76ba77600658b2c13bff52432d444261d39bf3d069a160afe":"11","9fd2929cde3d32d9cbc5f1d787f2f64729a5e12a14410556b31c0c099762c46a":"12","f695fc36ac56bead80c0d20a88e01e382819c18dc268f1679551b7c83db7cb14":"13","f22dc41ffabef4b3bc8f7af804fec975bd50718098322a673cbe4aaff9464ae1":"14","03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c":"15","a7b32e72502804bf2946a2a8856139cbbb759c5777e6b3e673db1fdf7e3bd06e":"16","cb9ae0bba1957075ccdbfd3b3481704d62087687a2ac7c411a4f07d444bde0f7":"17","7e1d069b7fa57c03bd7bf48807520feb953157834503aaff8c9d493f37dea69d":"18","24404059cabc63b2dbff0f42ba57183108b8189ef53ab62fa25141a1caea824b":"19","33cf9758477460a8056deef0295a1ebe65b39b392c361ceb920a83edacfe5d78":"20","e9a16316f330e3d150f6ffd194f6fd8acd1426757b097de4b88ca0db875202e4":"21"},"data":"xuiWbu5GjkueQhyH6sKg5Cn9/CSsPIjYgbhaHmjgwnnB+GL8UO5u0uURxTY6tkG2HbaFRpYZwLnqUUulEkVY6iNqJajFI0qDtrKams11cF2y9LaAalbqyv6U7EUt76d666DkXW8tf88nJ4HYfyAhhPCJ0cw5053K9BAVPbQM7fMA4MYY29k45U3HcIKNZcNqMftCc+fZB+fmZl1g7mSbrXaZyagRkwWwTdJ6/ecVOSSVOkWpckAaQWzGhwbO6zVWLtR9XQReIQZV52TwDMnV5IYJHnlw0Uvv2ZCVSu/oMN2TneW5fcIwQ0x/SRe+n4Mklzucpvasza+ZhRaRUFS53kvmbfPFI5tXqB3Z1+9S7LRLr9Ws97suTQ6G5eW6jKT2vf65ehnQJtA/gW6uwH+3IAT7ukFxO1knaRf7dRJDLuIc4Xnh+bRDnZUqfA+B+04pp6r0OS9oysD35t/HydVFeHgoyMCbL4RzduZvmu7y16WhIznn0DEfRmrYmC68C+DNcAbxeiXU8v14PgGycIg1++0v44Qor/BXfP5JW4WnYjVLW3aXN3FgI5rPuN6PqTzMn7z+eF2V28GNss5pui1xIbR2bTECAAnaRQiaz98F1LH4z5kYG1ehmyjIOLqz1nAv3Kuo7+DZKaSez4nX1oWznbXEnwd6uguukcCGpQllZoHYso/fz07e6p/9fskXPmg7LnMMHApP7Vay6XPhXV/AG0imU7uREFLbgnw3305Ey9fslmD8qCzi8LlqNALEt1TFNpAukvqodkv8V1o6zqzYNMSKaqJV4E9dWMNDpOFFTKv1FuZjZfzyPwyCcePgP7vcJGtUSYqRJwl56Ia8UA+l3FBiX8DCSW3GkG+wusf7bZ5kV6lV5DQJTScIyFxWwcECJ5S8/2QaBPTopeLo2NuMmFwjUwhBGVrDkUmtqjfb6DSfr/dR6AbmraRLXrpd/KUN7wWgp5GdLUAKNT+RdsUc0mLsLF3oT+XshfgfsQqi/pDnX9x3QfH/WuRtoywAIE5APU8Rnl+1NGsEidzeYrBnryA8VRi9vxfhuaxe3+rx1ewB1pgVSERPLF+0MYtetug01yRSxEUYJgYHxQmfnmkCoz+kKCejdpYVqKC+RzhjIMytRbFXNmS0NpRmtBxZrSIskKXjjwjUeEzMAttqAPC4IK1kt5IK+5NZPNZbf2Y8qDsWcBNXfw5sh7pJymRwPCge+S5Jy69tadeSAWpX1YMuq+By/o2KWawpokstxmE6w2RNPFhKXtGPvukoDnpV9wDFgBcoNDJctDVdIPqNolLxn6Y57HoOid6CO2s+PqQcfZSEo7V70Rk6OQ+02M0ED0/4XGq6vflc6IlQ5LO1urRT4INrAQmWdulHnmLf+HESJAc0ZICO1T73aQVaGVVHFQxDMVgaTer1UXP1xxfB1tazfJme2aycsDM1WS5lTwMRRlvgwupkzS+YwGq+nB1QFsZknKgeoacGYxQjFo6EGvszitNU+sK4U/EeAShS/nM/96c10awZVwQnal5T9sYOO31mA2pxyI4TwxkgWw2wkj38msz+8afHvPlFlqlU0UiEm7hYMj5s4L08msIY+GVc7tGgaRYklsnRFUU6s0Kql8BLPkbpdM9RAoSczy4tlGlaBAPeC6ouPgyNf1+VRfVZnqlPF063ok1KcEbd6QqQHo0kgsUMLbtdPbe752dmUo64sZXkuDKISmFEwQjn3SN4K7OOg9sk5QEz1STMvm8pazq1yb+0CE1iad5e+HoNkrGT+5GSVX+YShiItu5eyZXjZ7m8GQ2HZTA7mgv6FwGSI6o0URPIRk/UgKMCggTSat2gf3oVk+aZvRCvkGg+ISjkEKk49tQasLDAfvVjdue2JHpM1UwNhTlurHNasqnwNEzFzhflsMuM+V7dv/6/3AiJBUSC9Oyd/kWRpt5DS0nW+BkBcL5eBoofyssj0tAqxpWe+nNwCL9ljVPdytQCHWp71xEqnDxSq1KWV7u57MmBSaGStdyWtShBvEQdHQIDpXz8HVfOWOxQKttNYkupVJcbYhHNicwLzc3Ox1TaT/trfkmTXT80XXfQA83Ls1VVsYKjHDBT5/bIOx3IzjS0KNl7C5E8BuggSL69t8ogHSOKwH9CugZje3vj0BuzhZsl65k1i/pNS+vYwOifv6BhhbgWS6D2s9+a1Xi5YLGLE/EvMlw82N+o/owUluZ2vhekbYJ0HkuyrL+18l0L5B+8iJS62LzdD+hC93cGxqD9RVQA37yxzpN33l2y6teSrypYU7j2hMVv1l0Y6JU0l5itSdWT3VmWyHzdKLYNFjpA2WY3UgvsWRTJfFYzFEYUu2V6OqY7HzUiuKcVTYwB5Ky2qESzmIFiLRv0E9E+fVoYTKjk8v2gDaNwKWq7AJTabgeNaQVif3lUdZ1oQerb6aRc7PBBBKBD1YE3S8+wJ6C4MIs+XIxuJvjhhbOav5Q+G9Tk251dlt44cWQ61sCPi5pCMAgzcwRH2+ZQOZeYslt6g4XS3TorVlHveIpQkBOPvzO3fUkfUQzKPZ1QXFIBZnTLLIcsV+L/tt5kep9ucrqUjNcREPODf+nM/mQlfLGT8SLU9r2zMFkMm4zXNWswWTsXO7zm1YEErAtyggWff6gM66wz1dnNMiVXMQ=="},"preferences":{"data":"EZMrwxNFFd1sMGycoYE7IrlGGrfLixLUnLZmWMkFysfISe2ay3ueO0PGCApuKqh9hA=="},"oneTimePasswords":{"data":"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"},"version":"0.1"}',
+ statistics: 'SfGy/4mpXQdDOv+Bcfie4Yt/',
+ userDetailsVersion: '0.3',
+ records: {
+ '062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80': {
+ data: '7sgxSQlqR+wh3g06M2+sWp7raQxjjQ9jLIz2OcEB7SckuQcXNrhMlDCbL6ncSljtzgqhioWrOB409kIG8lc7h6ekghOE/Mhi7rVwAiRfNGB7r3mYxpEXRe96O2RG7E+NcSp8ezl+5gJ9D0o1abXPeFQYGcr95hUioCfyY+xrxY8TJVwdb9nHkYvBdKV7rCl1dTxgsKWK3nlo1T7e5uyiz5YUAE6BrCtTFAqtprLI/xOpRti9C+llohS7D6s8hkCBPZfp3chKFDrgpsCBFLhXN8jrBKSjHi1PJdRQzpJsgrxyeBj0dZx3gTsYOXqrYgdIzFUo7K1Tqb30yNprBiDMr7j0YYXiSvEb7OuOIP+HTXGN+yt09bk9LggyY6Fh0e+tenjQQ3soySN/XznOBpEjXbzXoz6fR1MXVnE9GgaX99LVNqwWfq2rIBdSE/FfspRiWP3BY5jIrEkNeRclS05U1zw3K3wxOL+cB9r2IynSXnK8QcrDNNRZ0W3PhsSFfByUXuviLSEOPuJa1mYP29L9Lj/WyHL1Gyl8xLbt2H41S6+wvIleKMuc7teH6wPXbnYphvbwBowoI6HZTEFkz3dQKhhY6VF/81iCXsuaz6BjyrzFX6SkQ4S3lN1tv4opQMJFvnmHb6EkXqVWfeIXzJIJO+owL4vDOf4okpAD+HPjjlVXhq6fvyM5UBIK9+tzJW78X/zifrQOfWRIhwjVsfUdZWmZ/S35vnHWNuXkM8GBYrDysqxanDtah3U8XLAiIhFtBOzpzr6qGaNDOKKgG3K8QXT4bYHOq1rQVUwzQuKhlCyStrRMQrC5Ry251xmLy6dKfppRarVeGDtzB/30BbtFNdZmzMNG2g+Jj5tFCrEtCMvMiQEWZHMU3tGMFxDef/KKdv1fFTJC16jmaUiCHUZmNjB3EO9R6xPVcMlAVKf57n3efrpRk/GTmm9JhAFkuF/wsveH4JjPpDUdkHYFu5tHbb30sbga3ufBAXbQL4ck10S24akU/cKraFGLvuKGaR2U0i6ih911TBSf3pAfZ3RFbBhVIl+6rSknC5+IXoBR7MRstBPW/xC9pQVjN5Qyn0g3aUjUSI+q4jcTuvMl32NtTJbWRMGhfkrpVzypZTyPnIh6XJkyBghlUARXw23MlbjiZxmY4ScDmcWZRZJWIknHlqjDKFDKNnwrfnEI9qWyMDno+jA/DEQz0mnpdZYEsoz1/qAmAeDt89vx',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009',
+ currentVersion: '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3',
+ versions: {
+ '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3': {
+ header: '####',
+ data: 'GCNNIhDQjMJQZGVSf+95fPtU6eOnFWVhuGm86r8WZGVR2Gf2EjbG1OJ0ZIGpZ/AXgirCMpo5AFxJe0Bay8IYg+xmBqMFhwFxzAgJBYCIts+raSaNRipuY8dTEqDxAqD1cChcG8EhSoiFgQ0fG0I7nNEUDJi0pIt4/ygBcwvAhuAenEp9ZW+oQA0+YysPQRqkz3IieFaOoSEbe5/SqpUilV4q1gTVyzNXvrxzxx+rlvEyGFgFN+vgtUZ1NrwlPk4gVksTpylvv6CFaMGEWKhgMG6efo0rJckKosaJTu1pldJdnmMK4EKNMLOd+jZ6pEhEhYyadrA4+zYU5TlmZA6ASzTaps8piSwZodoi9qY0ch2StK4mAbzeEGe2HdfHuAU9Tyq3Ppk3+VfNdKgpQfYrQOiSlXbKzK636tzXTN/gyrfOTHjBrRl117ywibgSX63ayAYNfcLpKotC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ }
+ }
+ },
+ '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d': {
+ data: 'fGzBu1On7e/6rAoSB1a4fq/CkS8Be/T8UP5cQ93asBTWndSYu2lW4DQ4SXQXSindIi3OnNx/f6SNv/extb7OrMLREF92wXI045ipPwy+DIICb+cQNMJ82Sh4cXaIcAWcyrm+MYri3qq9LBKbpwkILcebZidJ86lmKYHJozUezmfbMcwNCljHs/gYkHVzVcuw9L52Ugc6wC7sjsshh+UH6i4/2Frlrophtx+b1vervNd8eoYiKnedHVXVfW7UJcQoF27eHFgzwYnGvRW0KNXFFhqmPb61TSkIvNdCCvBKDP4SXrWvGgzU89wipvWdUPpQ+fCT6Mp3hPRrbJxwMunmjujZOzBld/HkjnXoiNfBb5akA280WvdyzWYATrjV1ZFx8yQY8G0+lRt/MxjKDc38w4y+Rf5WeRbXboJMvFatwooHUggk6qSRmZVvgOmFmNuDRnRYIFzqK3JclhJeVasnqhR6RiGSowc1Ffr1HhcZCMnXpQABGBkZcHD/zw6YjHRyh9Plw7XAm0xb16HMDtiwt7WLJpxLH/HP99j/A2hvMGWiUiFCaYv7AzyEPTmYbN32D1IsAEE/GC3FG0HypGTBolP8wpAfTRdlvWpJz8oRRdwuLV3Pgpu+kXh5sQyeZI6tnuMPQFmRDcMN1oo3E5V5V585nVMnKTFcXhBzD4UnoV+DQNkG/+iSPybQzz/EZmucEqGEYyjI3kl4MAX8UMEUxE4JO0fF8MzyBI13nxknowAceEammx1dGVaJCoIOdhadaPVPyOzXM1Vp1erVm5k4TsxSx1pll+GOm6hVoNHIuQLDueaMEpRxMhfwc8cDyXURqRGPTgTc0bint5xVjo10fnpX1gcdc/AWL6y3tXM80NW+uFJ4GI7VzyzfcMRzTiRaGi19z8MIx8PbIVGh2sw4FhgGujNsPrpuESvUVT+17M0+v8oEoABNlcizTMFs/sA1uqlPumFASltzmViAzClOsDuCh069hFLjdk/Ex5jy4vPYlwOT8Uq9DJC9ZWuZgiI1DrhWN/8QGAEGxxbvnSZPNCQ9kpD5p+iabinLLWOAirVNgKwIRJRyAu/uR9xKd7J9Wxq8q/ii+y5lGilbo2g24wbDwrkXYVhqp/4J0g+p8Wv1NBjCTSCqV39WEizUCRHo3ee9HnQnBJQDOyTBRuz2odTJtJ5tLYjWXZRdFzFSJrEq+Z1z3oq7LnhZy3YWaFXPeKmBCemMthtNt0nL',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ updateDate: 'Mon Oct 27 08:58:49 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:39 CET 2009',
+ currentVersion: '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac',
+ versions: {
+ '0ae362285f103722abbd046eee2b7d10aeae6a1d05cbaf2081392ce9df882bcf': {
+ header: '####',
+ data: 'sG6TUmPSEPFpiJ5YdtghWHmHbvUK63tZCZ+Q5iz2ALas//jN+lZCBhZcjEwPEJskBkK2R0MyAh14wWGh2bBHMjsokgTe+L+x+0c/Zi0epE/IC9gtOBhsTe/hZ2e2xOGF/SbzET3DAAYXvxduZ36f7SvvFnrkkKvpj8wGSdTFcBmzqMb9DL2bRyRCLGLMzE3F1a0q5CufCIRz2TgHm+Uw+kfvvwC7ig/F/5iLW90Ypz3vmEtMEFYFHZ9a8Oh0rsXGfevbMhFqALoywzihQEe/NiB8dwn7GEdYKSQ35rhvZh29ULWOZinqmg0ONe0HYaxx7DbKsVoue57S0CIUlgHLajzHfLfqQg2sFI0OT8TnHsGg0YZ6mM2EdKmEjJiER0cP',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:00:31 CEST 2008',
+ updateDate: 'Fri Oct 17 17:00:31 CEST 2008',
+ accessDate: 'Fri Oct 17 17:00:31 CEST 2008'
+ },
+ '10f45664bbd979a92f37886f1ecc6e52e49798b16dc997aecd37259ad9b2090e': {
+ header: '####',
+ data: 'RdKVaV/WWWchrCse3KtcXd47Bfm6IAwjqVUpaxoed3HeunI42AAm7xYYSjeK8edHpbNRJbhobBAX5OZtWIp/HmgkobKM8CIiWxrWz89FqyrbnPD7+fXdtgF2yTax/0sC1l0ibncdOuJKX6U829oPlXCpXIOjlomc4wEEAD/5V6FbORvdZ9IE/ME3LsG2y02cT2tIpx6+R6wC/PKXhZA2UDsTE6R2Op2BtIzpVORZLXsdyAp/4wvWQxq90i9cEpbsVQsMB10JVyNHNsRTFhIlHi9MVCaMxQvcrwRElMj/Y9x3RbsFzSGKqFLqdg7Fn/U+KYkpYtsgHv9hraPIb9lV5FH16+iItU/HBM6FGezIj1ZkoQ+dgjPfSjTZzgzDYwyb',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ updateDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ accessDate: 'Fri Oct 17 16:54:23 CEST 2008'
+ },
+ '2fa7b67e569d5e268d2b70b3d4d3a960d7e437e1937bcb324b67d0b9441db8ba': {
+ header: '####',
+ data: 'dpnI2qKjk0+bfyKktw4ZCWf+rWZ12hO5bda39CwD29JH7KtdpLCLe2LoLd+KKF2wOdpDsoI2iTiwRgFpt77e7DoWJABxq/0aaRCVN9XpqZo08iHiYhJyNlIszO8CdEhX+M3AeZqzTnd6fs91VfIEWggvku2Z+jwr0CbclY6FnOcNnS+1fj+W79Z9XC383GOm2ujjfo3SX/fyNQSw8aX+7AgJIRGR9uHK7M1cVfsNNTbmDb/HDgLlYZ1Pqm/9poHpmS7G4HUoRM2/WjI0R6F48dy5s8vZRi11SCnlnj5oRykScJj6wh2DltbCyesiaTpAjP6MQjTXsZzKpaosaQcQClZw+w6hDD2cA54IaBIv2j5KAHyhxDh2ERdwbdnCsDKPz4+zP+fmKfW295d4OY0l1NCSdcY+75HWTmBWRAooZeDTo7AE8m5sRwxewE0Y8J2MLUYsrs7Rl4kbZCiRRHU7cs+us3fq2DVn2OLGEbkRrK3kA9swT9W8ABqINoA79+DmDaIr6TGxe5AlHkCAl5sYAN4g42UX1NKhl4fWI1Scj9O1Ixds/1UUvqzavld0mE2cR9yt6LntjE5sQSAaexvymAJbU5IIM5NTk7NlY7G3PEvAPjcUsL9SGw==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:00:13 CEST 2008',
+ updateDate: 'Fri Oct 17 17:00:13 CEST 2008',
+ accessDate: 'Fri Oct 17 17:00:13 CEST 2008'
+ },
+ '5a17723c34226d8cd663f91b11bfa14979e694e461818113ec8abf7194b46b6b': {
+ header: '####',
+ data: 'yRTvhkoY9zDRBwFYf0G5U8zhfS1XWIUfwes6ADNnFyOrHOr7JZvZZHSgkOPnsmN/f5ngcvFaIV9X3TNTmmPLzD/ewgGVMR+ofMLyOIMGhxUDzosSd1+HKqwDZWneZ6xNsci87W8UCfJgoEGrkAtAwktqyS04pcAas74XiRGBWNcv5mHZONwGPckYUnnaVG02Zf+qif6Pp7ugdvXrgncO5oi2AMSoR8GQxMP+tX53YzLwOpabA32PDT6o+aDPwMstJNQjWCXjeYLDIlb0GjL2zgjglX5CfdGw8vNT5hwGEK2D1FkvHkw79m++9sOWd5w9WdGgtS4mrTZP3JHWC1sPqvsIpq6PsrzRrbfCFH7C4X/ya5ciOIZTCNl4dEGAif94zgN74ueY5BF31PNFtaRaQ1waKkbsrU63MrbQbBar9b0hDZoser3BdgDGb1Ecc2GbJM1HbDITttmFDrzy/Ugh2kistHx7Dci8IGgfT7K94TntRFc5R6suEqYRrmOn57YJTZYrwSgbeTqAt/KOE+gL9LawiLJ0IdSC2RQnO3yu/aOEThHxpdLIKiVJoiEQXYVnq2UpnO79GNtplNnUe1hETQ/JT0o5X1bbENyInUsFjPuitAfChXofkAysIhDOHAdifc0Y+pxOHbQLkL65ZOsEDXWSlwMcduMNdQm4LVx26GLIV6yVsaDN+hGta2CxUuSvEIMM6T5xhaPfJ4K57LVw9MbOjRXpmFQz3QgEr8ZZdUxgE+Kj6CtmsjvzXtCQ3Bv/SccTLJSR/LQ8XRdIcPoOlDDy5jSQDF/8lxkgV1V7M3+SI1iWESPT8My5C+RH32F2MNZzthYq5hIFUB3wsM/AaQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:59:31 CEST 2008',
+ updateDate: 'Fri Oct 17 16:59:31 CEST 2008',
+ accessDate: 'Fri Oct 17 16:59:31 CEST 2008'
+ },
+ '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac': {
+ header: '####',
+ data: 'RgIWPbNN3sPkIPBE6lfvf9/EoDFLemTZe0Qh/1wZLrKxLRNzFpUk9+NmeGUp5f1hM3XjXw4cXRvP6GrWq69mz9zGja+1TA6RoW3dFMpSQkbONcrSD1mIjxV2zIvzA/Pangz0ZixbEeHCfwXLvgnevbTXXFjkti3kLHQlk2pJpM3zMl+rMJtcsefszuJ/0tE/bO7sBcFqcYgKAht2OyDQORBAGiW1kI9USKM5OOfJJIZDQ0gDhRgl2U92l3kIOO8hdnj32oRedwfKFmdSRkuMY7ykU0bMuVEVkLi/FWmhHxi66C2ovAztVtMd1IiyoNcHc4UH942GC4pT1A8YQpIHxBAJbrQVhpl9LfFkmJ7xUc6Xs5j0Nv8+z2JGCnJI/D4nDJqYW+iCYtRWu6vUmbg0vGfaYWQFGRZRk8zWfHzHXBvHU8p0QsIjYgCLKiUaU2SRRD2P7JCjeTUrm3I1OI593iPsEH9J2PHCM9OMQ8/Fsdgd7lWgH6P9jLdGUwtb1hGaq8mg3JGrHFXcrVkUEBfeR7xljeSHD7j4YahYrua9EeR8nvq6CNaOr406AWyHse9SXhaOxt8qXRLoELpyQPsaLgafUpsdLjJqHz7J76Rp77NSOtXGplKjAtU1xj+d/agaAKYCjvUJC8/APJI2890Pn7VSXr/TPc5biPEIopyVYEHFqaT4e5nZW1Ku1HXC9gwUwUI9rITG4GzIH1WMEm7oFLNUaSMrdK/UTdTJZ66ENE3B9v9cTUpR0NTkbI+iGKDnc8GHPRlr2ZJwN4KFTxi+o/kkEOBjvRHR55nRh2+dke75LS/fzHQZw5wlyqBv5ZeUZfRA7QHfkj9acR0fJSqqNX25AUzZQnRL3oVpOxFWCMU7QVf5VpnRm9OIOd/5F5EoY7Be4doM/UV9U40F3E6XPZQ8S0GKQzrDjc7jKyGPLNPLUWTmGB39mTNDHZQHh5Xv5Q==',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 08:58:49 CET 2008',
+ updateDate: 'Mon Oct 27 08:58:49 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:39 CET 2009'
+ },
+ 'b57a2d2ffafa8029123362071c09709bb9192f06a17140440f0e41d22143148f': {
+ header: '####',
+ data: 'PQ53T2Vo2D8PoLI1qNX//jLaVZFTDTYk6geT9+4RoThTxvlJ+beDPnQzgYhd9iASaF9GQEEL8JxsBnNpEPa6JPOY4ndFLmDLyFDKXMprxq1UIbzFV6kFoYAk3uCCCa3UCDzdr1KXB2CiiF9HrilaA+xkm8krAvH8I5kZD+j23gByz5cAFvXg7A77KEURpjujURL65DW5M+ceIjo6OXaPW9VO03xhqGt/M47ayObpoEGJZn+X9C8s0SE5wOXHbn38YZlRI480OMvtDAxbEYUeQKMmzu6lO4Nw5hhOUjoPSLr/i3tmDx3nPcDwnSafx6jyA4y31eW6yazqTEOP5I5ArC5mUrF7mAAiFvbHIsMoF8PLj6MONlRIOZgbf9HzCpFdt8xBrX/TXp3LaSAj2XTWgSTFI2cgmU3qqPyibvIfUsB5cVHQCXi692JpC+B85axJ0FLyMl5w3vq0txlPkf6q+dadPYDaLHGZEmDjkWScA1GM5xPJHWFwqGE7ejgXKG0sMYsMKWYk+F2LEUmMHtEvSlpgJBntvcQ1ZjYQxeu4hg5txu1ykkif6fXgkXF6wn6qu+5caeJeNhWtAB4q7WVD47111woYMdkmX7AnDTXSAQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:57:17 CEST 2008',
+ updateDate: 'Fri Oct 17 16:57:17 CEST 2008',
+ accessDate: 'Fri Oct 17 16:57:17 CEST 2008'
+ },
+ 'b713e0a1e2664ac7bfa7ba887329ea023204d10298973e322983b82b222debf6': {
+ header: '####',
+ data: 'H3gIieYrH7Oy8LEWCZpl9vGp9qYdHNCoBNGijYqlcfXt+1JYvPj1abPp12xLNrDUHfaOZklU2Ip4tOf0CDNhgAan7LYyPqFoy9ss2f9/5RLcbjwiIwSduySIL322HTAwqlzlBt/qaJdHHPUrczmu0fb7fT+0dO4gCL/e/IjcHLefUUgNPAbpHG0Nv0+4lNwKZkIQM3tLRtfJyFBIgWKcMcP1XMic33kr24rwybR8Pb0CHZrOOvvUiGqyoED3ZTZf1twUDVNXO7MWCAC5dBc6/Mk/vSmbbGhppXAH02N0g8G5qzZfp3UVikls55VNhRYLHByVsgpkbIrKXyZnBPTwzm7qefpYAXDOgO+164L66/Art2FYGqZQRZLuh5r8oF38',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:58:00 CEST 2008',
+ updateDate: 'Fri Oct 17 16:58:00 CEST 2008',
+ accessDate: 'Fri Oct 17 16:58:00 CEST 2008'
+ },
+ 'c4cea1cd88a86b05f48a99896a37967c3456228283a0406331ca9f67c6f29f97': {
+ header: '####',
+ data: '1znWPwc9JwCe7iOFiUd2iGm4xJd+824B4VRqEtzCQkW46tg25RWfo7XagvK46USB7t6pC8WMLU0M/EC47KucsfpWUqHGbseoXT/8g8E8GoLnIsk9qFyJG7LGd1sUvqBgszLZwjWWG3t9zifmpW5nY9GialBYNmeSLS3bg5xDH+eCEilUUfDe7zGuVSuu/XkHacv/DYUst97e+6u44F7H8Kv8dTywJZpqbmveNPeWfCej2aBXdVV616J5lIRaj2uIYuQYG7blYJh9KZ7yLStdPndl6h65hIJpfWo0PM8nLJuo0lWNHz7misrutnmxJEjkwVIZ5YAmqp1Zz3VC8zw4IxkXrC/sPmp4PaNXgKz9ZJRaY2KV69WmHf7BUQ3QneGngbT0tN526SS5qDFwTGiuIlnYGWvTB2jVrbns68n/d8Fps8sSWfJBvvXJUEkaZB+1WqNilOPGXvyJ5k2O/iucFbRlxwlEHDny+AgsbtXZdp8cHQ4C/O4G0mnUMZuS38gn6e2kQ55mUhxKeORM+J6Rx1y4Iiu9KKNbxyS5eBpAlFB4xS/o35CS4g309vyOEhi37F24bpp4pM0xEPG4mcc/IyChHzaHUGEp1IX1ZO/r3ut9RIN2QWrGLUlZV/9rFKpLLAy6BkY/g8VYNrV8PztOL3rqy/qwqNZouONwPw8w8SA=',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:01:59 CEST 2008',
+ updateDate: 'Fri Oct 17 17:01:59 CEST 2008',
+ accessDate: 'Mon Oct 27 08:57:58 CET 2008'
+ }
+ }
+ },
+ '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:53:11 CET 2007',
+ updateDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:25 CET 2009',
+ currentVersion: '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854',
+ versions: {
+ '106a1116d22c2395906a346da4d830c7afbd2da9a46210d0b7a11de238016783': {
+ header: '####',
+ data: 'jgDUvByveAFnchBQKhiHGYDNDtj/7Aja2RePMer0FCOkkEu5GRAiLkxA3/DD3eiU+g+mCxnjnOaEIYL1O5o0+JP08XapsblZHTRKfveeFfs6sWwuqEHGYULBaXx4XSfK2B12HgpBwa5aD49489AkuyXi7t/aAXcKKJcLB1sC61DI3NsmajUaXHBi31Sp7nKAUpMuiWyguW0JVfH6KUPqyldVDBTBqHAis37c1qoR6aFHFfGgAfb35+syfmPRgemujMRkj2XO6dbt9zAYlHVSYFp9393rwPZoyBfXMMdDtSTmq7H9qbmx31GecHZlFN3NymtPPDYUbQ9mpPVRbxE9NjtiPrI5eGFvb++OdOx75PKjYjCAPWWFZ+4aryNn+h+yqab7pAuoG03ACVVrAFIOn09g1ssol/vqvalulEf3hAIviedyiNAC9D0UDHtzUwyIiELvR9qouXLZ',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:13:41 CEST 2007',
+ updateDate: 'Tue Apr 17 19:13:41 CEST 2007',
+ accessDate: 'Tue Apr 17 19:13:41 CEST 2007'
+ },
+ '111a8a4b6b912b808a93cf5e8785ca223112628d05f0bfc5dfe1eb40cb72ed8a': {
+ header: '####',
+ data: 't524etHmXljCnLC+IM+WPD8Q5VE7wDsSHVNZzFU4hQzk119t/N/vhtfHYz5HgNstU5T8c7h7RHKvFk5f+4ZwgNgDqSH7H2PrH+7/bV8+uuqbe+/3GYOvELjTF7v3xMyYs1B7ruHpT+291HVNZqxajqCl/+9nbG0e5feqNsTXWUTdLzF0szJuCTNr2I+fhxAO0LRVaf8h+MBPYyuBDnfFDuKm899IsgF9YoYRvjaYO69DkElvf4VP2jrXIJsRnGIUfUaIS/wQ54+X4JBZM/9M09MVOw1SVe+cwG+P3xyPUkqnSb77ECo86C0MktzeYFmPnPv2SM2KFA6slctXsyudoaNlReh1k+6no5J5BjaawTfqYjYrAtWSPsuhxYVsZym/X2CVbkz4rMSn+J5Uio9N5uZ6AqgCKdhAJlwzVb3fIIJwvFpVpy/0LMskb7aG2i4eAxwzx1H6rD3Y',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:53:11 CET 2007',
+ updateDate: 'Wed Mar 14 14:53:11 CET 2007',
+ accessDate: 'Wed Mar 14 15:24:35 CET 2007'
+ },
+ '144d6eff3eb5f1cb70c8906741d88018cdeeae3a618ac4066598ad6b04242364': {
+ header: '####',
+ data: 'NPgSZF0eSOzy0/Ns+15Nz4bjSwh4o7fWYgKgwXLRFrF8y3EdbiOH7AiEmmPrCpT1raeYLWCcDIrRTz+/9uvIrz6kK6BjU2emr8YdyLai+PTCRY0SafWS3QiYixX6DJiKIt0SC2F6dfmSHwNsbfTHilFhVXn6wXTJpWvC+sRzw+h42cYpQp0BoLSuFV7vPz/+wtuQdl28BiBgLzGsrtPud0tPcfldGox6Ia/1SrOPcqUr0tnFlNQiUvPU7N0JZgRNyr1PfpAEhmYRI7aEJidsZ36vGQpE0ZQMmQE/9tLS/InALRZT1YXfMsytf0o3y4QlgJrvRgBL7fGiQOZJpU7igLk15xAwU+OLIaYIbr2xlKDJvndHOcrFoYKry9/A/aZSnEYv79wsaf64bBgIVD2WJGLuSFFmzlFnbg/O4kGTin3A8XBpvFA9V6iCMvnEMkrqxD3Qgf7WhxFE1A==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:33:00 CET 2007',
+ updateDate: 'Wed Mar 14 15:33:00 CET 2007',
+ accessDate: 'Tue Apr 17 19:12:56 CEST 2007'
+ },
+ '1f1bdb7a21440ac20c6d913d676aa30dc360252d27059e77df51a1be36b2e263': {
+ header: '####',
+ data: 'TaOHH6IoHPKLLoyLyvsBszgsPPcDs6CiLVXzXuXjFSTrhPxzUw9suSsisgDRRs0ncjZ6BCyqoCxMnw6QVvGN4viUwYVR8AWdCg0NMQZ+LkNfq/2WN0M3KyASI8sIdMCwTb57NzOn9soB1HmmmETZfjr7HpY2cc+lS5/4f5rxI8XTEK60lLed+aEuJamAjeZUdgIyu30mMKKjxPfY3Y9iWMwn1OD0zF0mAW+hyEoMhhK7EYlWKCy+4qN0QM+yNFXQyERb04o2n4XrM+qr9df1GtbQMH8igK5VzXIrKjdHjKoLo9G7D7mfx6mRLsmoAJuE0R8gyzotgdBpOgWasHJ82iWEa1dLRKBHJ1d0Lnumv22tvYfasx2DIR5Tmx3kIQ3hFieLSXq48cYMiaZH/IbLiapIOlMgtWDow8JuySBLei/8FAV8jCxSc1Ui/SjbuK/kCvywaSOhDVIxGw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:26:35 CET 2007',
+ updateDate: 'Wed Mar 14 15:26:35 CET 2007',
+ accessDate: 'Wed Mar 14 15:26:35 CET 2007'
+ },
+ '70720f026f37b571e9765d27c51d3d60c7be0293c3266f1f987c8de9c6b5c416': {
+ header: '####',
+ data: 'NYaYljcgfzrlN1DVgrbyj4AeVhXGjXPho3IQwEKD3ZOx/yEZxldCNSyFsrk7PoRB8Q1T/6VV4CGa4HLRSB7QVCrtVqWyu4KbbmFoX8NIQ0H3xv+TSo3S/b3dldUeyW32ScaGbspaf8nFf0CffsgpGusd+kHdiE3gSLJvH9y5j47KgpyyX4TteVzqgez4dcXIs5tdzJq2eUlknwU4651QeKIuRSmRaDRhhOP4yRgUo/qXMlTJFmHviCh+IumvBdmDoPe3Vc1vZ1r8PxpDJLvDoB8GTDE42NhqHfVrew9ym1xlTD9wswwIEikfOyTq3JM857qPOHRqSqthEvr4WHbm1VW5PReIyse0lugGyOzqtCnADp9NvNI440VjaTd4NBQqF7XrRm56+1u1uTdfYGFV5BRiH1KmrM1sxXQ6PlOF9Lou45ALo20xxvJOLKG0RKLMr8gmVT2bNtOSJw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:30:09 CET 2007',
+ updateDate: 'Wed Mar 14 15:30:09 CET 2007',
+ accessDate: 'Wed Mar 14 15:30:09 CET 2007'
+ },
+ '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854': {
+ header: '####',
+ data: 'xI3WXddQLFtLVzxJaZWQaw8wAgSuXLjLnyoNXnFuLecTH0BzU36PatglVh2HK3LM8aDLzzbHILdlLNnJ9CY+YnhmGh8hswF9oKTgq0Wsesgdc20QhSMNFFjmMljY1LSXmcAYK04Q5mIzi6Pe/04DRdj+e4zbe5QI4vEBhp/ohEpxZnNqc4BoX6J0eVf6LA1pwrKWvxzMxorWsJrrr+mn3svdlF437n+MMr89k5sQJogufes2GZ9tTvVZ4247ITxXqxgAhwXtbuIs/A5UqqnNdsxlHfpLKG5KjxB6F0h7TtFA3gkZCve5UmAibBnoBCFaIVWQyVq+VO9iqDm3DeXsK2pepvgIvpSID8Poy+uwN7T95mivAsHG5p7MtgN9KwQzNW3Iu+BfO9FlPBMngSk8L29So2CIXe6lEsXSGEi5Yrgyo6hZi6IkGCXwIQ7TCEMnlQEGyKnnAVik',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ updateDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:25 CET 2009'
+ },
+ '9588b523f39cdfc14efa1e15ea7716c2d8eac45d8efd7bfeb19d716f9df72d66': {
+ header: '####',
+ data: 'q6DKkxhgDFs1XkqOYf6dvojPF+yhJbniTLFpSOS+I1sum3EZIJfYxJXyi2Jx3KOVNBMILw1+vrSLe/fh5SSWj8ZBoeppkPPLjyRNdiUyd4IfcRM5OSv2YcTxCubKCH2kIMFAzY/29A6ZGPG+AN8/kxkEHc1fxKaNcj2Cs8qejNR8yK1iKT1Ut9VfEee+Eqy2Ohgdq8wL/xAD5mUzdqHeQl8BY16pXGIYncLxMzR+EJ8E5jJTuGv3O41UbO31lvBSfCt2pfz2MrtsuqNoI8LBHJkcR6t17Bj+rHZUniHlyxSW/1rQJ1NnwpPgUJ1fhfQJZM8Faoif+0bvWFY4xWs/tCCD7oEvf0xM0I3FfcJLbYX8M+wyO08t9BmGdEjnr3VUcuS9qKaJRpdpMP7aQf+vJvioeQDXdOJ6Ceo3BDFc6JdNta1Qc+agGzN2KPbIPrLDL+08hWl61yu3GQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:27:35 CET 2007',
+ updateDate: 'Wed Mar 14 15:27:35 CET 2007',
+ accessDate: 'Wed Mar 14 15:27:35 CET 2007'
+ },
+ 'e5b71df0d4d79a195c7ec3288dd7738069837a7c4da3bccc1ebc05d8e4f19d79': {
+ header: '####',
+ data: '1NvK9Y5r0Q880BfB1W5IqdOR77mmqQU0d1GL1XUeQT75R2EgYE9rK1X1jLygCXboPhxzegEe7TDhUsn5XcHN0LkXcLYz8gD/7+He2HiTFxoHd2oQbI3ceBxDJ7+5kWA6Aiqy42QSCuA+TWIQcDVthSyFU7nNdqNxeBYeXiI4jgwcH3xvm0+pBf1OYLtywjUK1JwntP6o68b1LMQJFinDG+sqRcm25ggaZyxDtoLh1IBdSpmXk0papRnyyTGNgsws78dLxnH0Iqxb7FhqYfgLDIvN3i7+IALI0lF0EuTS0hSPlr/1fTz1/6bVt++wI9GpUsrdafUJJMPerXoCK+gAP8EMneLq4f5487HIkwWh1qON6Hvpg+tB95NOSJpqE72VpVxN4+wTQWyDMhfjqXBuQ1wKvTsD/mUsdinU0Wb/YT/zIWBNZPdqur0rjOC+mrOtSdlYSCH89Jj2',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:15:09 CEST 2007',
+ updateDate: 'Tue Apr 17 19:15:09 CEST 2007',
+ accessDate: 'Tue Apr 17 19:17:01 CEST 2007'
+ }
+ }
+ },
+ '36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113': {
+ data: '6fhueIibbxKRA7Mtb9TPcWiUKajnikM3D7PbOROBkE39Vw9E/nG8KrtJlwwPQeOGCFhssO/KX3ymYehCR8rfaEL1f9pfdh5x69mSxKRlOmtEknWqUgPzcb1yPenRbQagERadh0LF4zu91M4WjXK9qynEHoxI/pBhwQb1IsnhwtXl4ELtajudv+2Hv3p75v4XOXFsGQMsHPY+Zw7dkFFA8EXhvuxjiGvnxCUkFwNICFRdHTEovkW3VSerLdrYo5lDgjY6ebr/g7wDGuu4RLfUK4+HpzFwZ0+aOrjpFq2ePg2xObvkkMNNjZ2PcR6Cue0sf+aNqzIHIlFPpY2Hmrob8+bwxocKA6aagBu7z5GiUmZNXGE/Vtr/WWBV2+xIJyzXZPet0MLmSnGiALjPJveeKnnFdDtA929ydcAb8efc0/snfU/uDoXDiO5SWEQ8DDNjj1bSo7VPTtvZyFormE1KjqimqSwaUJzbIS4CxPnoDezaBtQmlG4z8mc8jXq1HfPu7s9PUzcbG30gbF0ch2pDj4h47AhE0ZoeiV+VYZTaYateSifQXKBQKjPcuh9PQyDI0HVua3itbbwxXpRubEM4fbvlcd+7gu+Zq03slYICD07fP0I6XGrRHVTfYpDbEb4GJBvRIeZLwRTQzOeFbPLpBU9Lv3zXxfHfcHy9oK+giIxefPdY1ZR2ZFPKOO0xYJsTr0vmTuXeXzy56bKl+yP2lFst5l9QG8j2JcQEotDV1KQS6mbcLjfIpEnltu5fc2t10Q25Noh+F3kF+LcMIYsDjwanojYlOC93mZl01hmSJdimRTk9otjlRTyC7NWwiyy7fe5IyVi7ACNPZyeUYJUPtKWcPbT73Vtf8W3/+HdhmyYNyMQ9PDCBb9WKMon+qW2+ZVH5yv/KqMHRY1fflAfxpHNhrCkwqcAAGw+G/cetbvQjpkfVT2/u/uLupMsITN2Tgvr/8D2IMm3cyDBUCshrp0AfzARRygHFK4x/0uLfCtQSNjw6zMK8mn80R5aS5bZi5gRS8JBMZ4Q0iG4kBlLpIYtsXSBwl8faljjdl/4XvNNWWrdGJn2k0eM4cESlOFFk4s3Yu0Zspo17nKAHINjHAiP3VlhuKSnk5C9hMU5i3vZO8anQmx9UEwUgQVm22azCjyNtUl6jVPYSNsal7A==',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 18:39:35 CET 2007',
+ updateDate: 'Mon Oct 27 09:16:14 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:35 CET 2009',
+ currentVersion: 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463',
+ versions: {
+ '381201fd3b67549bd6630841e8902be1499f3ff0c3514dd464ad9679f22f3561': {
+ header: '####',
+ data: 'DgjIW4YcJAYnckuEUzBFkfEC841LuanGopPgp+YkyMn3xuzdpGq/ObLFMVQaeAuyErh1B0REHPbq0E/SRUZbeXLXWN720GU4GXvY5bnen2h7pHvl/H4yz+kvyKh3EHJmmBjuz8s0kclFJQB48lter+G93TEmUaFke9c9m0IkKlgzwZ/PQKZyIyfZA09KFaozdSxdFRbswZj2Vq8Df2PQsKLapZWX1wYQ3lXOcyvNdTULy9MCXwPwX6te6hTLWxQOiSPsvB8LItlhQUsSbrJcJEvWPlBupPu5SeI25zDnqKDETPep63Ks2GWf45nXZzYYmQMzL0l2cenYFxlE18TcOd1Ms24TQ/iDKMhi60zZoo13qjVT5AKZ80KNu46t08qbACxjv/LeK2aM5TNycTFixGskPywpnb6MCo8ibRe5rs1WcTJRMD04sNoiuriivO2fiyo4rxjfdyfueMlOz+Zeztk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:39:55 CET 2007',
+ updateDate: 'Wed Mar 14 18:39:55 CET 2007',
+ accessDate: 'Mon Oct 27 09:07:56 CET 2008'
+ },
+ '99dc86ebeb20a3db0c5393d6d94bc1150187b04316a876970dbbcf517b55d6f2': {
+ header: '####',
+ data: 'AJwqCWNKC9z8DC4TUI0hWnqHvQ40Y/x+jXylnVAkyO2QYQcqg51odLFSfgP0GiGEGPYwDc+kUxRrfO+ITgTNm+hHi2iIWkP/ljAC+AQ56MAEKsU/USTbvl6ShZ0XTAdRpwI/oqqOhYThVs6jTm/J8+lx4tWoMtNj835py88c/9eW26pLQubr7VysLSWuIMi+iDp7zXZZz/0gxGKDe5xNq4MGIYw8/OK1iJCOsjBdrRygLlS/Mz9sRlKkwdrDsohtRG0F/NdsIoaU4FttGs/rY91SCedvHy6ovh0zXhxOO44O6MiMbP085D1jCjWJn9S1RBxjxc368MGfMJeZja87nuvgSnLS2tGDL6zFtVJMNcH/7GqQPXZv/sNEykDNWpypchCnwYUJxvBVb45FcUzagPm+SSiekWK1hrEntZkZuEhQZp7Ud9RcENpa5h7wXUJSV1vPl8xBylx9HWmxez7D9OYRqbOlCRAEDqup4ahNhYB9',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 09:09:11 CET 2008',
+ updateDate: 'Mon Oct 27 09:09:11 CET 2008',
+ accessDate: 'Mon Oct 27 09:15:58 CET 2008'
+ },
+ '9fbfcd3e7fe30d549a813f0e6c1be58ed45c3ae7305d7367bffefa097b424ee6': {
+ header: '####',
+ data: 'nZ+Lc5LWWLxnPvUrRrHhxG35PHq7GMbVENHfV1oS0Qw7/63NecssNoEbiOwFVMjAshvfUK7IjnzyvfQhNtFRbj2yzHOTWCd0eJ0O0MmvGzjpUntSDu9/G8RFeEu9jDKugwi/NhOa5legjT9pcsEAqR4s4NN/Ac6juQb6D/Z6Wd6wO0JQhT5/QPk1KllDpDeo2i/GPUKvEi/dXpik0KQcVLVylU82rf6hwEgvRQi+j0O5hnFW1E4ttxClrnPBEBv60jkNwcIpD0r+rvomDe8+398xUuB4DVDJoM+WUYfu6Sm3qI0yBfET+tJvjn8WsHhKTgZpOc2BXC7EdF99nNEg6kV5pSxV6AUA1XUz5kW+YfcSzAXzUH74OqroC0SucHe4+BtRKnbJy4h5vRfjTD+FJaj1Va02cxSR55tQhxm/k67z0QeyB98dnU1l/pPHwBlIWa1eR74gswNSeQ2jrzu5JeQ=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:39:35 CET 2007',
+ updateDate: 'Wed Mar 14 18:39:35 CET 2007',
+ accessDate: 'Wed Mar 14 18:39:35 CET 2007'
+ },
+ 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463': {
+ header: '####',
+ data: 'm3yhZu81UAjCY6U2Knrgg8mK+LX35Y/iZgIEm8MuRDAlg6UUz9Z1Anu63COFV08YyYQRuBzTgR9YQ8wrUD1S9FG2ZmtCDemqvd+5OUMgdn4sK7G3CuzAc5osOa5neU2m4y19WuobkGnhO78ko7pVVjO42q0DeMT92uFL6KE/2UCkWlq5SdFyS5qXEJEWs2IO5C8nVpdlO/eZ36Pl2+v+afl3QQMTthCVIUR4/zVP2ajbO48yjDXhYxzskFjtXMYLApEn0wO0dcifcsYhPkozz6Locrt/R6IZXnfZfuW5XXHbqhutoJFPK6L6t0Ib3B2r1TNkPaMsVs2g5V1g3ENRd0IlbG/uBk2o5tgeu6gOYlA1scEiL+/ad9ZxiqYB2ENCGZ8DXA4VNMnzxVPbO96OIUCb9suV0fldGOg=',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 09:16:14 CET 2008',
+ updateDate: 'Mon Oct 27 09:16:14 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:35 CET 2009'
+ }
+ }
+ },
+ '507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a': {
+ data: 'ncSFmp/+n1pYUKi2fwhMCevSwFYO5irdcpOlSxC6YPOKYavK4iUbtBsilYWd0hpvUHW2ItaDwiyNFxs2Lwegex6dawKrpMYkPBcaZQDa746yACGgCkhz4MAGnUn5HCmz6xhpCVXMMKe3w2nEOjRB+pOMOeJt2n7aw0hCJ9tQ9JTFNrZOxeXrqoexrd210Rmr9FnKhLIvhNTN1/vXRqP0ys10omJ2mowzF4KoEVmz3ET6pS2d7tGjt9M/OYsH/ETWWc92doF5PO84g5/3HePaCo8NCqq4ul7AWJEbdnkxxmd7urJzIscPQPcoLxL7GfG5LhHTFyHlfFz9dNlccfA+OPftjyfjXTjLYZzbxxbi/nAB9Esqj5AoHfqaJM1ZOrZ+qAvm8Am3+HAXrqtiybDITrCLmGH9ukWDsx7R3lYTlvjArwORBUH+4w4/uYGscVm9kOYj/Rmz/ZMH9JibYFcPcOnr3rWXPFUL/XsXTrm9lzOvPyEYJmkENzd54AHC4Lr5vHpeuipWFLiJOrtn2WcgDG/DdLaYGKsmISXj74XDtP6Ee5lKOtbwwcmVNrl11UCQBEFHNybhXvpil5laKddOauLJDKtaDL/mKYPbr5YSk7HPCzRyE7HM2dC1MpBHuJ8g+hDkgU3wQcxYduKLRpuC0uOqrODigGWhVrdiKdZanlWUq9EkE3eH+E2A/CA8mHl7UNaH89XSvgV7uZyOmK7iZ+1kd9OzhBLQdJnK9qqP467Y14KsTt1E1+tqlqVAuK79QMnllaR0e3ztBRAQsyf5SD0KuSGXWz+z9/RjbhamW1s0UFRGh3voQMypU5RcYfYUA5KVg0BiVKFaiZBZKLo213hKbrgE2KoqVDEmIBFmwsu/S3EDzUY22tTB+o8ZKQiYesAUafGtnvsOLa+h6weF1ZvQVBerbD3fhb2o+d4ZyPkoRAsop+5it0QxsWuZL+J2oWybaikxIP/1ZM2ow4QZLaAVqihyHxqhF5UxZ9zrWxfp34BIPzzU9esSifrD0gXZ3mwutaCukZoijnGODJZtFOy9Rl1gyS1IbpyRbwz5O/YRl4BsD2aOk4InajT13Sa1BLPblQcrau13aeg/IzQhcUJ6n7enkrqiJFTP8N1aFAuYv8ilu0V2ymIuCLUtc4cbo7KyA+gnHhZA+DjjrhG/izOyWtQY/WtDsqvo/6ILwFk37JDjHfkchPEVcdl9qT7goG/4zTGX+lx8UTKKZJjJhLjA',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:01:24 CET 2007',
+ updateDate: 'Wed Mar 14 16:01:24 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:11 CET 2009',
+ currentVersion: '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b',
+ versions: {
+ '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b': {
+ header: '####',
+ data: 'sgq3FGcsnlbhTLetMa3TQQE6uFZv/JL6Awha1066IimKoAtQGbAr6E1+mxRmvJle91sL7oRfi6suvDanYHfAI+rrG6qCOtESn70ssS+aGFyO3XwFgypzG/Qa34bjxJ16Aqd93H8IdhzdtOxs2Qmou3CjyxbT7Cq+YW/fAo1WfctL4yE4GBNPWC5lfebxSmINlBY+zTjhv9Pf2aK6vL4p3obHl+zhz0YdKAMBwbDyCLa9tYvhGBnq/W6lFUsyZCPVJJP3bQCQww0TNCcLJLm+SYVSiC0NwCQJq+yNqDkWTvv41p5EDB06eOQ2VqC7l4i/JLE/ql9h9Z++gck74/Qs3ppdVdG7sTzWyPya4v3RW2OTc1awFRZipAX5Zd7I97dyw6Yym4y+/9UT8z8iMDYykQ4+QnOhksDIE9a8q6agDF/rbZ/BCRcMWbFylGTdudk26mu0GdPiuLDu',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:01:24 CET 2007',
+ updateDate: 'Wed Mar 14 16:01:24 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:11 CET 2009'
+ }
+ }
+ },
+ '5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4': {
+ data: 'Xs+z3VzIqsWa7dGBqepwq75lTsx3yemNhTdRYYDDc3Kzpycyp961SgnKXHjE51266mfmj85ASFi/FKCOwk17lbD5UT3iawtc3TdgrQ18vBhBsmOA2F4JAa4yC58bTaXbyld3c4izDp7i9+iyRaFN52NWJznN82SXuRtPdWRtAxXB1V5Tyg==',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:45:25 CET 2009',
+ updateDate: 'Mon Jan 05 17:45:25 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:21 CET 2009',
+ currentVersion: '00b3a4cd7400cfc1e7f7b369bdc3dcdaa50d6020233e131b30d755c89249ea9d',
+ versions: {
+ '00b3a4cd7400cfc1e7f7b369bdc3dcdaa50d6020233e131b30d755c89249ea9d': {
+ header: '####',
+ data: 'uGAV9pZTjrTwBy24TX/OUQwGmgzTnXv1JBIxdGkeoLCUhP9tAjbpUVylrUI5+VRrFYkXYyZ0o2HEgKrun2f3PODTxlmAbfkUldOV5tyV/EUxN0vYSBtgsMpqQm3bOKRIAo/uzrhSE3iwMjvKOTH2jUrkmX6hmqhXWZfa4X231GovrnOjek8c7t+LUBmmIjXEr2GSc/UbBoFnni+Q7ZArwtU68xoeCjLame1e8Y9wvCO8gIfAzXQAHsDgzn1MVeiWIqiCBTs8YKCO1yaxZpkzXV0yWzX+bHyXlKWwAk7Fu9w0CuaRULZmRCQhv+MMDw8DEXciTm0R5dRiVmSCFBy8cL9qlSeSX0GlnKl8E4/TSqvhMJblwJJsgmGSZ9cEt2u0E08tHxKuoeaaT1rpAOoiqx+z7BdhqjWOQZOGM4gR3EwqvOQoNYFUaXjAdmiUzW+e+TgE1IBQ8udRFl/D2zCcqFO90Hgc7hHsTDI3aGYvi6bHADu8hFpmZtJAjOMv1JgCX4Hm4n+SsbHd0DIfkEUMeGlVO47lcGWBZNRRm7xl8luZ4sZn',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:45:25 CET 2009',
+ updateDate: 'Mon Jan 05 17:45:25 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:21 CET 2009'
+ }
+ }
+ },
+ '6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728': {
+ data: '3oUg1TD+Lu4ou06j/MddOTXDqRM+qSKD+6Iuzia1Hop1w7v/BXidqeoKJZQI2VY9oO9B70Nr3B3wDROF+ycy6Rq+FM/xqUGHKXn1lAaSc6Wgj6TLQ6eRF6YZKSPqTj7TDWyw/2pEWk4HjcT8drTrCaC02tzAXMhYWlYPQPW4fUdq4hawoHIdopUN3vafQuFjY47OhqXKav3bNao=',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ updateDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:33 CET 2009',
+ currentVersion: 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc',
+ versions: {
+ 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc': {
+ header: '####',
+ data: 'fehYRMkg/wFj2t/aWu7szbXwrCyCDpjQN4UNck4/OiDlth70a2ve6ow5lAi2jgdlV9WiFrPejfa8dD0Z1g19jx+BBsuUYnBEKD0K+NapdJBBeI0We2nj9nYIij2dfZVx7cuvhy8sN6+DdylUQLsFHbga+Gi5hWcMuULT4GOAIy2WanSQL1RSR4ruA6zm/t+VVboEkkm7PPT+w3LuRl3wRaD4a8ZwYiSV/SzgWooFrh2S3YOUeshdaGCiYpTbXscsOxsCxc11i6wQGBqYSjksmtZDvEegdQdzCmxvq4jaVWJElYYS3av612nD5K/w7Zei6RccBiODBPATjrIczYg7HwmQxIM/6QI9/LQn0LP0yqRVUUtfzaODf0uWNpFzml9l/1lwXuBJyQFBp7H7Th46ekw9yEuPD00oZ+eXvKwbwfUU0JshT4hnEBtIjM8fH974PU0y95f0yLAJ1+M6DVXCxGsBix2aKJx9fuZP4KGpaXg6qCb/6327rph7MGomcrGPIiDjYwD/NTMdGluc55OZfGXtOZUaJCUM6nihqDwU7Ly1ZzYorgcvkX/t/0RNcOkFzGYNByp7mdcotyiHqCDKspqz9mEXAd7Noz3HO5GFpPqbRo7htDigGU1f7dvgbbfRoTz17Bt9Mw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ updateDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:33 CET 2009'
+ }
+ }
+ },
+ '6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a': {
+ data: 'b2mcYUi59l434kGl7ij6dBu3063UL1dToMIu3Zsa9RV9RzeLKnezJhLKunqoAm7KwiJeqDo/REexHI1cshGYtHasVXXuyJfMx1grH7yhoWnkSRF4Sax6w5E5wnGkEpGJHOxXJ9rOjWHZ7yqCUUCB/dqLw4FwPOtRb/ynkBEYztEJA6EKGJuz0vrrTOsT8HMXtj/w6MEZ7qI3fPs=',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ updateDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:08 CET 2009',
+ currentVersion: '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3',
+ versions: {
+ '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3': {
+ header: '####',
+ data: 'pZEWSdYIkrX8/r6OYmO0GEuKG9baUgn40Bmw7hXZBd/kfWuRjWsL4/pc5F5Ojrx+N0dxmQn5ZqKAzOOri29Rm4ruxnCbyK+oDsCDyMSnWy/VJcvystnDKzKmBRQVAOSEJtzEb3OtGzvqm0PQ1Dhx1YUAx7L6KlXysmG9h9+MjOcErRL9/1x1LZ33ytR+zK4LvTAb7gN5/9QgwysFyCkNP8bG4nyCzPMiUrBnP0odMTUvDkJDlY0Oia6VjGW6oNxnGIgA5fDraRrW4JH2oejQcrL7+X+jpCp05g==',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ updateDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:08 CET 2009'
+ }
+ }
+ },
+ '6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18': {
+ data: 'jzjPgxRHApIJA/6hiY4XCtb5+eKzHlOeoiGwfVDvip95zU7ThHbdmxOUomeyCOZ3S1SGPT4lHvqZgfVG5m5RvH3JaAIa8EY1ZElRohoX3rETVPJzI/Ov5Rp3lZjtWlu5meNrcJz811HBHrtBuJxAmSjYcY3CCal+oC2zcK2fLZR/iOQ+69ONVFhdV9KiOqzNf8IisIa1sIgFopqsdHXiZ9oLe0a7Y56q+OplyU3A+TmxKLI+Qq+WkjvdMzZDDqzYH47me5niugYPdkQwN6WQUE0sK9QPs0uU4TOwqCwN9nPH/DoQ6oXWAu2+R4iCyt6ZjLNkClbps4s8Cwz6wfFQ+4T8bcldjveJenmrYwiUzxSd/4xa34yFVXVw2OD0n8yZhtvNFvfoPy+X9z+Y4f5HlM0qzL9zYya4KwWjFQzhOxFjni9JyGM2PJ1BctB+q1J+CHuhlVjUF0Y5zIS3zFTET8jjDGBZDWB+Ao9E8fUD+0OJJUdKJ4kUfn4ZUZUG20eLBjmJqWBGYZX7UFaPv8ksahoK26Ol6FnBE4KpPStQeDgXZDzGsiLlEsxHJLUFkNtAUXozw38bWWQvi2VIFtkw/ZViPIenmSNT14kUVWdrlKQC8x0+wECeh5ffv0i8UUw3v8QC2ZE7GV0OMl4ySlRCuDCfZ53YFoB3HIR1hSZMhHlHJDPUz8JOuXdHcUQaJeNrfWoC2KkKb0ZecBj9iXooDh9yGi0g7TS7eyhlz1LHpzEWB0CPsZqhNGMxmfFWur7v2hrYzoHQOeB19ZSmWzfUwd4dRpqMp0x1lZaF97jr+yyYhnuQvuO6lru15Pg6FqjzhsNiLtaqtyoaMiHZ9veZs04qZZ9Fn3U7HeJzjZSAssdLnvopXi363cXm9JqoClyV2OemnVoRwOZN2gdSZxGeOefKR7U+lrBAbJwViMnmT0Nd7AC8C1k34iEt8HJmpztXeOgX5CQpwUPENMCUPsookFbIh7e4aByllEQy0gBbxUz8JMIWYyw98hdASnZ4s8bQfSmiMM8Iw3YxCexKB62LYYJn1UY51NSnwCtwRep+NhaKDk2d6SLh9owxnFbjhw22RriPd5f1InJycjtpvMzWLavl/hDsjjj1kWpnCUBTM46LbERmjz+s4x7fSf2FhhguBT36elz69ivXoiXI+7p0E8f8HsSwm8sgN/AA5m1svsXsdWeZFUiWtAwLg0tI8YNHlazbvFCXfIC6Uhq9eDv04iqdZ3rn2c1rwSx336A7ySTBFdxOCJ46F7ShIhNKm2N+5Qf0K5B2L882fbwqiLsa64+X9aKvufKTsd11vyf19Zivg/Ze0FWoGC8D63Nh91k6Hu32RT+uAtJIjQIZxu9yXJM9lMaRA8ieER+ghrLHaGQqF9J3WmueER3UzU1midvTynOV6g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:09:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:09:05 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:15 CET 2009',
+ currentVersion: 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5',
+ versions: {
+ 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5': {
+ header: '####',
+ data: 'BbXNAy0GcKKyDPiwhP1Jk9mIi3uXMHQdhuxpDvoR2C3YITOUBpurxGhhvmCg+a9pS+fKJdZPxL2mPbJj6GfWTEsm7K/ECEjrVkSTHi6PTUUgYVbCumq9EHjUspos+7VrifZry3c73+qAvIKamvUlNB86TchMpOXVJIyx8UgRX+bdhrxk9ZCEVOiLCG1zGPX8IzmcxPmBRZFlHYqE4ibhl/CLEzWXZBYCofTusClhOh7YM/jBgvDt64W7aIN2y2KiKwmFySkFZdnOvbAb34tXVimwqjqWPvPwd6MujQeX1bmaDD7Y0kXac8CJxqasIezLo2WqzLUbEXdIHGilkaPT2ZKpKhKkpHJHFrV2lVuQJVqwPUr0Gf9qMKgVnsyU8kUfq9ox+fhH70+v7BQSjT7bxxDLs0UesQeL7G4SqvNet5hPI4GQEpOY8p5MUFReIBTRm72NQEU=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:09:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:09:05 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:15 CET 2009'
+ }
+ }
+ },
+ '7bb69b6366a8012f181c01e368ba18d4f7a82bcabb4959189736ad124c4bbfbb': {
+ data: 'wYPZIt0UHiNVefNwtGc7z7Lu3YoQrXdfKmWqilZp8yeIrNfSLB9p60DLMrL3GDq/CsvDYkGAZgj1C/6NVnzVsXsJKq7NDZn1UPOGt+hCnw3lEVbD7zHkoMM4VgFDn1sZdjLe8wdpIFfdlQESTipT3GVXv3swG2qX2O2yuwtlopR8yZQTLg==',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:44:30 CET 2009',
+ updateDate: 'Mon Jan 05 17:44:30 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:18 CET 2009',
+ currentVersion: '23f5fb503e54c0cafe3d4944ddaf40bc74fab8b5d96e2bbddf693b1afb225e5b',
+ versions: {
+ '23f5fb503e54c0cafe3d4944ddaf40bc74fab8b5d96e2bbddf693b1afb225e5b': {
+ header: '####',
+ data: 'IpYj+7t3DhSVD8r9PkLbF5xpGrHhg8omY014P1vkT2KkGDEUj+ekQAbQ1g66Z7oNhRDpjS1/dcDjzH0IIQLjGuQ0oRfL0xZefVTx3N88ZLE39m3cJz10K2xyg3xp06jFBmdNJuCkgRhMzeUXeEJujw4lS2kv7cO04Uh2Maui6jDR7E498rgePY3L32vG1S66li/xU1vPjNn06aFTqSYxUL17/mlJNbgp3XWjGC+l0dXLLfXy1wOm+/I3zp2caTs+a2zDUZ15s+3XeaAWpBH7QCaQsvsQmoBqPbMvkjOQwW3taDvV7Hvkh+qTjCEcLjRFwhZkMNn3N2ewcLWQa2aVIjxt6Z0F4s/1URztWlKVzCfto8RmrLajYRn3ggG12kX2xDJFjNPNfs/7A3tMn+FqXQCCNG5GI06JZ32aQfpnjtmXScUuEs8UeFgsNeYclQhcm5R0sUwISK+D345B8859w+4+9OTY38NgYQQ9o/tmpCjWj1tLYLx/m/GcR2em7iyDpBdcnWUb+tK6Ah89qvXriHwPLSNzhOH2wxmi7nXTRQWMv7g2',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:44:30 CET 2009',
+ updateDate: 'Mon Jan 05 17:44:30 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:18 CET 2009'
+ }
+ }
+ },
+ '8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39': {
+ data: 'pOMTY3PnUAbwMLDEYNJCMzp4iIA42YWr6gqoomg+P40e7LFUtbt/RQRelQwNIztyUSVLl0rilkZZkBUVvxrtTqvibKITCjJQGQIzvcb+Yl4mNosl2Rpp0xxMU03f1+G7eGbuCc5hJXYVAglhEYplaAPzHbRWXMY8iZXZPBuLVf5PN+rdpgAfkGeZ7Uf9RsQ9p/EglrWXYnTwXi3saUfzIjfvSHm5C+dXTY3FHpIc1YkjFrdVgMkhYQGV60JtZcwFtCEL2NpVljAbRgHoIXTOkzUvep4vxrtfBBWWMuAWEI06432gtnH6IQbrR6jOpwuMt7k/09qy/fARPHs3r4qTJ9r2uqWHJ7tjJw+IChQPC+3l5HcPpFURiw8LGAN1NyY1hUrF6N84RSn7AKS0bLa5qN++5lcjjxn/k8+JqmeUqN1/SYIbGwNnJeZ0vA8yvOxnD20iVADX5kOVqJDwXRPLaF6Oz9KkbOrmANCh+PmGw1i6PduB+FgAU4HViYCw5IGOUZ30Pm1NJofqfbhXvgzn7ey2+kUIAwDyOUpJ9fW+9jW/JU4rcawmzwBYN2V8apOoyc3wQJICm2984wIfVBpygCOZM0QDyVgNo57qKtYH3yMDQSkKvpEUmuhklMYhcV+4X5ggdqx7lYXO9IMDnFf2ZDiZyieTlOlRv/nNVecUB177Xpnq2e+X/ik2rCQWVrIymiV6ltr1DEv0krXKfvXGG/FMZHUmo3m+B5bG4xVhmt0GnHseqvY2Vrl9NksLgq3hTDOGSGIy5Nv8kfrd8B4/6Tavh0SumiyXnrTXyYXzCK9E7IqO/0KAln63VkcHsbOtS8mj1drN0YQ2KKaeIW+Yr3Gm0pbcODsgA6aFfz1itZVeovBqUklhXS+/Es8J8xOSvvSyD/TmlFjuErHa+wwNQvftosfwk9ZTt0eIJS5aLHdU2QsCjdfSy0DEPkk2siGhBX5ZhRzqyIAyXApSmy+e7PIqn/dDR51+D1ZHwoTQyTrd+F08jBWZgU/OvS8MRxNZSxQwsi7bcWZG+w0utrIDB8eSOMVBXI5XBeJb4h5Bzut18C1shGHeGkSJp04=',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:10:17 CEST 2007',
+ updateDate: 'Tue May 01 01:13:27 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:02 CET 2009',
+ currentVersion: 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8',
+ versions: {
+ '8a032b53f7356e2d8b28665211abbe2cf1c79fd8eee4752e83cebdced1c19911': {
+ header: '####',
+ data: 'OXpNHHSkdsaD91hw2LER+9XKpf8+bh/O+OcLSgG/gAx228UpifOCD4HTAOs0C7IJ5zhAq1L9NjCGb1QWWTFErYEtDEBRBV4kogscP9HWPxYyZHxjwPI0wE7Ri2eD4Rma76Utb+xVnXWuT+vNb8eRUCK8Ur1rlhYafS0uzAYvVqHDNfZaICksxeVQojil/kSPZDMu8ASz5pMNFNCF4SlwDKPRrJJDbNZ62A3px59YJtsla91DGVyOLhb7VNRxEwnXyxENfP78yA6OjvQDc2KhKFUpHbZws54IolLK1I1mY/Z8BiDXPSnOa694Q1eZxy1Kx/jLINZUIPgGg1++YWITx213awOISdf7Oy0/dUpu10Vr1hgAqCVlDp0IuGK01CswRzEdLVpUk1DaGHuin1rryZx9vThUkEJgQQc3ivr8',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:10:17 CEST 2007',
+ updateDate: 'Tue May 01 01:10:17 CEST 2007',
+ accessDate: 'Tue May 01 01:10:17 CEST 2007'
+ },
+ 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8': {
+ header: '####',
+ data: 'tvSUu+NPKHkwt/ZLXdLGdDm4jSxTEtJfsecdpjJ9UGN3Y2EBCmijU5i7q+hMfNDqBJ4/m5Ayju4zYDAKGp2pt8l1TFoDurITdFcV12jL8j3dc4TTD//uC6OtowRN+altgC1Xc0LsSvEPabjAlwfVC5xqirfm5t2mVmnFZ/GALkGLGxRJRduylT6goPwfunkVGwUdqMa3md+9mwYn2gm7CyC0lpcKX8AZ3B4Oa656yRa9m3Wjgb007TtorLIpZO2MzVwxcHBqqy7YpN+zpmZz6Md9VK3L4F724tuXXWnDeVzGxBO7aZVr62hwPMXM6ibCjUScsaS4f0chivA/tBJoyx7OqKhBxREGeGjpHTeLxyHcekbwXhXyeqxBuwG93yGKutUhGLVYcXwe8/+xSeaBGj/j2RWutKbNKG2yQyNPGj2cxJWsR4YfOQJTSOSWT3K6Mmf+r6hLhIo=',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:13:27 CEST 2007',
+ updateDate: 'Tue May 01 01:13:27 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:02 CET 2009'
+ }
+ }
+ },
+ '9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291': {
+ data: 'xXZUJjgxn62OqnzAvScHJNo4WjYEFp1vQ4ueBe1sk8dH4pXZUKV6m9c1d2cLUgBj4rUNP5cC66GiFHV7G5BDZGLrfrxUlYU6BWvzAz4eG463pRDhHXQgPrhlIGDlK6ovaIsjwaifvHaEfLREoXvLFluqu406KG58guhtWdIFK0rLypyRo8uyltGbTz8wZdu8atY/JYQnb8NaAf4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 16:29:06 CET 2007',
+ updateDate: 'Wed Mar 21 16:29:06 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:01 CET 2009',
+ currentVersion: '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7',
+ versions: {
+ '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7': {
+ header: '####',
+ data: '7wg/yWfSasUjJKV/5ygFfteazVSdqEJ8xGAqtS7m/W2q3rOR+2fr99Il2TzxXCnOe5zV+iir2tOqPQt6BCGbVf0NVwZtvfO/lvfMc7DIwyWuhZ0sS44LBTD9VY9fruuIegktVHSNBoJTCIfAHN/ut1iB80+51An+TdpYT3SGAVM4RdenQ9IdvDOnQo2KE0E7BzHekga800VJrbqI8aJEtmm5mOjte2xHYSPFDCtwURQclwxbNv32hAY/IUkaejqg93WGIzHIIK0+SSDzQwHYQo4yzVGCKKy75eghpvGyg1zbzlv372bND+OuA3laocARFfe4rRd5I5nh8vmSJ+vybh3EIJJzloD+qWk6hsEagkYI0RYu9I2uOfA8drmZ02GV5/ySDsBHX7uhaTPGx4J22rNJoj8s1L7UoaohUHFvUerBvQTir2LPbzqT+B07wZOU0ibtHlaN5C2XMKRxfvGATeR+2J3l7WisCIoRdpQcPFHA7nlTTShBiCVstLxolvd7MMzPOilsi3ecxXLQSeWara4JILqXQCJ4yLbQCMnSpIrZ3TXbwbPZ8fjKjogHNUaBPnmd1hWoc7IVvK9RSFBEdCh9U/hbyPMCiSjdsUCTclmhFmhiVIlB73IyWixmLwHSWSl/ckMxcUK6rB0IPuWcT8iJkxfqOziFhMvC/cNydpN5Nj4WX21c/1M7lVlX10FRx6NIYH5szEXULmLnkfEwr35G9mKJwR2pgZ272UiW2cH64/+M+Kh7XnPbQKxTwVR3FOhR/qdSHeA8MTc9FDslFaTT6YSeJEPoQiLg4c4UdbB7w5nA0o4qg82hiiJbTfT2zFHZeeWOpVO1z4V8SidJrQkh8aL1/Is7KaDVNfL+Lx73gfO6tdSviCJJhD29iTgn+MW4MlGwpeLKpvq+LkXNXi/CVjIa1VqtR/Flk2BqwT2hccgw6E1ML+QdW1n3TvTtdLIvSGheOM5kLdnF76e8Nj0kHDFbnxQMlO7lutngaNBRAvhvSLccT76TMG4OTxNZk5aOre6AIOuUfrFD3KDeOqWie5zpkvTOd/JK/JDFYgbYQh8AqhwJ7VWUH49vfd6AqfwHwdNWymI05F6/0Co4xoQ6qN+iYNConUXz78Uo7AraJuBDQ3a24+wL2mLjnc8jUDFUaAKM6gZUv9+bx1vk6zVdaZcuqgZc6dcyo5Oy8lmbJ/SmRb8BF/Q2nW3SDv77R+p0bKPLmjcytczlMNct58Q1LoiLnGck5v0wByQ0XIMd',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 16:29:06 CET 2007',
+ updateDate: 'Wed Mar 21 16:29:06 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:01 CET 2009'
+ }
+ }
+ },
+ 'c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065': {
+ data: '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',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:45:43 CET 2009',
+ updateDate: 'Thu Feb 12 12:54:37 CET 2009',
+ accessDate: 'Thu Feb 12 12:54:37 CET 2009',
+ currentVersion: '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a',
+ versions: {
+ '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a': {
+ header: '####',
+ data: '/mnLRePyLGwPaZ+EkbTRHdE4jz4gY99jnHcIp7AeMfcktEpPmUVNWLwGSJUH3ANP/cO1znxACVQPzC+g8IVIK0muJ/lZ4Iw+HkpsfPtBjPZc+bfhsY5Mud00YBsImleIMlbbJGv3l79eSPcea49OwG30xro6b6I0KK3BmSgr+BG2AmBrKVlFRTPFCHRbO+hG/LgW/xqYgwd9f1dnbeVYCm5lA2zdAnwmMwlUIi/J73MbnsSO0Qg858iF1SPQ2Ne9Q8SCyKKEZwBY/YeSgDzoO76Wvqbzk8uPdmZldaF4zql3ffBeb9ZS9KIyyk2vJcLk7c3DUc65vaT+w25+2GSpEXD4YIV6VSr6Brz4w4gzcDMeLve0U6oruqWijz3CDe40yhd4mMt6wTVs4xo0KHc6yKjTuC1ZUQwZvuCiS8T5czaGpc0+fLyfuE+pVBxTlpOjkoZqzk6NsH5lcKMzB1TCscJ8fbOdtJso7DRUvijIE5+ayY9IktZhMeHsk2zurKV95A==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:54:37 CET 2009',
+ updateDate: 'Thu Feb 12 12:54:37 CET 2009',
+ accessDate: 'Thu Feb 12 12:54:37 CET 2009'
+ },
+ '4ebfe3bec6d419d61eb68a1f25407824e404e3439c23fccde1ac19225b40cb06': {
+ header: '####',
+ data: '6VvjRN9LKi7tt/HsgqmU0bUdZQNVjVAYNLdCrfKdRJCx3W/GZHHR/AQF0FcvuXIn0MWMUypHpTZW86V459OEoV4W18HXEisQKEiqBnUCBaxBd1NKZDpYsThISXXOhZSbXylbLoB+kBaYzT+Fc7utDheVvVPeMo+iEb3ih42B3En3ZXcgUAdEjfbRUm6st9Jiaz4onwXWknVhkF5QewA0GXDhT2JdakFxfUDay75wKvspq5IszbEYwsu+TEgsbuO4/R/bktgsQUrbhtKIEIiNSccDNx1JkUKvIxrRfp1m0Ar3XJsDfv7YSJSLdyVheOEdIpBkeZ40LN83uzGRMZw1bQsKf+XOFTfacYZBBzwVj8e1rJC6AWlH6Fbn0jXw3JcEljA4zUh5IrYhWtyIZW338UVsMSIp91USeM4uCvPsOLAdyCXiWu5H8MMYGz1rJxVlTbMiq0tn1w1f+CL14v8EiUft7l8kfZzBZzdLvzdedD/wHQ==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:45:43 CET 2009',
+ updateDate: 'Thu Feb 12 12:45:43 CET 2009',
+ accessDate: 'Thu Feb 12 12:45:43 CET 2009'
+ },
+ '7ef137cf242e00136e57ddd262edfe6b418b6f57f3b5e5e15f3ec1232867f6c8': {
+ header: '####',
+ data: 'N5eWFfsQGHR1WytyXuVySzJ3zenJEB6IaKr2vgWRHTlJFzexXzJmSLoozTP9Z4TumDOLsNrp+EUeIa3Yo+RqSyQKQRFDHXlUYa6c9PPLPXdexSA9JO3AHzMSpL6K0E4gN3BybjL2rbcQwUqJLvCKy44OdiJvORGfIIpTPx2LQ1o4P+chcpOwwe/ZhgLWmNC6FmkTvsU/xJlNuApyD7tPX7Cj3lP8WBfYEPr68BqTKAa9cxai6ZF4BRC//rFob/4pQNHE+7qjOSY9HOnV5uCtZehPYBwfpBiDYhaxWJxXN6sxtpe7GC5CM7gAAHs5lgVaFSWffOAL3zeX7I4vh3j1nYdXoh5KowZJVVUUfhwqJo2T3YDVsaXNibZIaPd9GlbeBBk2HL6c/ao6B8QNwRU7GvMHAdJKta2I9mtU2NCnr0Uwi4rZRR05V4k0HIMLEJxRo/IYAysAYETNIAXzk0twIokOF5JPjP4uTXRZ8LdiS6JqfoUu3Jv/7yq8wrKZM7DaQA==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:47:39 CET 2009',
+ updateDate: 'Thu Feb 12 12:47:39 CET 2009',
+ accessDate: 'Thu Feb 12 12:47:39 CET 2009'
+ }
+ }
+ },
+ 'ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c': {
+ data: 'zbQlGR1fT8HoH6KvOPBoaIjMUsVMh8MSNIzPO2muIMJDVfXB2rEcPnIFl8fNv9BtE9OLecuex3BQVJKGXdVGFYVNiSS0SgPoEpyD6GJntEIOaB7GnhVflTm8fT7Ba8ArS4r+fIL32Jx9F8sYrL6jKPWeuImGHK+x3X32uORI6znkRac7J727TiTPlbj03X/Fj3Of6Bp9Wa4xbVMwzi+R6NRKD4A6Za3mqhoSpYFeHWld8+ChJU/w2wFkj292OjPBzvvz/SR2Zth+AXTChreQ3Zl1hWNGmU2Ep8ijFCYwcamgPkQwh4vBk9NJlzIgadORcb/0EPDxn638VNA0dbpW8MZUCIMWVe3A8VgdllWxei7dDy1ri6xsKlFovLYjRRPXgAqRSqVATqwyXqhBWhoV6VZ5NaSUGvM8okC2GQSweLuz29py0F987MISmLjav4gdvcMA1wn7FOIaFTNg7oy2CxZefGhHT3sHfX/PIvs/ovfj+7TewI0k+HR414az2D5reo7S5I4+roCm1QLVpPNcXUxbAmEbjF8JCsTtECZ4kdpG39dN6BaMlHoHSN3wu05uTSn+sL7g3Cg0pVLlnHo9baw3fUnVJp3MCEgZJELaiI/WF1Om2y2S9UeLur18z5T7hHFv3Px28D7c22HEDdF2CObeh2uOlZGAa06lp7YlYeoNtb4CqLlZAMK0xIHfNUceC4OMNvqyGswd5WJsYQEnMry20OkxY6YinnQfjAml54B6WlvNVlg/YaKjw5AVinUHjzEFfQbcBFnFGpqg5qJk9hZmb1VI6Ujhq73fPydSfkvfScTImqxCNPD/BR8ovoaJtNpE2gmcoX9A5zhZgu5xUnUnXoaQu0l7K9kWof/UmCCl0O1A6j41aebWr+aoFMalaOPzNJ02vfLuW155IwjFQvRuAp6EuktZ2dFKyFl3QnLbwsMnitReXMoW30cqTYg7ODQnopE73RIb41Nj07qdx6FQMzw4gAIEFBe1iRvlMHQazZCb2ndVvgtK3ZcPNtDoahuPRxMLaKZlRnpa8E5F4o8NHYNivshawZi36Hk6w0dOimCiuk/zvJ1mtx8hhX7B5dsXlNcKxLSvI1onEm2x9HL318xJeT0y29alzPYVFuQs5kq1+UV3h2hL4E/H8h+5mWtTLf/MjaTZ09okW/etuHFFjCmLoKwugk70z2yLWEJGmbjw',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:51:17 CET 2007',
+ updateDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:12 CET 2009',
+ currentVersion: '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926',
+ versions: {
+ '3895963f82854530ff754c8e2d1eaef8d884a8cba7cd058b8b7adcdc12be3da8': {
+ header: '####',
+ data: 'rXmjQYZgxv9jpFus3T/qa9Qc1lxt+mDF+dmZeDmDG3IiE/LnonGt2MqL+YlbFzisF99Uv0IQGOZCPigtBwOXB9m6R6R3lEy/YhD/C6b10s80OBj3yr3PoTsoTmbnmZMYd4r+qx8SaoLLkR0aK6NADYZXebR5QgVtwF/a01EifI6YxH1wm1RX3kyRhIrMzOtL8zHbstPvW4sRtv2YpZqlZqBTdoiqztDUZTKEcCcU5QLnHYMNAVpDHE7D9WvQy8Il1taAbxg97Ir+2ktZLjqfJdKhU7ZLv8fcJiRgnQKPqDWcqpjA+CXM6Ak1HCf9SRJh6Hl64+fk3jEVAPmHvry/xq2RPCG2YnVNWZ+uL3QNuH4zt+IbP4FnrxkCAprmEiNwvuEefMgliGRd+FowIaiFWXcEtYxxQvRDujZN6eoTUU0KVnuy85PKi3ih0ZECoDM88MFhztwCG9/nJQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:51:17 CET 2007',
+ updateDate: 'Wed Mar 14 15:51:17 CET 2007',
+ accessDate: 'Wed Apr 25 10:37:27 CEST 2007'
+ },
+ '5311936f6a95cf123007ef867388adb5c1ec5b2cf1173d66e501daa16488e42e': {
+ header: '####',
+ data: '+VirbcZ59SiN9UJKrQkjQx0Z4avHIhvw12Hq7fs+Qnoz4RgCS17fqzYyJe+jYorjlMPjzUcALYOTobqJJp4Sp8v5nOilHW64Gny2XRp59PQPg0zE4TP22l1PzK04+qJusR5NLPU39hYbW+InkDapdIhdf+nIruqeA311bRLg90A8xmpzio6PkZxXmhZMabbEVfXsYFBQKVBFloTMusBG2eaxTjeK0hOAk0uEc9RGOEwCOvZvjRFCP8DyZ5T6QV1pYYgBFBwSFrB/koXmBmObj8zscJXQ4H4UWC0yw1B3ABbhNX7vC9q+vgZTxnGqI6GvzLcrzaXKTEyfa9twq+vKFX1hqDmM0UVLw0dPOy0/3tabJjFrYbz5EEKVin9UqWhuy5YIvHEJlMkH190Zo+lPMuHvD8TiAU1M/n1bTQSBQb/8STD6uqefbKS/s/bXcS+bdVKBmSgCuutBznYO',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:39:26 CEST 2007',
+ updateDate: 'Wed Apr 25 10:39:26 CEST 2007',
+ accessDate: 'Wed Apr 25 10:39:26 CEST 2007'
+ },
+ '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926': {
+ header: '####',
+ data: 'P1LfM+8PA/kyelFsojabLfBW9D0Aey5qDClz0OTdSamMT2Mv1U35eKcr6ilUrbtW+dKJotAzs3B1dYGzaEQ1j9HnhiL2pk4wgT1JWGe5c9frmFX/3YGO63c2ngnaC/Rrv3LC251cLVS1aoWNPskWkjZLzF7EiWbAeNYTplSa6MWm2LdHAm6xq2dcgYx53RJVvjnsCzpghQdzL96G8ScJjnUx8FC8mHW4Ds0rkHTeoM344Ao8J3o1XwoFqFFJ2X8+lSkj8LVVdjff1EHIicjrMM0oJG8VyxK2TxMvg4mnLWP4ALfh24Wrb9XmrM0NjhQXBo07tL9dwa7sHHKiBrM74644vBR7NB0+Laedg8D+6FmgNoR6icB+qvxCIIvAhOpJ0er9f0CGDDS06knx/lDtVVNewzxx4ATuG0HQn8M61eU83EfbKWG4Mg+9jtRcW0/bdFW/FQr/OeKg',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ updateDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:12 CET 2009'
+ },
+ '5c622bec0fb939da012beb98a858a4e16bd670b3e6fe1f7c92a247f88a65c747': {
+ header: '####',
+ data: 'XGlplDTD1xamZO04H6RiqcLd7XaPwxI3MqpKTCVHPBoMEkwE4A1izGjFKdPqHbQIuYYcT9xDgPOknlkP89jDTfcR4UfENtKHFgFaMee4orSER+MhldJRxMwPLorZmMNNZzVmTmwJS7FI9jYiXEvDbcyw41kN+SA0mxzWpc9emaX4TmZHzlBpY2zXKJLyN3otYYzcTWzuu7DJejWrB+CnNp925X9vVomBPfp/Gt4tiOFsE2ZyEf1B/7cDmMszlQgEgGJONS+C8Qyr+X3GEh5iPoYsGpMNmF7aYnZNciE/B5lP/ABVbZIi2KfmRlSf7Cc+kMkUXyHxOeZHuVv1ZlzfIe3gXlD0/yUJFHNju8ai+F3hpSkhMatf71mLQzD5oFrTmKatH+zQZhGPP9dQxG1cgZRcjbyUQJMazo+0TJuNXNndi/oiRzRJjYRUbZKsfRzIAEU=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:51:49 CEST 2007',
+ updateDate: 'Wed Apr 25 10:51:49 CEST 2007',
+ accessDate: 'Wed Apr 25 10:51:49 CEST 2007'
+ },
+ 'bad48f8ab053804a02bec678db01baf24de35ef04a17b90e1362e67fa352e4a4': {
+ header: '####',
+ data: 'SXl3D4C5Yt81L/117xsHYjZxT/fANq09VZsMNAz3Gcn2+2gopG+1K0JFg/1Mbjt4EMbe5Or42zBlJPo5EAldAfWu4MoTkQzo/wKPzgOWlIi3A9QwZegw3yCuHvJv8iNcpjGfpY0OCzTZKNomTtwc75l+8FqgwPDW4wDkPG98275ERDR8mFSZfUAiQxlTnCbskFneUQ6hdN2gywkyJKuTEcrMkIpzwe9uqPaQg8GjUvvy162/LVaSQAVRIiTbW5URCD+hT5cKOkmFeBejHar8zR3SQQ+tIJlKERBwfE0sNR+RebSboYxWPECYPp0DMj30FnHbfYIVTgRCIlepy2hfis0+9C7dop0jK2nFREjcxSIqonF+juCrfJDt4cTlpn2SmcoMJQsUOedSh6ZoWweXm7lu8buCbA2Q6SY1L6jz7okwIikIinxGDq3qT1pWSgpntI8wvYZ8RD0umJsoAzPYH9zlfQ==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 11:01:21 CEST 2007',
+ updateDate: 'Wed Apr 25 11:01:21 CEST 2007',
+ accessDate: 'Wed Apr 25 11:01:21 CEST 2007'
+ },
+ 'c03d1fcf5b6981741f5d4787315534641c61daee9aa3c063540fbb704989ded6': {
+ header: '####',
+ data: 'sbn5IDJM7VtYov3sqW9+/0USxZEw2xq8di1XVPMMZ6kN6oZZrAY7ukxXHYh+mfuIa1/uV4i4v1YCaKZQShLgUS4cchlK4nnNVL8zejGwB+PaY0E8Um/Jg6E4UAFAZ+haZwzWLQS8lJ1r4hNMTeFqsDRUhC30awJRz8e0rBejLZiS2Hk/jgpH3i8Za1GwDzogw11iHXejYI7MaQGB0E9eQsYYTxGjmzcLfVYkd4AKj5pSEHvsKZklSuWIyDzwaFiIO7xqcJmS/8Wkm63JGNOW3nLR5Ao9V/2vthFHBqS2lQNRnkPWXbmNK3v7vi57zu461w1Nn1U/70EvhHRMk8BdML3XI/U6WgDARjQuVsB8FnTkzapaORG5vUd7nTtWjPdyQzOqacm2YKWpAiG6fUQTZiBusEd8jdnv8BioGUTbXgNVG23zcRbbbEdjKc1aizXHQE1LnROvoHZHkwg=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:59:57 CEST 2007',
+ updateDate: 'Wed Apr 25 10:59:57 CEST 2007',
+ accessDate: 'Wed Apr 25 10:59:57 CEST 2007'
+ },
+ 'dbc283f49de6e303c06a52725b8187f344ba7b433b0158d704f094edba782710': {
+ header: '####',
+ data: 'fbNrpIoYF+gpMUjSxoOc9Y68qRlE2yk7FPPkrHTu07HHWkAWy7H7nFw4BwGiFViMkyEC2orUrMeDYhKmMYFj8DEcALk6452BtNutGZSoqDhD8xnSEPF6fP2Xyy+vZHp4JWDXZt/xHk4vPbxcwTTlmRz5aO8ChXIH5iqfRL9+Dx+gJDKgKmCRMZYMT1pyOUewmsT6QDYdGFJTRRiDmoLfCVAXhJRtqQSBcx3kN3kuf8gyOMAeJnFGISTAj7THzo7eGuQol1omTMgGbDZoL7WJNfZIDamiT9TWwzp3UmQcKIsRvA2ZKtePWRmpWyq6WydJgFXHUuUDVpwT+kc1Rn9Wq2zwm1VBw6gqKCp6W9bZO86rRMs2CtuLT+agSpqb4kz4SEYDCW0+aUsJDCYBXx5yWRM26r0XAbU6X0D+xopGuaVzsV5G7chkCO8mUsjHzZCK7hOAz6OgjR2+',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:38:17 CEST 2007',
+ updateDate: 'Wed Apr 25 10:38:17 CEST 2007',
+ accessDate: 'Wed Apr 25 10:38:17 CEST 2007'
+ },
+ 'ec525dd942f72b71b5fa1aca0a36a9960b71608bb27f32bc7923713bde021b12': {
+ header: '####',
+ data: 'AHP4MFiGukFCCnjLDGoqJUDEr6QNL+KoZlcwOqJIYusRtl5qmhZSsODHbAEpmadxLGogDPrWoH5/XLZ85ASGRF5ALzDgrFKP47/bSEzKVTDABY5BJSqvKgS/lCf2LdR7+0HWUVJ6Z3GOb9GqsXC70pMxDo/RfclOQPa+k/sXCW5u0TmLb/0i/dZEM8N++4umXsyy2WPLtUVzQZ/VdTMDwl50FeQxu3aNGy4qYd4XFk/7gxBH9skBD6/GqpNajHJrcbi/WZt7PZiN9skoVZHhm3YLmteP5hJnrcCGBFJHWuQpXfB7NR8rNmd2c6maemKYmUlX25wQF7JPcROOcyT8iYpF4Hk/eSPs0CSkaDdqSD0Nj9E4kqZrHfVGMwBbDFyAzdHTN3EyGuC4cBXdfNZbdBqwghuB1x7RLXs/pbXg1xqukjRdPLTxUogPdaQBHGo=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:56:58 CEST 2007',
+ updateDate: 'Wed Apr 25 10:56:58 CEST 2007',
+ accessDate: 'Wed Apr 25 10:56:58 CEST 2007'
+ },
+ 'fda6581f0137dd641387a7be193b06edea4451835817bcda38d22ee24ebeb77c': {
+ header: '####',
+ data: 'QwDMobl0Kds+J8mknphumnONOIF9gH+pC/AJpxGmuy/rvKfHSeEuuWAZ/yWj8J/I4V7OjpyTs9/uCWeKs9khpdkcxtObB36IfcbWBHGOgFjvqKgwMa7eZSIUPZz9k1NsqJC9nU9U7w5EBzQKVIjJaey1EdhsggdtNOpQTzt7iu2mWKo33dJKQCQ5VEwhpGh6SH1TgKFbdMkOJJY8d5xPYUxR66LVFpFzgHP0ML5M5U53PK+apT95UIAlqf7N32BjPK63Nsj1WPsnuuL0vWA3KmefHzwKGeatTdsgck+1mwnCDJncPWv7hTwMLGPUaY+Yww3K3YPihuyCUtUdV3fer2VHVAn++JdzerHiLI/86T8gHiLAi/anFFh6i2kMMVxqzREh+62n34MrgdMqbSFQb0V4Dhm45FVJH43uuEaoe3OJPtyvj1HbcSR4VEVgGkDeced8aAK+Dg==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:58:33 CEST 2007',
+ updateDate: 'Wed Apr 25 10:58:33 CEST 2007',
+ accessDate: 'Wed Apr 25 10:58:33 CEST 2007'
+ }
+ }
+ },
+ 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:06:54 CET 2007',
+ updateDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:23 CET 2009',
+ currentVersion: 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf',
+ versions: {
+ '12bd9887eb84b99ad40c1e413cccaa9ffd4deed340c71fe53610088faff349bd': {
+ header: '####',
+ data: 'MiAIw+S6GDmLLMcGtkl+wveV7dZAFrL1zGZh/FPvG4kpOBbnyaolRynNrL1yeUbEp4gLL2cK2BGYiVc9196PMOvKPHR5Rqp6GlT6h4RUJ+nFFF5/3LNGzQtJbiY0rrYKptqyPBC8mhlqtdK7sQkQonj5LPhKeCX6AyE3juBPEuFYhvTv9a/iRPub7BdlAocz+bb8ObpbVHnNvbGhiRpx9MpUg44JRxLQYhtDUMi2UFtURidKaK0k2lP81ckPDCgVgxy65FjCq05vSaCW0hanNrIwl+zAgi+3ChriqmflvsZYC7TQzUBPXrAQ8bKmzppZWlArIOppRF7+paWrHA3Qcz4uO5Sw3DvMwbgl+XINnmkE/EbA6VJOjrWYJjsibvbCw6vNr4q1A4Yxwy0a7EXbjFiwpEr+jMUhsq8+d0DxP3tQTusV0l9wcT2OWrDRKdjDUXLQOV9BVw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:27:40 CET 2007',
+ updateDate: 'Wed Mar 14 17:27:40 CET 2007',
+ accessDate: 'Wed Mar 14 19:00:21 CET 2007'
+ },
+ '35af99615d1be9d9841b4a37488fde9aac291c73c8c3aaa570cd05b3fd0baf5d': {
+ header: '####',
+ data: 'lv0pIfnhZZ6ktahFGl3AgAfdcveIcUyAh9x0iVOCzmQ9VjelBztlvxZEo+uByaFh1ptM+eqOFT/Vk9IKhNjRWTXrDXioP7oZ8IZ1kLfk/XuMFH9AgYzm3H1T/yLq5lg1WqqZ+OfO9m37Z4kbTjK9+adIAJ3TwsMxIDpIHYz+qbznjJocubYCbi+DC+4wo6qu5C44gf8n5QF8DOCGaBCyamxFvkqrSMo/Y+3SG3yt98MSgeMScGESuwKKGDHZX0v3ZXvl4UFbxywUtdbipDv4PAlzh0aadMsGqYwO8bPKEUElCWBXd6kASugaqiJaZFtb02EnC+nncv33ZSx+WyJqwKIBk/Kpd3/YDJnX9t3QU60j0YKf0my9oX1746F5u0XGX1DNRaw/1g95zRHoMu6j2cSTTX7CJglzIlTU8kglSO1LOasxm3Gt8iT+8+Lhh4Dw86ugqHXl',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:09:07 CET 2007',
+ updateDate: 'Wed Mar 14 16:09:07 CET 2007',
+ accessDate: 'Wed Mar 14 16:39:40 CET 2007'
+ },
+ '7cc6c6f2eccd8bdefddca21a59669655d7515f440b025144b9ba6b18472cf189': {
+ header: '####',
+ data: '3W8FqWzBVaEbMZRukwXcm03WbvITt8WVKKuJlcSszN0dCJEsIZ9vLAiDp6dfsFF4PEPcSkiy9Ww4FiBYSg5OLW6snRNdA7Wo62dJ3lqn8TjBzv/Rt+khf9mj/WwJZZ4wum+qdwTRPyaoZcAWgA6PAPPVp85iDBP8UBdiFOs+y5kz9GiB3psvOvqC9LZ/RyK3J+H7ierfWecnbqB9LT5Yuhfi8SO/gw+5vve6z1v8sVcexI0o8gk97rDV1W2gZz2WNtO7K5+233Z7aZlzouEbDZEOGG+zEYh6SctWCspgUATElf8vZ29fABsk3uZQO2tnBvINChs6jCRxnbmnjb2Y9R8u2QRtHjjvRro9E+zhQf3laJc0G0ZJp1zN0wwKx+sL7uM6kG1aszNJkzpykR/Uz8bKvoOfG9vkz9+4Pczh5xR+k9rCE8nbu6Yt4EMiUfdfjZJHAhST',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:01:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:01:05 CET 2007',
+ accessDate: 'Tue Apr 17 19:20:33 CEST 2007'
+ },
+ '95ef5754f9a4514e5bf883436d60c38c3cbb15c3f5452d512a05839ce20125ca': {
+ header: '####',
+ data: 'Rko0V7wG9GEmH9pZtXSfxKGDLRhZr65ef/DjkwhsPoYfLryET/ViMjcZcM2blyiLKOxjiS/avGGcXUmInz2AyD5dAFTGge3qAZ3QtxTcNn/fvfJeN+JyGJPIsTIQ7P+jd0uJAb3vPuymISGJluTsP0MZ8zxahSSRUV/VIYwm10tiMVvWEq0+8FynKfWDqJ1eU4pnI47CAdN9CuWhxi12RkMBYgiUzNzTh/tbPTFMc7DIyRfR+si6TuPS3PmtnKt4FMFAX3FznGBCNsonUFf/n7Zy+EYEU/B8wJO+18mqbui5YvmPCPPKiW/pfVuaWarF7zcIcthYoKQfTaCaulO0VRtTA+Wg2LtJv+QcWWWTiY2A9FC/PppLZ8+nFDeng6LqJYKoGnn6qwtSVH38s3Inzbs4r8mSOR099tqwfCnZc9zZHisdIbVm82H3gnqelPmc3IXb3nHb',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:17:20 CET 2007',
+ updateDate: 'Wed Mar 14 17:17:20 CET 2007',
+ accessDate: 'Wed Mar 14 17:22:06 CET 2007'
+ },
+ 'cc7ee01d38e4f1de010d2a235e3b76e838ca05fe70223b8358a5e41975bf2b7b': {
+ header: '####',
+ data: 'TJ5ClYK5JmZvEuNCA+/UeUJQ2rGXbPnFqWP31GAGXqhZmC0RuDNjl3sv0nFKmcdMa/BzvLSywJhkidoRhfKGwN8nZc8M0VpujFkpvdXgNsod6x+5LTMP67qCyvD67pkYMa7O+aosKi/ZWWnYBavZSdhyuWnU1wPxxk+wwcjjIrA5Tm5zTXM/68nLLnIWs2bQbUtcwHgLrBEUshG5oTUFGxrs8zYwodsYUuT1CVwODZrzMxvvbHfH6Lqt94m4hBF0oIrDCd1cSaXghS4PiZkJWQVxJNSsuYF/4PlPrV4ATZS3Jm+DqOxLOOnU2Xu1Qe9DxBppnXjs/WpohYuMV5YeD8iOJLXTQbFKhBJNSCoLp73QywWazuKkasC6cbBrTHYykEKXpt74iE6oKg67YrPkIZJ/jKEGnZ7wsY4ObeDTS7OUbHKxPHRM3ZrmB672R/8ktglg',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:06:54 CET 2007',
+ updateDate: 'Wed Mar 14 16:06:54 CET 2007',
+ accessDate: 'Wed Mar 14 16:06:54 CET 2007'
+ },
+ 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf': {
+ header: '####',
+ data: 'CiJDd/ShGw3rE0xCNZspkdH6hRzvSyaNiuQeMBI0NR1MReaa9uVMV6Ymj+BWVQ8FaOziQ94aolsWre51EKwDWC1otdovPXWHxBXBBI/Y5A4dyQisBeR5E456juUwDtLKX5En4iIuOL14IGt+keUtb5JyfBGuTTA+EnohYzvDxu9MDh/7nzCcWzUxh2zHEBSyowfOwJhx7G2xEvbBgTg+TkejMudbq9k3Owebe9QNdhU9rsY1UMxjL8+HgJmgyo0C0SA91tZXBB3i5ePvg++ze/SW/r+XO/nnVzcEwCJE2UWAL+vNh8tUm+sEbWaqyKwjHNSquxV4cYOG2Lzo45Wp/vZwiUR/8MK9THf0FO1mn3QCd/37AMMneI1Gqk0TNwNtoQKgLVBNhhgX7dIVpRxB2iiSBYyUK6N9LlFahW2QVDS7kdnKH3vk1cP50dj21E45jEhhd75v',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ updateDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:23 CET 2009'
+ },
+ 'd65b23008b22e5000726db3fd22b074b08553fe82245c3526f708b8d89f70963': {
+ header: '####',
+ data: '0y9WhoXwZSfzfxuql8LBc5/RiclPKQxcBYjcdGv7v6B+WuGrB6uu6d8pjNoUtsZnFv/25sefW3ggVgDuI5iZNg2lBQVIwgcvK5jPM5foit49d3RSWl74XdHY2XqykRNDbboKAiNfro+abo/YYQXjkhNBOC0dWSUUw+HmgK/Bm5NmJD4fDTV7OYFsvX4ExjnX9pktaB6aiLZWN1cZruW3Lsszx/ryHpDtcPrmK2hgLQ4FjRSXunbqXKJLOADQiMbGZ8DKZchB5NcEWlE3AfL6ybJzTyr4jXuS7A9PyitxYNKFHAHpJEhxGkyuhUE66QMt1n9NKzkNx6yhhGdIUF2zVGsBUb/pRrL2gt0X2lsZ+CnWFu4jRAeSi3KfK4VrvnoYkVlJImxPiLrzJAvqkuA6TyQRpJ4yFVJ0dgxBoxZVSN1fp9Yvkph+Os8LZscJtpYPPwVDlCnC',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:22:08 CEST 2007',
+ updateDate: 'Tue Apr 17 19:22:08 CEST 2007',
+ accessDate: 'Tue Apr 17 19:22:08 CEST 2007'
+ }
+ }
+ },
+ 'd620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045': {
+ data: '+iiHiN91FfHKOXC8Z/tg+YynPECa5sgYGGofcoJeXt3FAAkAFu3NsLuwjYIaddJiB3MIxFccrCrB5eDDL0SzOS+j63GcoMCeeiXss9YfVunA4RQTTktiU1BknPYfsfHj8EOPDSVHkPFs7KhAnBlgyaDiQPjYko5Np1H2i7F7pRmfC8W5LGdisaqxFDa+1ghu8K6a54QIpbfOmolQU3w7T5qiOdoZv8GLDDoORvMMb4P09IzXpk/yDEZe1GJ4g1a9t+lHAhiKSvdnZf+MhK0jvs6R6ALlmO84lRP34DmT/35Fr5C7D6EJl0OxXkWgYWelTlfU4b8+SStYP5LPYeD38fodSmObpKmpp653T1v2yaTybI1hojgLbH2DuA5VcQAM5JHMjoSy6s76mf2AZZeRnej1dqdvIOTf1Q6CR+ZNIqnkukrtGq/6elF3eZZh1Ln1EZDiTzsMxUHBngtiRmRDofqRSJUGbEAjw90dBoiaIO/WwLAy4cTec0nJxwYd5M7nchEly8Cb+zz7naP+vEGEAWq991u9NFZhrw7WgNgHnG0E3km+X+SYvv0i2MkqjYs6ItDkBNyi0Udnc4CqfWuKa9q04t8mZiy49LU34Ho4/ijuez3rdOeCO/oIwkRkLZYfFO6IxO56tAI3d6iJqmXY+DX0YUZrJ6FT7bDsUj0umV1htuj/uEgQZyOnKOyA8cSjOTMRIkodI12HrtdrIA966BDznsKW4F7f31VaSxI5ezHsdiYEsTqwaZlFQMsjfZX62EvDLJksJTe3JG15BNgsDUUh1mqIDCmVswFTpUTTb+50ap56c/uERSET0iXP8mb4hKwJkmngrBEir3btuMEMS0xSFQ2jTRjlnWRQr9eZT2biarzgEhKHyu2qCUtsUj7TiieQJY09EXCP3g3Da+61nBMoAwi/VqTI6vQaLGtuDrA2+VYGc8x1SiahmAkRPpQS+5N9qPvxxFRbKforMOvmeboFVxdKesub7BHIXQsSOKsHFZnFHswa/oLBITomp3ewfp125RjBUf1C3hMBNg/tmE5pgLqPfQqWK7IOnfdyt0jc391XWb6H3CVcgC8DcPKJ68o7DBucg9xTNwlIxBTafupsBa9JUkBigqYOW8729lNjj/QTvTUaCxWub9SDT6/y1wQUI1wyyg+EaR0fHqumMhIMbuvIPd/SvKMmZ4TXtBc1U3H3IGbkqIfx0f5rI6AuNMD7/pXTAy2Ot1ZBohnQmEotXRvDwxPMqBvPU74t3USTrysyXfJqeFtHi8GTR5X0m/PYQKWCCHgKvjw3d1CJk7tTe3iV2ulk5cnO7tOydTMJFgPuT2oyDDDTp5jYJPRE0OzZcpAzvRSjELfJ111sFBOEzTqtBUHA/E4BnTIM13md0ZaMr33E7ii8rS7vaKrQAI5moonAtAEOVbx/ZrcZ3kGzHpRCISeteHgnM4I90x391HqDkc1A7b+iDQF8OY0H/0as/3gaVaqs5jsuhIByj0+KmoXsdq3ZBhEQRW151QDCdMKdulNUxbKTYV/t92z3slU6lO8fiy+ON/6sTtS6jgnM+oCLxTfpfBdz0uKG7jiSOyunj27QxNjLyu1nF2+mAcDhtMN18QkJGLXKYv39kx7ny1H74i5rba32/QEAFl5eLJNIQbJZfZG3HzKMVS19ZGwgsYNqV1G52x5+bZUTR8YcrLWmPTJ322UxlhTmyjQv+fVCnpksBtjLGntsGloemFF5YVlcl1AfyHb+KlXiAZn+8vpfVVBddFFMeehokzYE1G8Doa/3huhqdtC9qvAtpP54G2p3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:36:20 CET 2007',
+ updateDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:28 CET 2009',
+ currentVersion: '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130',
+ versions: {
+ '0bea892da673bf4b3d3e4e97cd3e1645eb177a8423dc761583b876c5ffb1e2ca': {
+ header: '####',
+ data: 'BmZz8j6Khuz7Q11xPA5zSECcqn7BOcMtLx8AmX2iE4OrIwKWcZ+u4B5kCBxtFPRZWLdWcxAF8VfaedkHx5jxPNeWNIa7NEXXcFLYQv9lwUaxmtqodYtVapAg7N+onw28UnV1vB/h7ll26u263jWYohtd5eMnXhEjIEbrQYpf84jQYlpMKjUDhsVQeZvTI/KfiXa6O38ygO9R+xlq8xKgPPX2bkXfPJiyzlA+GoLSORc0tdqseGGOK4BFyp1V/KRUQ/7uQmGs1yNWt/ijaQtJXpWkWXmjHyTjXsi0z+1s0KH8TwSOfu8yjVshMyIyEDd+EsmZeK0QwMCm96v311cRhMgAkQOqL8xc2uRpGygtTkV2frthF237GOV5vwO9IoMZQFlvKZreV5mPPPBeqfP+o4QRpdnJRRCaP8Ds/MmzGBqE13ntwmo1UVX1k408ZtMCO7h1eQVTgCZ/Y2RD',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:51:02 CET 2007',
+ updateDate: 'Wed Mar 14 16:51:02 CET 2007',
+ accessDate: 'Wed Mar 14 16:51:02 CET 2007'
+ },
+ '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130': {
+ header: '####',
+ data: '++u0MEaILPK8riF0UzCnb+MnC51GYcdqCFRKOP7XYt5QvzWtxhDMOvq8ugCDF8G9sYPAoBLiCxFcuCtnkG4fp563VeEeC/dRnArzMDvjILYKAETgpnLQAfyIR+D8RfUkCbr+aOJ4XEKcy9a240OQJFDT0whoTKuX/6XVzVM/D7F0r+hJiOD1ELsVEi/+U+dXXO/VDxoyjFxfa1+M+Ygk8ewecX4nVqwOiFWHNK2lXW90inip0p8yqDsADx0KhE2tjARWVsjoNdf5RSUOYr0Sb0syyjBMi7oF4jpbLvHpu9fe8vpIcve+aSA/MF0Acxh0/gToDcO8ER3K4wcJgNPIs9lXiSrmuklK7kmS+uhz/rWCtZZH/OB/ov5sez5H51EYLmSNQbx5wZGZhtJWNN+AkJobg/Nt4XKRTe98CutbeiiYUGPxQvwG431Erg4y/q216n55FmCBIHZcUsa6Hk7ezF66c52EuAnVEkn7TZLl7vvym+sv9lKev31xpAGwX5Gy0tx2A7cSE55ZoyqOS9kf1s5Kwprx6RSBzfy7sffLSWHxyOSBnd7B1MNZglVSsbB1r4gMgZdYG//MZ/3IhTFbUqqw2xXHzTvBPA2Hl96g5Xzx0dVx2wHWcPcTSH23VrLscQCwyiDVINwmIzyG4CVSW/6gzA5VM4QYOrUDX2ZA5ligkZpWs0HTqmCB4SoqYJUpafaF2sEtCWHUjuVdw+rQiTBCcRTr8f1Vah2q2xbXMedLCRS3Vq4vlT0a/3wGgVD05CsAom31ZzmHQm94hZrx3FTPenhxLtTOHtDYXnbzYWufWEBSJs6VNtG9F5Md63NZvzEZiggfxTREDRZ7I9MBOPhrxz/3tAo+xInwvLXOEnTNOHVATm9u50kDs1qkJgqiXlxi9pZKmrTu4BeXS8cOxJ8O+Yb0Nh9bExfw+CC8X5xiWE58OwalxY2qlvuoR6mOqdcd+L7YPbGq+hJ/7WgJlrvtQe8IjGF1sJg6jfO8ZeGaPMF5NnbQVxGAq39g00on/z6dW0BLZyA6uglv99si8aRLpMk=',
+ version: '0.2',
+ creationDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ updateDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:28 CET 2009'
+ },
+ '63760358c7f5783d11fd769c78ca3f1ce787113368743655ade89bfa67d0d30a': {
+ header: '####',
+ data: '7lG/UvX5KjLbN+OrHbDeqXmweYeOL+0p3/UoLi2K93mCYdwsvx8mg+zghxwg5ITKPiZ9D/QWIShqiPpl+dvQJGWgs9EcP5W7k32CS2RNFaZ7U820rSpahHP561HDcBU1++5wHWszLnqFFiCuDja3OU90dsCTLI3g0igFgqpaRbjLcRTddI/1N48xNfV1YieC5Kei+jZ34zzrfKRn1f0F7mTkCqCSfygjnpRBgZyo9BfJ9rHULBvplvpslUUfFTShkLnCx0UbWPXog7DIZUCOwvPr3KJvmcZtCJp/1nW7gm0E5PaueJF10+ZlB6pKvueu+5yEgVmVu/lctmPX/UwTYZDgY5VWSWS3C+JNAvV87ZQKKmp8N6aMFMNOLCsOYL5hFN9uWGtMmvtgawqt7OhO9HukSUs8pDTgNeXoWyrorLM0cH2fa6a78GxNs3nCSUmqSQchJf5eWmASZgvI5xXmHXsNbuc4w5R9BaEPzyrrSAIa6r9D3rpFbUhMm+qPv9pZE2HF9liJVdWCBOSF8ZfCjsq5suyYz+YCsFHnwwpYmKAqJNXUMIhxkjgOTi5lNIsvS/iNSN9kdkeWINZk5iQFta34uJbGgjUhRy930ZGMBEV36T+Vb5tz50M6/MnlzAoUDeZAu54btKcrIpIq1Se+8zldwd6UKGq5nG+dMPk7CyKfZ5LkM065KGbgEJfHO651AMWp1sMAsbIAM6h1gVKbRjNyNwO+UK8eDpIX1nXHVj8bDVh96160cFbZj7htsUnXZh2AWuY6ahwdrGwYeSFoVAnd6xUF2oH+zFz2coLmLjD4Xm9IuQFsFO0U1Vo7EKUJHkPgIsXUT9He9tl8/K7UYQMXGgPTpercQFQ1ctFEqlPbFoVNO0j7Z9lmeSBcLdvY67CCbsoBDVJzj/wLRdBQStfeSUe7bEI6ff8+0gVkEFFACc48fWWA6NLLtvJkYjdojjA+C/Xf6EGNeXU/VENMJokB10EJUTueVWKHCLGI/JDBQBBB3HKX2VNFcEMJxES7Gfcbhysm5bdmltyRUJAIdXvw',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 12:56:43 CET 2007',
+ updateDate: 'Wed Mar 21 12:56:43 CET 2007',
+ accessDate: 'Wed Apr 25 09:59:58 CEST 2007'
+ },
+ '6e0dbb3c582039d985e80e10d94f424a63f0cb5b2ffac6388fd806ef89c1da40': {
+ header: '####',
+ data: 'f5hBUeedsvb1VBTpmpQ+XgGbnuVDMVEAdbEN7ZLK5k++4Iuw7l52zX6AHCWUFMDRfT6joiD2DMj0O8B2g55SeOQIAtZb4PZnbf3+ZEqKMOOI7iYSfo2PctLbzzzztma8EUXYkg7sJKCuZuyXhkWZxikBqVQIp9WE/bhRxa/atnB0jJyttnDMdTAN8kxIizrHFfT25hSbcPI1cSzsmF2nLabO6hLlm7mdLZCOD6DSv9hMeOXgqXo7XdfLA4k8swnOA/85HZFmhaYjTyoDGsK8yoJny/xBbiaRij1HQcHkbG6k2QKcs96pjmiJPoCv2dmsU3Bh06l1O4OEXl/RL4qBGJBKsDW/TXy7Qqa5y6LCEnlFAfefTHVgzuEQjJ2qb/z//oIrmujt+8hEa8F7Jyn6+FGqMNRxDvIQn5Ty/CPUStS1lNL1PEb7TA3ChYkYvnuhNVq8HHf47neGMpUwC5ppk5Zzb/5zEP0XH4XXkNbR5/TYjcb0Df3egNLSQLdO13CO3mKeoccmtfcmaFCtOLXWc2xNNcu09s+/QlZMuiu1TAzhWXU2CAXT7K794mTXHXjgGEaEe86Pj1nO1zHN7QhKDN92WMEdYasRAVDu/XYdzpsKJZ3POhNJp6pynotVBOkPk+2g04S8uujLVSIPZIwu7p3RmPQGGvfMviswhyPvSsPqND77j5msYOLCnXXjeXhOe0E7fIRpxPK1F6/N0R4tZCYNJe9Zo248XdqBvl5ZQWDC6aQH1E4djPK/08CS7/kAECqGqOCDPRvvMUNkGOnxsMx5eofr1YR7zWOZajr2GnfhA9fjrLv6KxXPVU0z702aS/Mfnf87ckGpOKA8/ssJiyZ4fzP6uN4pEb6wEta2DnnacUDd96nMvB9HvGCDoYZH646+n4oev+AnkYTy+ZRpmnsG6/3Z85iH3RwN6P2I3DWvGuN2e+1zQ2kaBMDms8qeXVY1+8qWr75ihizHCJr6E8Rd2Sw7xM0+6mKpu6gVGIi09auHg1+6Q6PlCr8Hy/pc4Exj9Hx1m14WKSF2SB1SYOnm',
+ version: '0.2',
+ creationDate: 'Sat May 19 11:26:44 CEST 2007',
+ updateDate: 'Sat May 19 11:26:44 CEST 2007',
+ accessDate: 'Mon Jul 09 15:08:39 CEST 2007'
+ },
+ '84f3b8571428014d04d7c05528af73c89cedf17e23b1f9541fe7060512f4c1a3': {
+ header: '####',
+ data: '2/zsq97zQBq8wE0oAC15HW5pbbzgokoDkLSEGniP1VL+sW3b+tXYOQV+VSFJo8ERNlCSoy679G7N8tPKgA+rO2/roGP/iKEuE38et9R6v9nhCPfo1vKt7XpvzJYow/qDwdStylXbfW9QN12Yx12r/nkPldVTXCYQDF0Vs0h/I1XMjbILpq1smbNXAUdn9I3W9o8KpREvac2H1ir2vYOzq9Ubhq4jggX/9s+FGm40f5MX/OM+lJGdRPCMG3rfWVeFeWEGWpmg0AXpV7eEuKH7sPrWy+QLXD1IwNE03QLhuOh0qEPsEi6kcCaZyLlCHYlzJ/hIAR1CBlCtGm+vqD+WRr0mGQtl81MMl6/BoW40dya/6aIKNOWfmYNgdfplknkVqxFsJnwVqjQJWfCzbW1KqBvMHx/7oPNjbMS0KKhd8ctOsTLSvq4zFI+mvR6BggwT8rwcfa66shJIaDDC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:38:54 CET 2007',
+ updateDate: 'Wed Mar 14 16:38:54 CET 2007',
+ accessDate: 'Wed Mar 14 16:38:54 CET 2007'
+ },
+ 'a4218c7ece0287ebad7f3cdd6510f424245a4d7d42ceb083b664a4335bcb7690': {
+ header: '####',
+ data: 'hQ123ZhZ4AiXD25P/0Laq3MtRO2oSIrY+GoYe3UAiyEHc9HZDCvR+POEEaARXNyh+U6z8S12P1GvQbzo23ZCt5byhqC+UmbfF3Y4FikM7WmHaRPtWjv8JNf3X0iJ9a2IBLA1BlqgJolnVDtrLsFx+6rBIU9r8pI2jdcsw9w9feRbE9/0S0filh66azojT5RM1qLcIUVWGixROY6PALSnA9PCjA6IG5WUa/DX7DyRrosZ9V4ZheMlzlz8CgEKBTN/HREIbPrEocBOvmnbupIEpOvH3OXKDXf39KAGVBAU2IIkOrGyWfT12p9dK+Zf+MQUl4DDIdAbF81Lus+LQmqtQ1ieyV0nNiqFhPuglLvKRj7QZRFfHNyejkMTZQWjQhBdHRmfSxyEgmFrM17yVVz4cMis/44g3szHMgAAfFIc79wq09oNDEV+ZUMS2xyBCALjRmhedqYIMGRCAG15',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:36:20 CET 2007',
+ updateDate: 'Wed Mar 14 16:36:20 CET 2007',
+ accessDate: 'Wed Mar 14 16:38:12 CET 2007'
+ },
+ 'c6613ccf0c1c6b65798c6f35657a10d4c6033aa32204a90d9d0274783a1098ed': {
+ header: '####',
+ data: 'ATU61Uq3Fe24JAEauMRtY8vMjzaQcPtnt1fshTD4dGuptFH9XoZ4bMC4XKHI7JKbx1NUEbR2ySOj9K/NJuWEGZjRgZbNI/KtuxNedlm/7jEpHQx4ZfhXQ8OiUDd+2bB9g6V0Ck2T1gM4IyaZMJ1QfOlYmGGv8n4flhHC5kUzL2OIiAxNHvKQjdEOccnEsk25Gg6FveKHD6NqVunsiCqhxJ84VBNzHJscuCTRcbt6KwR1+dw7Y+nhTjdDFq9UidlxTO0BKYsqj9F4Kq1LXORkSyab7zKooFH5kNd8torb5UFto8dfI8/+DOVHMxNRh2aWSn3O9bzwi1PfYO1nky2O6OKR48Y65Hp1sm3Xj4AAVHWSGakYUSV5M5XxKKzvoKY6Qqhz8GhbkzM2FC0IKTEcmINMvzXdzKRTqBFg6i0t7Qo80i3sQSoju3/4CYRozI2RrF8W4f3/0XgJf21oUAdTXOmSePSZoqhdejXeNQAgb89v+ZextxA6NJNYqvrx1NjdKmWKJIU+o3AgPYj4UIwWHwVADHITKrIWl/SbOsGP5aERtSiLnC+xqfRUOpgfkAYLcytspouHxvQjgNY4I1U/2S1DThG/N2EzuPl7GLYQ+Y3RAvLObFbrV8S3DS6vXIkigxyJT++MotIKoPBq0xDq0ck6joyvwvg4jXUMKlJa8/LQewJlbH8Lszx7SwjynzEQUJcpCnmxixzSNfRzpzgEBQSiClEEqArYykew3rjz9lc9nkdXUCzz81WYsvk6rGJ6ZdDsfKsG9+kaybuLL8huE0ERhznKDJW44ehDGQLr0phO3CI8n/9Px0PhPeZ1hvoiiH8CFSW5f45ZrFaaQG8hNyzWCpCFoX0/dNsNPsAkOJnO4v0PvO0HDOif1JjgPjCS51vBzxu8gYhkWlPo2hZxHhnnrbhxeBUU9jhLAx+NmxxfTjIWkbtHtVjm3ea/D2nuL1YrZKmQ3Qs6GamKlh3WwkRWRAVU3+/mbSGOISxo0u5v8QSmh/IPIXltniaQgWweqGNnCLWluuTyhoqnqDo0II7q',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:04:29 CEST 2007',
+ updateDate: 'Wed Apr 25 10:04:29 CEST 2007',
+ accessDate: 'Sat May 19 11:22:01 CEST 2007'
+ },
+ 'dd2b4cdeaedfc97c384f79c2878fca9a981efde6ebe212138db235e51b80c64a': {
+ header: '####',
+ data: 'd7ZpqQ4CTF00+/UnTvNnnkMXB2Ow/K9dys8V09Nedq4sgMUk08E1vqi9mdWbzNfRD7aV3blru8PfoRrxXRLTG/bjQ6xncecQoAJeUtSplKEO8fhuzGqbMqz47/y3aQDHBbygMAGV3wLgJO2Pv8p+8U/P3cEJisd9OqTNE+EYQz4eiq9dllMNUQjDY9aLHE8H0ny/5r9uohGNjXX/LfFMshjeS4rToCG5mzRaJPaRs1jkjzSntpF0RLxfU1acpJX4pNSuaLscdJ1lIwc17vygg6f3xexqvCeeFZBot1RwwbztZKbMfap4pRF5KoftD9bXJwoFMXigeMGLy0scpzsp1s8zBIwLhwUxEE0IBh7qeStg/3eRSW9slazuIR452O3Rysb+n/jWMyAhIOCSrnncjjH4XHbzV5GgT2d4f8jfBPmOT7l7C1ev41D3FGFxEb5TZGcJTaIW6ofLi5T5',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:52:12 CET 2007',
+ updateDate: 'Wed Mar 14 16:52:12 CET 2007',
+ accessDate: 'Wed Mar 21 12:16:29 CET 2007'
+ }
+ }
+ },
+ 'de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4': {
+ data: 'ZYvHAVCnw96hB+0XxnBY6p+vwvup1BopHUeepu7yOOSdYNFFOFEvtCbxXXoyVaKZAeSd2Vd7YEwRP4TTJjjWNPapT0D65AFqM8x+0rEjhmVfQGZAS4L3QctzRAgBoR1qTr0iqI/46ETkNq6vHz9mPLHEL3MQ/zoh4Pp0T+uMsY5ptzuMPcG0YwajSm5J8XXV2V5ZBEANpgL91xjgh1I9LiKJa/Lv3R9HAZG1uuCvzqjA2LWYeH+6ZcSpadk/UPxDw9c78FUnSNbHAcjuYZ/yI3v5SaZTjEzsB1MtAh6AFiHtvKIMWpqoOs7XQPhz1xXPoGZ7VR64A+/bN2h+Uqn49bQrKjTRGegqkEWFcBwhFH/ZkYfSHCGmZQTVqOakqyofJ22tS0ief45gYaO54YvIliTNTY7SZMRCEhUzz6dz8ENqP7FxhUVcQRbBr0JTmaf6DAwu86iDgkvcp1cY2trnUmlvrgz2GW6TgXoFjFlchUkHIByFeIJ02olfJg4zP8PzgYp2zhwmXL8iXHXnwzuP9bQKq5j8o+UhR11zn4MFvWQyD1UEplK6vphMdS8iXDViLrOwuMz1XUf7RxNdW0gqXwx+qLU+CeypyWLMIlgTlOr1pBqD/S5Jx+Gbn5GHQViuFZHJUjJsU0xel001KjB2Wf1Y15OSdLZ5l0tn/4HYKmZLufTYpub0xrss5r3Z72RYz3wvAWFXzkxWa+oBiRQiF6+ix8DBPTc3tm+ORnQBYcV/VNVRziimV3MFSsD1nHgIF1zu+eXIKE7/b3lzY19KpvtiBio94dejWoA/WO7KXWv2sHH0JoZnRh6lzu0HRFgYqVm/052nCGVA6XSfrFtfIupxdBs22C9wrwC5/Rwanf1S8BQIXpm25P4dv9Y9cS6c2/DUHcle4tsUJlqC+LpRGKXRdolFkiL9r01V09Kev/K2oXaWGYmBLbRfIyvEHyHNeNXv5fnaZ3pTlIwXjJ9K9yKA/1AKAsAEuKlM3N5ep9pfyuyfOWj1I6RvBwVqKvcBZtYJ4u8n9jrxiyq3ZZ35eB62D+ceOAD2s5+LL2IylYjiJA1OO2qpu4x9rt1NHXM6LYJAruBnUrJ0Ylqz/ElcJn/lXAzY6RLqVcZ+tuV580AUkFiaXFEDcqdJbbzh0R15g9DtaeiQZd1PG0a8Xblj9aMQoRDRJeksw1GWO7TfrJX1Cu4k+sgARWRzZ0DvB0SJAxPcmhg2iBByn2ESlcxPvMOpzuJI11BUQsZZ7dcynubeMvdqBeKsC6HMcm+8DLEUPmzsC3HIfARlNbt1fOrGJNuKaLvF1AAdwllELoPf3lQ6EVZI120=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:20:58 CET 2007',
+ updateDate: 'Wed Mar 14 16:47:01 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:06 CET 2009',
+ currentVersion: '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28',
+ versions: {
+ '201725aba7b4dd93531e40ee08eb8156e3aecd3db4f11e54d4d88ed5508c72a2': {
+ header: '####',
+ data: '4ndloDtoW1Mhat41ZlW+nN+WkdEriCn/z/oclyBFQSljJRlMwUFvzE/OCVYc2fQx1D1GBedY/O13v+SCAiJXUrr0dgrMDOfmYy7ZtNo0hYshjaYQucJovt7UQLeFAuLO6rNK9CrsYA/AWoiT878z2iCYCqVq41sL8juCm9n+d9aR0eyjXAKj8QJzVz/uvdudoGQ5xL18x2yUZnemY5gQklYlm0u9zzCJ3rLOENnnAggFnSJ0oysNjB2UwQY6P53bqXzF8E+u6Rv3OoIbmCIZMaoK1G5ivnWHwhLzp9UVdIj8ipfLsTJnGMk+aZ3nnEJ7wQCaaLy/lY2RYmSeUTTZt2ImK4ZLrSxRC21QkD+juyIiaEBJdhP8UOfcqE8Hw+etc/Cl0QgBtv9AgXD4BiZs3HUTXsV/PhIzP+6TGyr3/A2kt8dv33V7Gh2Ba+28wtsG/+HwCMk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:45:40 CET 2007',
+ updateDate: 'Wed Mar 14 16:45:40 CET 2007',
+ accessDate: 'Wed Mar 14 16:45:40 CET 2007'
+ },
+ '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28': {
+ header: '####',
+ data: 'eSAwxBi9CLckMV3o9PxBjVZZ47g2AOIsbPt8QMPta7U+6KKUm58cXHV7BDfRkbin3JYQJGYfu4HYHmayGt4IcX4RD3riftxnG3UFNqG4LQQ8+fwA3xTMBisnUSq0JYc/PKdBKzxH9x8moSqZC/cgFWe90p0PxdY13otjd1qvDL2ALAgY/uEDboTcLTbSEhpGIYQHtQ1ZjDG+KXI8J7atuMvS0KFreNUm9+uMZT0yCXwNpGy+ez2+ZDXTEjZUKaFPLI7g/vyySn6VMXmlqJftGXZ+fW5UWGaxb7WFa1hh/nI2okPuRlUQh50xXQJXVvanw1ATJbN1PRfYEfvQKLlAAwYuoB/qL0y0vU+3OktAbgBvwt9prs3IsqjwMeaejVTo3Yj9pQPJ14a+6lxQZQRFUaLePIPdYvq9NRM7chkNYminW0JN6umi6bvJ4KKTyjAglBQ6X4s=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:47:01 CET 2007',
+ updateDate: 'Wed Mar 14 16:47:01 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:06 CET 2009'
+ },
+ 'c7398bb27021058c9965a332d678b0070287b8ad12694bc8732346e6d84fe9a9': {
+ header: '####',
+ data: 'L+wk8k9ejeUeVz0offdItFpy8drMl1hi0FODBMKlPIAmEcNjnHU/IktOlyLrK0YHj66DaplXw2EyRkJNcMIbfACUtavxhWBH9VTftOPepsbsrU19aP6Xk7R1pr1sC76w1TgKCjE6IyBnK5qk1oHqcGv71GJLMmiqGivKyYOXQ45SH9tbHC4GUrg0YxoAYRwXqg+SlwRHpSZkX55NzPCEZn9eatGKCznTZs7pg0uBoM546fOIEBMgGndNk6gnsAH7At8yYxDMnkGHUctsSExL1O+W3bDDDx7D3uPkkjtd9se0exPru0fmsfcKPrcRkx8b8MAdgcylOtMdYvSudPdR6foSIqKMqktH35QlH6Rr5E/ire3O632QlmCieKDoPk/cB/qL3gKedxT1NxtC7SNR3aumKBAKOBDTVSjWWq3sIImQPZz+RUdRajeqkryNDVVPLFyjdC0=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:20:58 CET 2007',
+ updateDate: 'Wed Mar 14 16:20:58 CET 2007',
+ accessDate: 'Wed Mar 14 16:43:46 CET 2007'
+ }
+ }
+ },
+ 'eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 13:35:58 CET 2007',
+ updateDate: 'Thu May 10 15:01:21 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:54 CET 2009',
+ currentVersion: 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec',
+ versions: {
+ '157b5933272bb6b8a70bbabb7fa0369eb2660f7f0848dcc653f592f5afd4f2a4': {
+ header: '####',
+ data: 'z8BUTeAbrs5GeJ+SxaV9ceaAoqxtW/touC8xhjkEqbG6+IgMrfuz6ABRn+vwiN1/Vmfw/tyad4kB2SyzKgaYPH7rXyBir1mzJi73/oHsXv5wWNhEePmjZginGGcWQ0P4AnrAoxlaI8tXo3fbsz8e40x1b56N5J6zIdvX3eewgIMU+J+iomZVPDQq5DNu0aGUL1xs797FNm4vLQbVRF+mzrZlT4XZNzOr/W/Br4vG/Ureoq1QRjAjj+8HRt7ojmzrpDX3RtmSbWqUPQqx/KpFGqVUNw0zs09MomVIYilRawe/zegW2KZKK4rmqoUm+mnWQTf/I31FYO2N8dLrI7OV71EWlVN4FSO2A7NRUd92uVxHzItMQPS3CSQ57FYAC+WhJh7k+/ikJumVSf18pZRSRaEeKPxbJZFJqrWsWk+SsqBIJ4EklAnBBU7zLmMVe3GO/ml3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 13:35:58 CET 2007',
+ updateDate: 'Wed Mar 14 13:35:58 CET 2007',
+ accessDate: 'Wed Mar 14 13:35:58 CET 2007'
+ },
+ '1835468626573e6189e5302f6f354628f49900efe08adc931990d1c11fd522ef': {
+ header: '####',
+ data: 'Bv0je7USknogpb1ng86CEx6GbHlysuN3e5Iy43kg1iN83AgRm0Hp6/yMivQe/mEmQb+67cjHfKKrznAESYzY8uv3b+ystxoIaQL7tKJ5HYu2NUVvZxRC+PE7AkBhc+O28OzpZEHXXz62uZFsjRDw2hC/KP1XfYW+Deuulnpz6sgjuyWIYXF2486DzaycCqX0NmYXKE7oXAthOlbo+Zsm8Y5MWh5ploJFrzhAm0CCzjsGSa7NBOBWU2o6vN0NFMcOG2pdjZGWpWo1QQ5G9tx9UvM5pTamwcg5TOr4yOd16JmYTDjK2Fd5mdUuG3zIxFR8StIKI/Sd1ah8U+DGbNlVYAVb5OREJxQxVv6I5dxGC43CGWbpx3fB5wuFT3Jek6tv+LgBJaI9Ika79NFJQrLVMFbQgD0qU8YgCmLbxIJ4gxMBUgTN+v6PraIDHleYlpW3KVIiNxv2Ztc=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:24:49 CET 2007',
+ updateDate: 'Wed Mar 14 19:24:49 CET 2007',
+ accessDate: 'Wed Mar 14 19:24:49 CET 2007'
+ },
+ '47f73115ba2079f4b3703f502e3455498900a21941625c25d52ebb7da31055f7': {
+ header: '####',
+ data: 'pK+wAHWg4IJcixnFodLQ5EH+SFQIOMOrthx52u21WZ1ziRWJLSYGwA8CNNK8/welwzPHOPWu2El+zE6cwLHrzmL8EARLvvJ2fEK11ZIvF2C3R06uNrA7QFZr7iu6t67osrpfljqbjKQrMECUCUDrBywRvlpaeIlThfA3XByezK2HtbyHD1/xnyQSenUFu/6Zq1EkVdm9iCkbej2KxZSxA6qMl1WcnplBdOqBSmeGGJ0+Ikn3LZ7t4ztqflsug7QYyQlrmI+d0UB8MFWpf6jYjZQwf1rMH5XHFvrWUCi5IbFNJBUPF3n3IfUlrnjUSBEcW3tmodJa16/biK9/iKqh5ImlnpbQgK7CStgQ8ByJqddJre1idCiK/dyR1z+IXHTu4qm24cJeGUk7la4WMG2O5U/otFbXG5wTVgbLsxfXlE6fzxHAzvEftEE1ZPNOBpRZ+LVYEHKFESIz',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:41:15 CET 2007',
+ updateDate: 'Wed Mar 14 17:41:15 CET 2007',
+ accessDate: 'Wed Mar 14 17:41:15 CET 2007'
+ },
+ '6564169ac5bce1a632c602c51e9e5d637bfd4e87c1fa276e2cf65f39405fc4c9': {
+ header: '####',
+ data: 'fs5hydWDsT/FxWTb57K6zYKwVF310zjHHHtRS/AeBN8XZqTcirhV9oxJW6G6TdDkD7nQfWf53AbsivXn46Tx7oarzoU4R+1mz94TRCkEe5X2X7Wa3HbTj38+QwbkomF7np4MUkVc06aRPqkUE5hvSDbGn4SyKCjo/AnGhuW/QJIqnWVj70tf7CNTb+GR/y41JhJd7yk6U3cIP6Imik+DAvM5pE0KqxGLfLs4c1ChuTFNHfiQbYjs3tANqJCO185t4S8UIY5VxMRcnqgRoloFK3uFACIXoyDGG3FjILgxRCw2ePFsrm2Jtxv+JX4BsM+KDk67OsN91rjQnK5vBP72SzSge4EDCKJXYKdA8KJGYNwRIzk5d5ycbZgW4YCizVw8v7sLMn60v7YrDfBwXAJvvlTP1chA7HoE+WALqXkfBW29AOCNodE3eTXbI7iWz3vcWOCPvSm3hho=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:25:28 CET 2007',
+ updateDate: 'Wed Mar 14 19:25:28 CET 2007',
+ accessDate: 'Thu May 10 15:00:47 CEST 2007'
+ },
+ '7674ea33b650e84f9a461a91928bfc259de5549ce905339fc3b23623c6cfd09e': {
+ header: '####',
+ data: 'D7mLcDpylLnklOtIw/kvYX0M+CR6Si2t8CB9bTT3ZR+bTpXP88OtI19g1k9iPEUPdgbtFKPVw4oNmynP3x+pc8R/zzn4v697SvVtQxdF39Jmry5dnB4SMx6oRkuaISs0nxvTrHJe8U+s5ehzvQ2WWxWZ+LaoBWaYR7slgUFKLdJFyWEalPwMPVu//DoLZeWg19n2C/0Sy8u0DGdYHJVserWrQqxxg0h0m0x1wuKhF7IGvqgyJ31T5w00nMHNZbs89cUuqB/2doMgoUD9BqV7F/53AveuBDcdCc6jlEe8NOdoUyMuhwwwTyKONfjY5e5Cu5W9I36o7GpeKlckoKrTIWFO+NLG8XZvP/f2WJCsIOrCk/LI3C+bxBP+bK4tHRH13iXLeJYUlMK4ibcf8WI445qNoggJSbZzGr7Dav23KZWPcxzRxhI2u6j25/kKGnu4kcMB8ke5N+4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:46:36 CET 2007',
+ updateDate: 'Wed Mar 14 14:46:36 CET 2007',
+ accessDate: 'Wed Mar 14 17:40:01 CET 2007'
+ },
+ 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec': {
+ header: '####',
+ data: 'u9HEcfobxZhG9BY3dVG68ZUYkREFcZ4q1o/xWyt3qje3icA+Nu9yCrZip/4fqe1daUX/MHyzUQdulIfjSwATjj3vvDSPjuGvrtx8oUjJ/K6GFsL366ozi45LkqkOaH02/nVrb+ik2HWIgcne/OzNrwf1mWLJoBF+8ZwQ44xqQK7ikG1mblNWWbZFFQE1B0QPmE/I/1ovm2hAr1ZsNj1l+N96hwGsdsdVFTzn+S7Sg8GTbxEFAxDQkBYEw1k/R8i9EIBndPoDZCebr8vP+c8qSEk/YmBXJ1MGVVvic0/Utn67iNLz9aBnv2z31DvvBj8bIwOxQpB+tom5Ivwe84tFkwwvpxFqYccrEg4bbMcevUo67TBVe+Lb2wzcK0zOr7iHhswbXaLzzOEQ6uF/v2ibTbATP2zNq09AIJjynoSDmrisGHsBrHgeXjiDspc9U70PVC83EsjPRwA=',
+ version: '0.2',
+ creationDate: 'Thu May 10 15:01:21 CEST 2007',
+ updateDate: 'Thu May 10 15:01:21 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:54 CET 2009'
+ },
+ 'e699fa287c2de3d483144b48064a47cd0bc56a436431ce23b48cb8d8c42ce851': {
+ header: '####',
+ data: 'hVD8NOt8g/DIe48JbUUo77e2hMf2UBN6ah23PrIzGTpq0LifC2K/0/s0yeL/PHUOncdT56NccKpF8Fp6EWJqDKoKZPWASuB1vHCEkdbcxlqzqo98VS3A7p2JFwQzSv+5t6y909hhbxobXMCUfZ10HBqGo6TaFc6+pkYqQ/d7MEnj2NuAXC9X9TLLuZSrZ96NCKGr8YVKzxinxHdiF3TdRvIppFByXPlbZ3xiielEnYm6pu/GffW7Hkwd7Vou6jwyggxVqvoVtuAdiIy67l8GX0gQUGipFkvvrAkXfm0sgtWGQvpgDuV/bXq/L5vX/sFpWI2u066lMUOsJQmptNP/Nkp31+ZNk1nCcUIYDDa6vcOy/gRrOFcenPTUQjRkE95KPaCqYBSIWsjoFE0EIB+iBnBCTK3laBSC7pplOtuLCY1YJcJuOkzCVQCVXjhWrNJM77s7a5OyTuE=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 17:43:29 CET 2007',
+ accessDate: 'Wed Mar 14 19:23:51 CET 2007'
+ }
+ }
+ },
+ 'f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732': {
+ data: 'vxOgJv/v3pP8GFqbFLTcgtBqw8V3zhCN9rRXUuWAfatABtr3pySWvt74ITeGw+sDtApBsu+zTY/95BFVtK3y0QJkC5cjJYhLDwvMwpqa0lRfCXWSYmuEhbPETwkW1MN0kAEOMqsUD9cQCH9GDD4A17W89AoTG5Ce//X03YBG0cDjbotgENsWjQpK88LXABHBQAoTF0BPDjN+xai2QPCgN0l1IVpUzI87oZJS7x/4r6DjGTOgcc3+vtEujr+8dGNaq9xTEfAFs1kv6GMeT+R/VkIQLVO+vSxi2fd+954EAXQplt047+aZ3c0c78N6B+GhSi9DgNnbTLu6sl332Zdgo9R09uucS8nvRp3HcTzxriKpx0ZMDh9K9ig5NT9Z2H49pDjCJKTukDU7b2ktOEUNZt58s+uIlw1bMFY1TMETGAHbTq+hld8Szg8f7nJGDQF10kV2ykVEQ2oUBMC9y9VCLyYD0BWId6DUcTNXyI+MqAC4j8pp0NhURY8VSjtnV4Rlq+b48ahP/ifJdq+xrSiT9ykGqc/EyebC1uCTIZewk9MtIAndVYPckMIe0xQ2xhX6/m2bdNboVa3dnS5eKFdbd++un6FD+QAjgtcBkXQnwfptottZoghclKL5h5gPePCQL/66CLYy5+3xctfCG9u+VkH97JKL2hW+XZ/KuxLPFkIAYmbFKsNdIizfpbk5WJvoSzacpo1mwNjZ53zn9xhy/VkSIz3lGl83a6FyoHuR9VklyhTaKrj2JNWzjLaQPiR9Sv2eFNjLTivxtxLwKae5Tz14WU2QlXATC5xdcLeF9nK7yYVarcKlRsYkkvetrVpRiWUVfy9mZQIHOWJtY5AcptKso2Q0v4CuD1C/wV18DMDXzwMXeOq0cKxCsZOuWjO6RwWKzfeZnJ99S+EsFmdI/wxqiu9slJ0xXvgLvjiJhJ03qWwZV45peU1qmvKQrXS80QqLp3kUfRGLbZNOvkZbyf5OK96MA7lok8PuCZGg5jZHFX4B3vxSQ32P7VGSWO5CqHpF45YwtlONZKB0cuvKTRazZ+B2zJfwMYRQloj6sL5501oPqmjVtDg+0aoqKe5DmTf+fHV4FwAxQ8RuW7/BVL+lwf+zjtd31I/yrlDdb/Scs6yayLV026yuHxdQRl+ByogtrXbY4ViuU3NCkVrme7K7meRHnQdXyidhjzHdoJnRPa0IoI4VW3VwWNENRRNDTta2whOdIKsQYtscWBWZnQplRmDChGikERYQVCWejDNgvnbnGrlyQYPF0/vcv6PoDpIvh7Pze9y0MLBU8DnWqAhpdqHPNVdjdq51OKlSitUk5TSN9kxePe0KNFZueLjxZHUFIZ+SIkTxoCoaRWYMJIWvYkcT5S9Y/7NbdapuUaLZNGDc6tgD+LVYRRvGEdPWaOHb7G+qOmdtx8vYxZUqq5mtwnIBRzEllTJyKwwK/kOfAxiRjLxf7SOXsubPuA7bHR9fI5rROSR5rcU+nOfSV9Wf4wZkYBlSmQYqzQfmwl0UCiipJVa1DwYwLimgo2RqhI0M38gEH+mrknnevE8zlUIaEWzxoOnyWbtCecakXS2XvE9j64dswJ3bbeQ3fDQr1308x9qKSjFdDl3eNcJx2e9YwC7wZnTmHeHzRXnZwXsJXqMPDQV99wEDBr71BjlDjMx7vG9bOWrhsyJ37EOvO2X41Ij3j0X4MYpbNgxBFP6zJSu3gILrtqQRpQq6mQJ1bWHyCN1ge1zKNT9pG6rGTRPE9LqHROQuROpgFM1R+DqW4XnGOBYSOtznnsnj5fxfdpGeFq+v/ftvVuN5XsgX6dnT8R77iNUs86Iz2mkxLaQokkNzXl5o1rnQIse9+kcKVZ72mf5SG9s9DD7cZ7bOtmkuZCexJpieIosqLV8jc0IA',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 17:39:39 CET 2007',
+ updateDate: 'Wed Feb 13 15:29:04 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:41 CET 2009',
+ currentVersion: '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74',
+ versions: {
+ '33ce5a03b6d36f59d0fbc9445dd01a515cb56eccc6d854cffbf8aa66f3e4a45f': {
+ header: '####',
+ data: 'pwMmqFOwpW/uSys3hm/AcoERF3eDj4dO+O5SdYsR2mJtmEfXcjhS9altLhVOsck0KMQJdxE3rNDFbduF35yVetXuQrrL+bSRlXMq03EXETyrRzIVhFEM4BjoCSS9nKGgixp04Ve9WSuwD4cXRmcN/L9kCJSCqflXqhkYkjAywQoj1KxHPdAqMaGRpEWioUIfX+NiWbO/qtOu/USAhHmWFXla6/A9kKQeU2d+P3zl9KF2Zm8qm8NXjPKmh2dkd70ATbdzxt9P3BafoRf/Ud8zLIVdQYTbv0pn6UMIiUDRK1ryvgfSY180zg4qkP5pBnxhEgOxbjT8JO6hCl8n2jUCRJLdUXHwgpeuHcKYDyZizc+p9Kbc4+d8K/2UEKgSR6gza6Cpw5TQbZQq+2LxWUoVb3HM3lTqBKUPM0FdY2/3twZm/1bI1uBMPnyp9x/JsQV+xOpu0ZulTA==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:39:39 CET 2007',
+ updateDate: 'Wed Mar 14 17:39:39 CET 2007',
+ accessDate: 'Tue Apr 17 19:09:44 CEST 2007'
+ },
+ '686ea579db132287e8e322194652ec57cba6e60274c00f734db7a0b36702c817': {
+ header: '####',
+ data: 'ilf8U30hSq2mqje9kZkKQAMiEFV0aptXrm8fOtoOR8pp36V29kXyUX6FEOh5eXSRr/jbqGytxKENJeAGxnsv5U+8GgbvlYaR4MPM8lbKcpAoBCc0+CCOiwnp4XCoXFCNttbTzfb6qgR7wqdK7YLnrvfzJieQqJukQZvtWtsVZB/Tis+5niomz8Ca8lo/FjFOIjAq6xtwrW4CS12+yZdTKNbj8e+HwoUcesF9RbCKQlpVHuwhZ/8ghdzDgjEE8z44rDepEv3Lx/aUi+67velLH3j+1crnxBUz7wP/dWzftwWgIxDkCR/vW63yY2Xebt77swDg8g1Qj5OJdYiAq231HKaZjxr10y88JI5HC1EvbbduDN6pknKUgM+qEdojpi2BmjK+9MtV7sVhJoWqwHG8q9z03kgGoFnWEb53HyMVes1n6HYfzwnw+idPFWGZJ4IB25WfJLfQuQ==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:12:39 CEST 2007',
+ updateDate: 'Tue Apr 17 19:12:39 CEST 2007',
+ accessDate: 'Wed Feb 13 15:27:04 CET 2008'
+ },
+ '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74': {
+ header: '####',
+ data: 'l18dnf2TRfinuu9KDraIo41yvG3mNFqiSCOkyMI6WZZD4RnF8R2Ob19fJ8zXv04eDx7TYyyGP1IlFWEdT3LBrOmmbtUmIvtYanIfKTkT6UGHNH2jh1HyHqJbpgIlr67mOm6Es/AgF44BiyJrk5R1y9tA90oeUQynMufiM2MFLpdalDYWEh+W7GV9WCmbBIU/soioTJ1ep2gvy4kJvTSrXENaxHevKfYwn8ucocvY+hjkWB4GWOR40qtaG06wWMLeRsrTBH1jBG9srzbBa4u2IQ0+NJjQrYdiu7nfu6Uyu7Ya/4bxV3Sukao91XvXSFIhcI2OuKl0njUshv6BDEfHwXIQuPtn7KaTx2uYl1pUeTv/tAFvf8Ng9OFNgK0siIMkeg1thFwRiGSmxjP0QZipDtcCekIxj2k=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 15:29:04 CET 2008',
+ updateDate: 'Wed Feb 13 15:29:04 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:41 CET 2009'
+ },
+ '7ee6a662d1980467eea86a58cd7299ee02000740693df2a7ab9dd64347dbbaa4': {
+ header: '####',
+ data: 'ZnwtGdkg72+TQKCJQhZQIqP9sz79FcptnmH8VJEDQY9xTburh4cyhgbgROBis+awp1C5OyiAAoWfPnuRAN8Ai3d9f8M8yjnDGJ4BAJ6OjQ5r4RDQxNycCApXWO3mJpBrx56wMsCVWT6Z8a4khzPrf5HlDtus4lRV4GRdhU9FMpwuaCfgVD38MhlYXDaPgyu/8N+6eQHuFxquXjOJmptfO6tVhP1+/tEHo6iUAX3sXMZAionssRgPllQJxfzrsu7GQk3h66PakRzgStTHUCcdyoEe9c4VnvUgaasTbhENA4x8xPrxjo24zwxfFpWNEb1+pe8N3+dOXTsIdd3CMKrxQ5KkwzyN/Bj9jXNk9YX8PC0geJiR3bCGtPsAd7aEFB7E6y0RVX/RL5f6x0utSYw8mg6lfprlr5A=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 15:28:28 CET 2008',
+ updateDate: 'Wed Feb 13 15:28:28 CET 2008',
+ accessDate: 'Wed Feb 13 15:28:28 CET 2008'
+ },
+ 'c860f9bbcab5fa70854212e18c11a3e9bdc2382f91cfbd25636955c443a05f8e': {
+ header: '####',
+ data: '1rztZ6mKVFVjlL1kEoUsXEMketdElGbOpYK9iy3g1/WeMcTd4D/UjgHvmQHzzNuYJc/yx6cCMMU9dofLe3vWLKhqDAPAVCo49qiH527hP9rQE+0SNO1v2Ymk80hL/gqBfju51bIYxPKAD0uYA+GMX7OdL+S7qdealebERcnVa0K1AHiVU8lu5yIKk55U8zwitk0u86J1zwcraiM3RGXir/x3oZRIKDwT+lhUJPr8GbVjgKlPu07Ii8OdrAGdHefETDlyNnaKPJHTbGXkd3HZ2CYhJCQZGn1Hwfs46iRd5aO+3UErYtgIHl6CXuXd4E+DNW4UJZedP9YV860DBkpqMiQokEMYTh8Y2sOUyf3ZEOshfGvJUhj8O5p7rNm4+2BYO3XhREdV39tn4vUj56wYj+GL5CekEl0c4Mx7ViTQA+gLvk52V2w/5gFyFNQ9U+jUQpb2n+d9cw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:11:33 CEST 2007',
+ updateDate: 'Tue Apr 17 19:11:33 CEST 2007',
+ accessDate: 'Tue Apr 17 19:11:33 CEST 2007'
+ }
+ }
+ },
+ 'fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6': {
+ data: '4zgqvaaWm7nJO09LKN6o5hbWwGzOv7VVmXDu5T+JCHTSOXbteogax2Zrv0uKLkfooGFThJBk0rXfXxE64vMOq3AeHXGw7Chg7hz8Z2Lpjr4FfE6q7Em7UuAlAuL1PiyXXJJK5iSsRY9tkizuYl19aXW+CgpPznYD/PyXgeYxqt9WLqK8cl5iAU87R0cQDhwl16ivzVgiiFeaB6B5FQqWBAHCEgXhqTsaw2gv4snbmPOqcUZbHy/Vb9hv4lPBJwGFNxQzeZUad92VBC8YbIjmbohDsXjteqD2/k1qOgpUB/U5BpyVwsi+5ahgb8gbS+AqYoRDYzkaj83ksPI4JzWyZhpqjhDauaI6M7hGnJ4GB8UZc0M3WPgrlf1r+TXCgpcfembqL1MyteM+C+ItPRP/QdaIXxLOmvGFOBKQYEI7UceUWBCSEzORlS2S2lltlqt+K4B8QTULiKaXCfRmF/u60FpJufIkUX0pE/rQVChxswSWvh7uJFDBIDx8MplTX724A7DN5d4/Ad4Yi2cj3V8X/DEErnHTvirP3tZ2F2oAe7kIdu+JuCqKcMaGB4hVijzv+yim2TCPvrGTFaMmg9PvcWHpik9jEIabCkdqAR8EGIkD29+yvG4vD0DTRKv2vPIfr60ZQnsgs8nlPPoNa6lNHvI/EO0nBGBYBc1TW+syV5h/zOG3rHX0XCHhISZmDMjra7eUETWChncR88P7ciC4yJQtzXFGzeXp2ktzZ8m5g1EQfgtlUVZsHN8e4OQ9DjKt0unfq5RFBj2jlG8TBZn6ZpebxWR2qOxp81KQLHJND9zRTy3h65+k5wo3MnnxE3GbeXg2dFIORRvGUT6bWsqW1fqR/pg1GO8KNtrt3CryZofgE52kuk6hlcmSk9974JR5523+1/hbts8n5VrTi1C6GWhnxpiJb1XIvICdag5g7C2iYppzLKVzbJcFMegwDUrapbmGhkqnGwSY1EQSDyagPr2xlziWhdWdCOVAYcyw8dOpdD97QhVef0OWrJ8nbgFKD6wn21475OFxooheWiMCyZwXqESVG1cVCjeaCsymBtEVPpmQdSkOfMdXpKVF+3osb4K2XDpPeU1zPWVozeMp68YhLztQ/g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 18:43:29 CET 2007',
+ accessDate: 'Mon Jan 19 16:09:30 CET 2009',
+ currentVersion: '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a',
+ versions: {
+ '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a': {
+ header: '####',
+ data: 'QfC77EWgmmnxz9JqLdn9Tw7mNztfQZPdNpaML03EdFpphsjgLloqBRX0UZ21oozjQGHpcUMMOsaJgzCuDlfh7T7ePVV60Ps4AJtzv7bHSVGKsj1iALU1qjtesOYJayp8bA/3peo4HEnVgP86jc5NTwJxpsUhNG0Ae93xVu4lPF0gL0/yjgZUHqYZXkb+oXrcybL0BSOjRnB9fRpA1dEhcwJwoelLTvg7il354qp/Wo+S9Cz5E/K+xnlJAuSXCRXboWea/ZZ9TX88q5uUcY5jLF7Xi2HoFVZw2f5tbycxwGtT1CKXp+OAKn6mQaBAYM51zoMNDT7MvBDXD3v4Cidjgh24GZ2zndfkYT0kHCtY7OVIVSTsXTR+5/XMedojVvDlX9LBa9ST99NLCUy7Di94rJtX72ev3Ei3I1w3qPvCl3jgD2VbIwLogCzqLtY+2IkLAa8M2EpX/D+h',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 18:43:29 CET 2007',
+ accessDate: 'Mon Jan 19 16:09:30 CET 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'syntaxFix': ""
+}
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/Connection.html b/frontend/gamma/tests/tests/Clipperz/PM/Connection.html
new file mode 100644
index 0000000..181a3bf
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/Connection.html
@@ -0,0 +1,71 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.Connection - test</title>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Toll.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.Async.js"></script>
+
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript" src="Connection.data.js"></script>
+<script type="text/javascript" src="Connection.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/Connection.test.js b/frontend/gamma/tests/tests/Clipperz/PM/Connection.test.js
new file mode 100644
index 0000000..e4d0d15
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/Connection.test.js
@@ -0,0 +1,255 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+
+ 'simple_tests': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("simple_tests", {trace:false});
+ deferredResult.addCallback(function() {
+ var connection;
+
+ SimpleTest.is(Clipperz.PM.Connection.communicationProtocol.versions['current'], Clipperz.PM.Connection.SRP['1.1'], "the current connection is 1.1");
+
+ connection = new Clipperz.PM.Connection.communicationProtocol.versions['current']();
+ SimpleTest.ok(connection != null, "can create a connection with the 'current' communication protocol");
+
+ SimpleTest.is(connection.proxy(), Clipperz.PM.Proxy.defaultProxy, "the connection uses the defaultProxy if no proxy is specified on the constructor");
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'simpleProxy_tests': function () {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("simple_tests", {trace:false});
+ deferredResult.addCallback(function() {
+ var connection;
+ var proxy;
+
+ proxy = new Clipperz.PM.Proxy();
+ connection = new Clipperz.PM.Connection.communicationProtocol.versions['current']({proxy:proxy});
+ SimpleTest.is(connection.proxy(), proxy, "the connection uses the specified proxy, when present");
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'login_test': function () {
+ var deferredResult;
+ var connection;
+ var proxy;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, shouldCheckExpectedRequests:true});
+ connection = new Clipperz.PM.Connection.communicationProtocol.versions['current']({
+ proxy: proxy,
+ getCredentialsFunction: function() { return {username:'joe', password:'clipperz'}; }
+ });
+
+ deferredResult = new Clipperz.Async.Deferred("login_tests", {trace:false});
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addCallback(function() {
+ proxy.expectedRequests().unshift({
+ name: "First handshake step",
+ functionName: 'handshake',
+ parameters: {
+ parameters: {
+ message: MochiKit.Base.partial(MochiKit.Base.operator.eq, "connect"),
+ version: MochiKit.Base.partial(MochiKit.Base.operator.eq, "0.2"),
+ parameters: {
+ C: MochiKit.Base.partial(MochiKit.Base.operator.eq, "f527cdd90d0d47f8524b4e165398ad1455eba515d04abd101d1e93b3c6ae0674"),
+ A: MochiKit.Base.operator.truth
+ }
+ }
+ }
+ });
+ });
+ deferredResult.addCallback(function() {
+ proxy.expectedRequests().unshift({
+ name: "Second handshake step",
+ functionName: 'handshake',
+ parameters: {
+ parameters: {
+ message: MochiKit.Base.partial(MochiKit.Base.operator.eq, "credentialCheck"),
+ version: MochiKit.Base.partial(MochiKit.Base.operator.eq, "0.2"),
+ parameters: {
+ M1: MochiKit.Base.operator.truth
+ }
+ }
+ }
+ });
+ });
+ deferredResult.addMethod(connection, 'login'/*, 'joe', 'clipperz'*/);
+ deferredResult.addCallback(function(aResult) {
+ SimpleTest.is(aResult.result, 'done', "successfully logged in");
+ })
+ deferredResult.addErrback(SimpleTest.ok, false, "the login procedure should succeed, and NOT going through this code path");
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'login_with_toll_test': function () {
+ var deferredResult;
+ var connection;
+ var proxy;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, shouldCheckExpectedRequests:true});
+ connection = new Clipperz.PM.Connection.communicationProtocol.versions['current']({
+ proxy:proxy,
+ getCredentialsFunction: function() { return {username:'joe', password:'clipperz'}; }
+ });
+
+ deferredResult = new Clipperz.Async.Deferred("login_with_toll_test", {trace:false});
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addCallback(function() {
+ proxy.expectedRequests().unshift({
+ name: "knock step",
+ functionName: 'knock',
+ parameters: {
+ requestType: MochiKit.Base.partial(MochiKit.Base.operator.eq, "CONNECT")
+ }
+ });
+ });
+ deferredResult.addCallback(function() {
+ proxy.expectedRequests().unshift({
+ name: "First handshake step",
+ functionName: 'handshake',
+ parameters: {
+ parameters: {
+ message: MochiKit.Base.partial(MochiKit.Base.operator.eq, "connect"),
+ version: MochiKit.Base.partial(MochiKit.Base.operator.eq, "0.2"),
+ parameters: {
+ C: MochiKit.Base.partial(MochiKit.Base.operator.eq, "f527cdd90d0d47f8524b4e165398ad1455eba515d04abd101d1e93b3c6ae0674"),
+ A: MochiKit.Base.operator.truth
+ }
+ },
+ toll: {
+ targetValue: MochiKit.Base.operator.truth,
+ toll: MochiKit.Base.operator.truth
+ }
+ }
+ });
+ });
+ deferredResult.addCallback(function() {
+ proxy.expectedRequests().unshift({
+ name: "Second handshake step",
+ functionName: 'handshake',
+ parameters: {
+ parameters: {
+ message: MochiKit.Base.partial(MochiKit.Base.operator.eq, "credentialCheck"),
+ version: MochiKit.Base.partial(MochiKit.Base.operator.eq, "0.2"),
+ parameters: {
+ M1: MochiKit.Base.operator.truth
+ }
+ },
+ toll: {
+ targetValue: MochiKit.Base.operator.truth,
+ toll: MochiKit.Base.operator.truth
+ }
+ }
+ });
+ });
+ deferredResult.addMethod(connection, 'login'/*, 'joe', 'clipperz'*/);
+ deferredResult.addCallback(function(aResult) {
+ SimpleTest.is(aResult.result, 'done', "successfully logged in");
+ })
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getUserDetails_test': function () {
+ var deferredResult;
+ var connection;
+ var proxy;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, shouldCheckExpectedRequests:false});
+ connection = new Clipperz.PM.Connection.communicationProtocol.versions['current']({
+ proxy:proxy,
+ getCredentialsFunction: function() { return {username:'joe', password:'clipperz'}; }
+ });
+
+ deferredResult = new Clipperz.Async.Deferred("getUserDetails_test", {trace:false});
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(connection, 'login'/*, 'joe', 'clipperz'*/);
+ deferredResult.addCallback(function(aResult) {
+ SimpleTest.is(aResult.result, 'done', "successfully logged in");
+ });
+ deferredResult.addMethod(proxy, 'setShouldCheckExpectedRequests', [
+ {
+ name: "Get user details",
+ functionName: 'message',
+ parameters: {
+ parameters: {
+ message: MochiKit.Base.partial(MochiKit.Base.operator.eq, "getUserDetails"),
+ srpSharedSecret: MochiKit.Base.operator.truth
+ },
+ toll: {
+ targetValue: MochiKit.Base.operator.truth,
+ toll: MochiKit.Base.operator.truth
+ }
+ }
+ }
+ ]);
+ deferredResult.addMethod(connection, 'message', 'getUserDetails');
+ deferredResult.addCallback(function(aResult) {
+ SimpleTest.ok(aResult['header'] != null, "got user details - header");
+ SimpleTest.ok(aResult['statistics'] != null, "got user details - statistics");
+ SimpleTest.ok(aResult['version'] == '0.3', "got user details - version");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+//#############################################################################
+
+SimpleTest.runDeferredTests("Clipperz.PM.Connection", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/Crypto.html b/frontend/gamma/tests/tests/Clipperz/PM/Crypto.html
new file mode 100644
index 0000000..f95e994
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/Crypto.html
@@ -0,0 +1,281 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.Crypto - TEST</title>
+
+ <script>
+ jslog_config_enabled = true;
+ clipperz_profiling_enabled = true;
+ </script>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/DOM.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Profile.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.Async.js"></script>
+<!--
+ <script>
+ MochiKit.DOM.addLoadEvent(MochiKit.Base.partial(MochiKit.LoggingPane.createLoggingPane, true));
+ MochiKit.Logging.logger.useNativeConsole = true;
+ </script>
+-->
+</head>
+<body>
+<pre id="test">
+
+<script type="text/javascript">
+
+
+Clipperz_PM_Crypt_test = function() {
+ var key;
+
+ var plainData;
+ var encryptedData;
+ var decryptedData;
+
+ var result;
+ var expectedResult;
+
+ var plainText;
+ var longPlainText;
+
+ key = 'trustno1';
+
+ plainText = "Lorem ipsum dolor sit amet";
+ longPlainText = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec nunc sapien, condimentum vitae, varius vel, pharetra in, augue. Mauris quam magna, pretium sit amet, accumsan id, volutpat lobortis, nibh. Fusce sagittis. Aenean justo. Curabitur euismod pede. Morbi at ante. Proin nisl leo, ultrices sed, facilisis et, nonummy sit amet, lorem. Praesent mauris tellus, pulvinar sed, nonummy vitae, rhoncus non, nunc. Proin placerat malesuada nisl. Nunc id enim. Maecenas commodo enim ac nibh. Sed condimentum, urna sit amet euismod gravida, mi urna varius odio, luctus pretium lectus justo nec felis. Ut in augue et est malesuada rhoncus. Sed vel orci. Mauris suscipit. Praesent cursus velit non turpis. Donec tristique dolor ac est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla est sapien, vulputate eget, bibendum id, pharetra nec, mauris. Aliquam faucibus tincidunt dui. Proin iaculis. Maecenas sagittis. Integer et augue. Donec vitae urna in orci aliquet commodo. Vestibulum lorem sem, suscipit ac, placerat nec, mollis in, felis. Donec laoreet odio a mauris. Integer rutrum, sapien id varius molestie, mauris odio egestas orci, non bibendum sem felis in metus. Phasellus consectetuer lectus adipiscing mauris. Ut magna tellus, euismod ac, suscipit tincidunt, ullamcorper adipiscing, massa. Etiam orci. Phasellus a urna. Cras neque quam, laoreet at, tempus eget, euismod nec, nibh. Etiam hendrerit. Aenean vel lorem. Ut ligula lacus, congue eu, lobortis sit amet, venenatis in, magna. Nullam cursus felis quis est. Sed sem est, condimentum eu, vestibulum a, mattis vel, diam. Curabitur tincidunt pede quis pede. Sed neque diam, convallis vel, luctus at, porta id, nisl. Suspendisse potenti. Sed volutpat lobortis orci. Praesent mi. In interdum. Suspendisse suscipit ipsum eget dolor. Curabitur et tellus sed velit hendrerit varius. Cras sit amet est. Donec arcu nulla, vehicula et, pretium in, placerat id, felis. Integer mollis auctor lectus. Integer ultrices elementum sapien. Nam et erat. Nam pulvinar porta tortor. Nam at risus. Quisque nulla. Integer vestibulum, lacus id bibendum laoreet, ligula mi pharetra lorem, sit amet pharetra felis mauris quis justo. Aliquam ultricies. Duis a pede eget lorem dapibus rhoncus. Aenean eu elit non libero consectetuer viverra. Maecenas velit mi, eleifend vel, malesuada vel, condimentum quis, odio. Mauris tempus augue sed turpis. Pellentesque condimentum, lacus vitae pellentesque ultricies, risus tellus posuere nisi, et dictum turpis pede nec elit. Sed eu lectus eu justo sagittis euismod. Vestibulum lobortis, urna id mollis rhoncus, orci quam euismod ligula, at malesuada lacus magna vitae massa. Phasellus mattis fermentum velit. Nulla vulputate consequat enim. Maecenas quis neque. Curabitur sagittis facilisis neque. In elementum, eros non porttitor rhoncus, libero turpis sodales odio, vitae porta tellus purus et ante. Nullam molestie sollicitudin metus. Donec a elit. Morbi ut lacus. Donec at arcu. Quisque velit diam, interdum a, lacinia at, varius et, odio. Cras neque magna, ornare id, sollicitudin id, consequat a, est. Phasellus vestibulum est at leo. Nam facilisis, nulla dapibus condimentum pellentesque, est magna viverra ligula, at sollicitudin urna augue ut sapien. Fusce justo.";
+
+ //
+ // hashing
+ //
+ plainData = new Clipperz.ByteArray(plainText);
+
+ result = Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].hash(plainData);
+ is(result.length(), (256/8), "encryptingFunctions.versions[0.1].hash generate a 256 bit signature with a short text");
+
+ result = Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].hash(plainData);
+ is(result.length(), (256/8), "encryptingFunctions.versions[0.2].hash generate a 256 bit signature with a short text");
+
+
+ plainData = new Clipperz.ByteArray(longPlainText);
+
+ result = Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].hash(plainData);
+ is(result.length(), (256/8), "encryptingFunctions.versions[0.1].hash generate a 256 bit signature with a long text");
+
+ result = Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].hash(plainData);
+ is(result.length(), (256/8), "encryptingFunctions.versions[0.2].hash generate a 256 bit signature with a long text");
+
+
+ //
+ // encrypting / decripting
+ //
+ plainData = plainText;
+
+ encryptedData = Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].encrypt(key, plainData);
+ decryptedData = Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].decrypt(key, encryptedData);
+ is(plainData.toString(), decryptedData.toString(), "encryptingFunctions.versions[0.1] of encrypt/decrypt functions work with a short text");
+
+ encryptedData = Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].encrypt(key, plainData);
+ decryptedData = Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].decrypt(key, encryptedData);
+ is(plainData.toString(), decryptedData.toString(), "encryptingFunctions.versions[0.2] of encrypt/decrypt functions work with a short text");
+
+//console.time("encrypt-256-short");
+ encryptedData = Clipperz.PM.Crypto.encryptingFunctions.versions['0.3'].encrypt(key, plainData);
+//console.timeEnd("encrypt-256-short");
+//console.time("decrypt-256-short");
+ decryptedData = Clipperz.PM.Crypto.encryptingFunctions.versions['0.3'].decrypt(key, encryptedData);
+//console.timeEnd("decrypt-256-short");
+ is(plainData.toString(), decryptedData.toString(), "encryptingFunctions.versions[0.3] of encrypt/decrypt functions work with a short text");
+
+
+ plainData = longPlainText + longPlainText + longPlainText + longPlainText + longPlainText + longPlainText + longPlainText + longPlainText;
+
+/*
+ encryptedData = Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].encrypt(key, plainData);
+ decryptedData = Clipperz.PM.Crypto.encryptingFunctions.versions['0.1'].decrypt(key, encryptedData);
+ is(plainData, decryptedData, "encryptingFunctions.versions[0.1] of encrypt/decrypt functions work with a long text");
+
+ encryptedData = Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].encrypt(key, plainData);
+ decryptedData = Clipperz.PM.Crypto.encryptingFunctions.versions['0.2'].decrypt(key, encryptedData);
+ is(plainData, decryptedData, "encryptingFunctions.versions[0.2] of encrypt/decrypt functions work with a long text");
+
+ encryptedData = Clipperz.PM.Crypto.encryptingFunctions.versions['0.3'].encrypt(key, plainData);
+ decryptedData = Clipperz.PM.Crypto.encryptingFunctions.versions['0.3'].decrypt(key, encryptedData);
+ is(plainData, decryptedData, "encryptingFunctions.versions[0.3] of encrypt/decrypt functions work with a long text");
+*/
+
+ {
+ var deferredResult;
+ var startTime;
+// var nonce;
+
+// nonce = new Clipperz.ByteArray("0x00000000000000000000000000000000");
+ plainData = plainData + plainData + plainData + plainData + plainData + plainData + plainData + plainData;
+MochiKit.Logging.logDebug("plainData length: " + plainData.length);
+ startTime = new Date();
+
+ deferredResult = new MochiKit.Async.Deferred();
+
+ deferredResult.addCallback(function() {
+ return Clipperz.PM.Crypto.deferredEncrypt({key:key, value:plainData, version:'0.3'});
+// return Clipperz.PM.Crypto.encrypt(key, plainData, '0.3' / *Clipperz.PM.Crypto.encryptingFunctions.currentVersion* /);
+ });
+ deferredResult.addCallback(function(aResult) {
+ MochiKit.Logging.logDebug("encrypting: " + (new Date() - startTime));
+ startTime = new Date();
+ return aResult;
+ });
+ deferredResult.addCallback(MochiKit.Async.wait, 1);
+ deferredResult.addCallback(function(aResult) {
+ MochiKit.Logging.logDebug("pause: " + (new Date() - startTime));
+ startTime = new Date();
+ return aResult;
+ });
+ deferredResult.addCallback(function(anEncryptedValue) {
+ return Clipperz.PM.Crypto.deferredDecrypt({key:key, value:anEncryptedValue, version:'0.3'});
+ });
+ deferredResult.addCallback(function(aResult) {
+ MochiKit.Logging.logDebug("decrypting: " + (new Date() - startTime));
+ startTime = new Date();
+ return aResult;
+ });
+ deferredResult.addCallback(MochiKit.Async.wait, 1);
+ deferredResult.addBoth(function(aDecryptedValue) {
+ is(plainData, aDecryptedValue, "deferredEncript/deferredDecript functions work with a long text");
+ });
+
+
+
+/*
+ deferredResult.addCallback(function(aResult) {
+ var i,c;
+ var currentChar;
+ var unicode;
+
+ unicode = 150;
+
+ c = 100000;
+ startTime = new Date();
+ for (i=0; i<c; i++) {
+ currentChar = String.fromCharCode(unicode+1);
+ }
+ MochiKit.Logging.logDebug("String.fromCharCode: " + (new Date() - startTime));
+ });
+
+ deferredResult.addCallback(function(aResult) {
+ var i,c;
+ var currentByte;
+ var unicode;
+
+ currentByte = 150;
+
+ c = 100000;
+ startTime = new Date();
+ for (i=0; i<c; i++) {
+ unicode = (currentByte & 0x0f) << (6+6);
+ }
+ MochiKit.Logging.logDebug("(currentByte & 0x0f) << (6+6): " + (new Date() - startTime));
+ });
+
+ deferredResult.addCallback(function(aResult) {
+ var i,c;
+ var currentByte;
+ var byteArray;
+
+ currentByte = 150;
+
+ byteArray = new Clipperz.ByteArray(plainData);
+ c = byteArray.length();
+ startTime = new Date();
+ for (i=0; i<c; i++) {
+ currentByte = byteArray.byteAtIndex(i);
+ }
+ MochiKit.Logging.logDebug("byteAtIndex: " + (new Date() - startTime));
+ });
+*/
+
+ deferredResult.addBoth(function() {
+ SimpleTest.ok(true, "COMPLETED all tests");
+ SimpleTest.finish();
+ })
+
+ deferredResult.callback();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+}
+
+//#############################################################################
+
+try {
+ MochiKit.Signal.connect(Clipperz.Crypto.PRNG.defaultRandomGenerator(), 'readyToGenerateRandomBytes', Clipperz_PM_Crypt_test);
+
+ Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+ SimpleTest.waitForExplicitFinish();
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/Crypto_performanceEvaluation.html b/frontend/gamma/tests/tests/Clipperz/PM/Crypto_performanceEvaluation.html
new file mode 100644
index 0000000..094a58d
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/Crypto_performanceEvaluation.html
@@ -0,0 +1,153 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.Crypt - Performance evaluation - TEST</title>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+
+<!--< script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES_other_implementation.js'>< /script> -->
+
+</head>
+<body>
+<pre id="test">
+
+<script type="text/javascript">
+
+try {
+ var key;
+ var shortText;
+ var longText;
+ var veryLongText;
+ var byteArray;
+ var plainText;
+ var encryptedText;
+ var decryptedText;
+ var startTime, endTime;
+ var startTime1, endTime1;
+ var ClipperzCryptoVersion;
+ var i,c;
+
+ ClipperzCryptoVersion = '0.3';
+ Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+ key = 'trustno1';
+
+ shortText = "Lorem ipsum dolor sit amet";
+ longText = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec nunc sapien, condimentum vitae, varius vel, pharetra in, augue. Mauris quam magna, pretium sit amet, accumsan id, volutpat lobortis, nibh. Fusce sagittis. Aenean justo. Curabitur euismod pede. Morbi at ante. Proin nisl leo, ultrices sed, facilisis et, nonummy sit amet, lorem. Praesent mauris tellus, pulvinar sed, nonummy vitae, rhoncus non, nunc. Proin placerat malesuada nisl. Nunc id enim. Maecenas commodo enim ac nibh. Sed condimentum, urna sit amet euismod gravida, mi urna varius odio, luctus pretium lectus justo nec felis. Ut in augue et est malesuada rhoncus. Sed vel orci. Mauris suscipit. Praesent cursus velit non turpis. Donec tristique dolor ac est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla est sapien, vulputate eget, bibendum id, pharetra nec, mauris. Aliquam faucibus tincidunt dui. Proin iaculis. Maecenas sagittis. Integer et augue. Donec vitae urna in orci aliquet commodo. Vestibulum lorem sem, suscipit ac, placerat nec, mollis in, felis. Donec laoreet odio a mauris. Integer rutrum, sapien id varius molestie, mauris odio egestas orci, non bibendum sem felis in metus. Phasellus consectetuer lectus adipiscing mauris. Ut magna tellus, euismod ac, suscipit tincidunt, ullamcorper adipiscing, massa. Etiam orci. Phasellus a urna. Cras neque quam, laoreet at, tempus eget, euismod nec, nibh. Etiam hendrerit. Aenean vel lorem. Ut ligula lacus, congue eu, lobortis sit amet, venenatis in, magna. Nullam cursus felis quis est. Sed sem est, condimentum eu, vestibulum a, mattis vel, diam. Curabitur tincidunt pede quis pede. Sed neque diam, convallis vel, luctus at, porta id, nisl. Suspendisse potenti. Sed volutpat lobortis orci. Praesent mi. In interdum. Suspendisse suscipit ipsum eget dolor. Curabitur et tellus sed velit hendrerit varius. Cras sit amet est. Donec arcu nulla, vehicula et, pretium in, placerat id, felis. Integer mollis auctor lectus. Integer ultrices elementum sapien. Nam et erat. Nam pulvinar porta tortor. Nam at risus. Quisque nulla. Integer vestibulum, lacus id bibendum laoreet, ligula mi pharetra lorem, sit amet pharetra felis mauris quis justo. Aliquam ultricies. Duis a pede eget lorem dapibus rhoncus. Aenean eu elit non libero consectetuer viverra. Maecenas velit mi, eleifend vel, malesuada vel, condimentum quis, odio. Mauris tempus augue sed turpis. Pellentesque condimentum, lacus vitae pellentesque ultricies, risus tellus posuere nisi, et dictum turpis pede nec elit. Sed eu lectus eu justo sagittis euismod. Vestibulum lobortis, urna id mollis rhoncus, orci quam euismod ligula, at malesuada lacus magna vitae massa. Phasellus mattis fermentum velit. Nulla vulputate consequat enim. Maecenas quis neque. Curabitur sagittis facilisis neque. In elementum, eros non porttitor rhoncus, libero turpis sodales odio, vitae porta tellus purus et ante. Nullam molestie sollicitudin metus. Donec a elit. Morbi ut lacus. Donec at arcu. Quisque velit diam, interdum a, lacinia at, varius et, odio. Cras neque magna, ornare id, sollicitudin id, consequat a, est. Phasellus vestibulum est at leo. Nam facilisis, nulla dapibus condimentum pellentesque, est magna viverra ligula, at sollicitudin urna augue ut sapien. Fusce justo.";
+ veryLongText = "";
+ c = 100;
+ for (i=0; i<100; i++) {
+ veryLongText += longText;
+ }
+ nonce = new Clipperz.ByteArray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+
+
+ //--------------------------------------------------------------
+ //
+ // longText encryption performance
+ //
+ //--------------------------------------------------------------
+
+ plainText = longText;
+
+startTime = new Date();
+ encryptedText = Clipperz.PM.Crypto.encryptingFunctions.versions[ClipperzCryptoVersion].encrypt(key, plainText, nonce);
+endTime = new Date();
+//console.log("[1] encryption time: " + (endTime - startTime));
+ is((endTime - startTime < 350), true, "[1] Need to improve some more (" + (endTime - startTime) + ")");
+ is(encryptedText, "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", "encrypted text");
+ decryptedText = Clipperz.PM.Crypto.encryptingFunctions.versions[ClipperzCryptoVersion].decrypt(key, encryptedText);
+ is(decryptedText, plainText, "encrypt <-> decrypt works (specifying the nonce)");
+
+startTime = new Date();
+ encryptedText = Clipperz.PM.Crypto.encryptingFunctions.versions[ClipperzCryptoVersion].encrypt(key, plainText);
+endTime = new Date();
+//console.log("[2] encryption time: " + (endTime - startTime));
+ is((endTime - startTime < 350), true, "[2] Need to improve some more (" + (endTime - startTime) + ")");
+ decryptedText = Clipperz.PM.Crypto.encryptingFunctions.versions[ClipperzCryptoVersion].decrypt(key, encryptedText);
+ is(decryptedText, plainText, "encrypt <-> decrypt works");
+
+ //--------------------------------------------------------------
+ //
+ // veryLongText encryption performance
+ //
+ //--------------------------------------------------------------
+/*
+ plainText = veryLongText;
+
+startTime = new Date();
+ encryptedText = Clipperz.PM.Crypto.encryptingFunctions.versions[ClipperzCryptoVersion].encrypt(key, plainText);
+endTime = new Date();
+//console.log("[3] encryption time: " + (endTime - startTime));
+ is((endTime - startTime < 35000), true, "[3] Need to improve some more (" + (endTime - startTime) + ")");
+ decryptedText = Clipperz.PM.Crypto.encryptingFunctions.versions[ClipperzCryptoVersion].decrypt(key, encryptedText);
+ is(decryptedText, plainText, "encrypt <-> decrypt works");
+*/
+
+//#############################################################################
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/Crypto_test.html b/frontend/gamma/tests/tests/Clipperz/PM/Crypto_test.html
new file mode 100644
index 0000000..f5b0a60
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/Crypto_test.html
@@ -0,0 +1,169 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.Crypto - TEST</title>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/DOM.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+
+
+<!-- ================================================================================ --> <script>
+//MochiKit.DOM.addLoadEvent(MochiKit.Base.partial(MochiKit.LoggingPane.createLoggingPane, true));
+//MochiKit.Logging.logger.useNativeConsole = true;
+
+//-----------------------------------------------------------------------------
+
+encodePassword = function (anEvent) {
+ var username;
+ var password;
+ var encodedPassword;
+ var srpConnection;
+
+ anEvent.stop();
+
+ srpConnection = new Clipperz.PM.Connection.SRP['1.1']();
+
+ username = MochiKit.DOM.getElement('username').value;
+ passphrase = MochiKit.DOM.getElement('passphrase').value;
+ encodedPassword = srpConnection.normalizedCredentials({'username':username , 'password':passphrase })['password'];
+
+ MochiKit.DOM.getElement('encodedPassword').value = encodedPassword;
+}
+
+//-----------------------------------------------------------------------------
+
+decryptData = function (anEvent) {
+ var deferredResult;
+ var key;
+ var version;
+ var value;
+
+ key = MochiKit.DOM.getElement('key').value;
+ version = MochiKit.DOM.getElement('version').value;
+ value = MochiKit.DOM.getElement('encryptedText').value;
+
+ anEvent.stop();
+
+ deferredResult = new Clipperz.Async.Deferred("Decrypted data", {trace:false});
+ deferredResult.addCallback(Clipperz.PM.Crypto.deferredDecrypt, {key:key, version:version, value:value});
+ deferredResult.addCallback(Clipperz.Base.serializeJSON);
+ deferredResult.addCallback(function (aValue) {
+ MochiKit.DOM.getElement('decryptedText').value = aValue;
+ });
+ deferredResult.addErrback(alert);
+
+ deferredResult.callback();
+}
+
+//-----------------------------------------------------------------------------
+
+encryptData = function (anEvent) {
+ var deferredResult;
+ var key;
+ var version;
+ var value;
+
+ key = MochiKit.DOM.getElement('key').value;
+ version = MochiKit.DOM.getElement('version').value;
+ value = Clipperz.Base.evalJSON(MochiKit.DOM.getElement('decryptedText').value);
+
+ anEvent.stop();
+
+ deferredResult = new Clipperz.Async.Deferred("Encrypted data", {trace:false});
+ deferredResult.addCallback(Clipperz.PM.Crypto.deferredEncrypt, {key:key, version:version, value:value});
+ deferredResult.addCallback(function (aValue) {
+ MochiKit.DOM.getElement('encryptedText').value = aValue;
+ });
+ deferredResult.addErrback(alert);
+
+ deferredResult.callback();
+}
+
+//-----------------------------------------------------------------------------
+
+init = function () {
+ Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+
+
+ MochiKit.Signal.connect('decryptForm', 'onsubmit', decryptData)
+ MochiKit.Signal.connect('decryptButton', 'onclick', decryptData)
+ MochiKit.Signal.connect('encryptButton', 'onclick', encryptData)
+
+// MochiKit.Signal.connect('encodePassword', 'onclick', encodePassword)
+}
+
+//-----------------------------------------------------------------------------
+
+MochiKit.DOM.addLoadEvent(init);
+
+</script> <!-- =============================================================================== -->
+
+</head>
+<body>
+<!--
+ <form id='computeKey'>
+ <input type='text' name='username' value='' id='username' size='30'/>
+ <input type='text' name='passphrase' value='' id='passphrase' size='30'/>
+ <input type='button' name='encode' value='encode' id='encodePassword'>
+ <input type='text' name='encodedPassword' value='' id='encodedPassword' size='30'/>
+ </form>
+ <hr>
+-->
+ <form id='decryptForm'>
+ <div><textarea id='encryptedText' cols='80' rows='20'></textarea></div>
+ <div><input type='text' name='key' value='' id='key' size='30'/></div>
+ <div><input type='text' name='version' value='0.3' id='version' /></div>
+ <div><input type='button' name='decrypt' value='decrypt' id='decryptButton'> <input type='button' name='encrypt' value='encrypt' id='encryptButton'></div>
+ <hr>
+ <div><textarea id='decryptedText' cols='80' rows='20' style="background-color: lightgrey;">&lt;result&gt;</textarea></div>
+ </form>
+
+</body>
+</html> \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLogin.html b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLogin.html
new file mode 100644
index 0000000..e11adfd
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLogin.html
@@ -0,0 +1,103 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.DataModel.DirectLogin - test</title>
+
+ <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Toll.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script>
+
+ <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script>
+<script>
+ Clipperz_IEisBroken = false;
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+Clipperz_normalizedNewLine = '\x0d\x0a';
+</script><![endif]-->
+
+</head>
+<body>
+
+<pre id="test">
+<script>
+ Clipperz.PM.Strings.Languages.setSelectedLanguage('en-us');
+</script>
+<script type="text/javascript" src="User.data.js"></script>
+<script type="text/javascript" src="User.data.old.js"></script>
+<script type="text/javascript" src="DirectLogin.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLogin.test.js b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLogin.test.js
new file mode 100644
index 0000000..d385c8c
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLogin.test.js
@@ -0,0 +1,195 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+
+var tests = {
+
+/*
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ ...
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+
+
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+ ...
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'getRecord', '5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4'); // WEB PASSWORD (0)
+ deferredResult.addMethod(user, 'getRecord', '36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113'); // DIGG (1)
+ deferredResult.addMethod(user, 'getRecord', 'c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065'); // SAP (2)
+ deferredResult.addMethod(user, 'getRecord', 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'); // YAHOO (4)
+ DirectLogin references
+ - dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496 // Yahoo! Mail
+ - aa18149164302d5dbe7e2d3724565b9550e00887b49978559783b2e38c625584 // (Yahoo! Groups)
+ - 6f7bbc4e42ea462b5246e6f51c3f86056bec50601ce2de6067c8c1d26f21c07f // (Flickr)
+ - a7b32e72502804bf2946a2a8856139cbbb759c5777e6b3e673db1fdf7e3bd06e // (My Yahoo!)
+*/
+ //-------------------------------------------------------------------------
+
+ 'editDirectLoginLabel_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("editDirectLoginLabel_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addMethod(user, 'getRecord', 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'); // YAHOO (4)
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496'));
+ deferredResult.addCallback(function (aDirectLogin) {
+ var innerDeferredResult;
+ var updatedLabel;
+
+ updatedLabel = "updated Yahoo! Mail label";
+
+ innerDeferredResult = new Clipperz.Async.Deferred("editDirectLoginLabel_test <inner>", someTestArgs);
+ innerDeferredResult.addMethod(aDirectLogin, 'label');
+ innerDeferredResult.addTest("Yahoo! Mail", "The label of the selected direct login is correct.");
+ innerDeferredResult.addMethod(aDirectLogin, 'setLabel', updatedLabel);
+
+ innerDeferredResult.addMethod(aDirectLogin, 'label');
+ innerDeferredResult.addTest(updatedLabel, "The DirectLogin returns the correct label even before committing data.");
+
+ innerDeferredResult.addMethod(user, 'hasPendingChanges');
+ innerDeferredResult.addTest(true, "When changing the label of a DirectLogin, the user should report pending changes.");
+
+//innerDeferredResult.addCallback(function () { console.log("+_+_+_+_+_+_+_+_+_+_+_+ >>>")});
+ innerDeferredResult.addMethod(user, 'saveChanges');
+//innerDeferredResult.addCallback(function () { console.log("+_+_+_+_+_+_+_+_+_+_+_+ <<<")});
+ innerDeferredResult.addMethod(user, 'hasPendingChanges');
+ innerDeferredResult.addTest(false, "After saving changes there should be no pending changes left.");
+
+ innerDeferredResult.addMethod(aDirectLogin, 'label');
+ innerDeferredResult.addTest(updatedLabel, "The DirectLogin returns the correct label even after committing data.");
+
+ innerDeferredResult.callback();
+
+ return innerDeferredResult;
+ })
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'editDirectLoginLabel_thanResetItToThePreviousValue_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("editDirectLoginLabel_thanResetItToThePreviousValue_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addMethod(user, 'getRecord', 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'); // YAHOO (4)
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496'));
+ deferredResult.addCallback(function (aDirectLogin) {
+ var innerDeferredResult;
+ var originalLabel;
+ var updatedLabel;
+
+ originalLabel = "Yahoo! Mail";
+ updatedLabel = "updated Yahoo! Mail label";
+
+ innerDeferredResult = new Clipperz.Async.Deferred("editDirectLoginLabel_thanResetItToThePreviousValue_test <inner>", someTestArgs);
+ innerDeferredResult.addMethod(aDirectLogin, 'label');
+ innerDeferredResult.addTest(originalLabel, "The label of the selected direct login is correct.");
+ innerDeferredResult.addMethod(aDirectLogin, 'setLabel', updatedLabel);
+
+ innerDeferredResult.addMethod(aDirectLogin, 'label');
+ innerDeferredResult.addTest(updatedLabel, "The DirectLogin returns the correct label even before committing data.");
+
+ innerDeferredResult.addMethod(user, 'hasPendingChanges');
+ innerDeferredResult.addTest(true, "When changing the label of a DirectLogin, the user should report pending changes [2].");
+
+ innerDeferredResult.addMethod(aDirectLogin, 'setLabel', originalLabel);
+
+ innerDeferredResult.addMethod(aDirectLogin, 'hasPendingChanges');
+ innerDeferredResult.addTest(false, "Restoring the original label, the directLogin should report no pending changes.");
+
+ innerDeferredResult.addMethod(aDirectLogin.record(), 'hasPendingChanges');
+ innerDeferredResult.addTest(false, "Restoring the original label, the record should report no pending changes.");
+
+ innerDeferredResult.addMethod(user, 'hasPendingChanges');
+ innerDeferredResult.addTest(false, "Restoring the original label, the user should report no pending changes.");
+
+ innerDeferredResult.callback();
+
+ return innerDeferredResult;
+ })
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'bindingValues_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("DirectLogin.bindingValues_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addMethod(user, 'getRecord', 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'); // YAHOO (4)
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496'));
+ deferredResult.addMethodcaller('bindingValues');
+ deferredResult.addCallback(function (someBindingValues) {
+ SimpleTest.is(MochiKit.Base.keys(someBindingValues).length, 2, "there should be 2 bindings for this direct login");
+ SimpleTest.is(someBindingValues['login'], 'joe.clipperz', "the login field should be filled with 'joe.clipperz'");
+ SimpleTest.is(someBindingValues['passwd'], 'enfvDG1RxAsl', "the passwd field should be filled with 'enfvDG1RxAsl'");
+ })
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+*/
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+//#############################################################################
+
+SimpleTest.runDeferredTests("Clipperz.PM.DataModel.DirectLogin", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLoginConfigurations.data.js b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLoginConfigurations.data.js
new file mode 100644
index 0000000..6c0bf49
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/DirectLoginConfigurations.data.js
@@ -0,0 +1,33 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+directLoginConfigurations = {
+ 'Yahoo! Mail': '{\n "page": {\n "title": "Yahoo! Mail"\n },\n "form": {\n "attributes": {\n "action": "https://login.yahoo.com/config/login?",\n "method": "post"\n },\n "inputs": [\n {\n "type": "hidden",\n "name": ".tries",\n "value": "1"\n },\n {\n "type": "hidden",\n "name": ".src",\n "value": "ym"\n },\n {\n "type": "hidden",\n "name": ".md5",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".hash",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".js",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".last",\n "value": ""\n },\n {\n "type": "hidden",\n "name": "promo",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".intl",\n "value": "us"\n },\n {\n "type": "hidden",\n "name": ".bypass",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".partner",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".u",\n "value": "5gp62cl2vg3ov"\n },\n {\n "type": "hidden",\n "name": ".v",\n "value": "0"\n },\n {\n "type": "hidden",\n "name": ".challenge",\n "value": "iBEY0IK6k3t9Uals32mrTos8s48p"\n },\n {\n "type": "hidden",\n "name": ".yplus",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".emailCode",\n "value": ""\n },\n {\n "type": "hidden",\n "name": "pkg",\n "value": ""\n },\n {\n "type": "hidden",\n "name": "stepid",\n "value": ""\n },\n {\n "type": "hidden",\n "name": ".ev",\n "value": ""\n },\n {\n "type": "hidden",\n "name": "hasMsgr",\n "value": "0"\n },\n {\n "type": "hidden",\n "name": ".chkP",\n "value": "Y"\n },\n {\n "type": "hidden",\n "name": ".done",\n "value": "http://mail.yahoo.com"\n },\n {\n "type": "hidden",\n "name": ".pd",\n "value": "ym_ver%3d0%26c="\n },\n {\n "type": "text",\n "name": "login",\n "value": ""\n },\n {\n "type": "password",\n "name": "passwd",\n "value": ""\n },\n {\n "type": "checkbox",\n "name": ".persistent",\n "value": "y"\n },\n {\n "type": "submit",\n "name": ".save",\n "value": "Sign In"\n }\n ]\n },\n "version": "0.2"\n}',
+ 'Parallels': '{"page": {"title": "Parallels Account"},\n"form": {"attributes": {"action": "https://www.parallels.com/account/",\n"method": "post"},\n"inputs": [{"type": "text",\n"name": "Email",\n"value": ""},\n{"type": "password",\n"name": "Password",\n"value": ""}]},\n"version": "0.2.3"}',
+ __syntaxFix__: "syntax fix"
+}; \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/EncryptedRemoteObject.html b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/EncryptedRemoteObject.html
new file mode 100644
index 0000000..699c06d
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/EncryptedRemoteObject.html
@@ -0,0 +1,66 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.DataModel.EncryptedRemoteObject - test</title>
+
+ <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
+ <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script>
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript" src="EncryptedRemoteObject.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/EncryptedRemoteObject.test.js b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/EncryptedRemoteObject.test.js
new file mode 100644
index 0000000..0a4fe0c
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/EncryptedRemoteObject.test.js
@@ -0,0 +1,225 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+
+ 'simple_tests': function(someTestArgs) {
+ var deferredResult;
+ var encryptedRemoteObject;
+
+ var key;
+ var version;
+ var rawData;
+
+ key = "just a random key";
+ version = Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
+ rawData = "just a random text to encrypt";
+
+ encryptedRemoteObject = new Clipperz.PM.DataModel.EncryptedRemoteObject({
+ 'retrieveKeyFunction': MochiKit.Base.noop,
+ 'retrieveRemoteDataFunction': function () { return "--"},
+ 'encryptedDataKeypath': '--',
+ 'encryptedVersionKeypath': '--'
+ });
+ SimpleTest.ok(encryptedRemoteObject != null, "create an encryptedRemoteObject");
+
+ deferredResult = Clipperz.Async.callbacks("EncryptedRemoteObject.test - simple_tests", [
+ MochiKit.Base.method(encryptedRemoteObject, 'getRemoteData'),
+ function(aResult) {
+ SimpleTest.is(aResult, "--", "setting and getting serverData works");
+ }
+ ], someTestArgs);
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'decrypt_test': function (someTestArgs) {
+ var deferredResult;
+ var encryptedRemoteObject;
+ var key;
+ var version;
+ var rawData;
+
+ key = "just a random key";
+ version = Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
+ rawData = "just a random text to encrypt";
+
+ encryptedRemoteObject = new Clipperz.PM.DataModel.EncryptedRemoteObject({
+ 'retrieveKeyFunction': MochiKit.Base.partial(MochiKit.Async.succeed, key),
+ 'retrieveRemoteDataFunction': MochiKit.Base.partial(Clipperz.Async.callbacks, "EncryptedRemoteObject.test - decrypt_test <encrypt data>", [
+ MochiKit.Base.partial(Clipperz.PM.Crypto.deferredEncrypt, {key:key, value:rawData, version:version}),
+ function (someEncryptedData) {
+ return {
+ 'data': someEncryptedData,
+ 'version': version
+ }
+ }
+ ], someTestArgs)//,
+// 'encryptedDataKeypath': 'data',
+// 'encryptedVersionKeypath': 'version'
+ });
+
+ deferredResult = new Clipperz.Async.Deferred("decrypt_test", someTestArgs);
+ deferredResult.addMethod(encryptedRemoteObject, 'getDecryptedData');
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.is(aResult, rawData, "encrypt and decrypt works");
+ })
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getValue_test': function (someTestArgs) {
+ var deferredResult;
+ var encryptedRemoteObject;
+ var key;
+ var version;
+ var rawData;
+
+ key = "just a random key";
+ version = Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
+ rawData = {
+ key1: 'value1',
+ key2: 'value2'
+ };
+
+ encryptedRemoteObject = new Clipperz.PM.DataModel.EncryptedRemoteObject({
+ 'reference': "testReference",
+ 'retrieveKeyFunction': MochiKit.Base.partial(MochiKit.Async.succeed, key),
+ 'retrieveRemoteDataFunction': MochiKit.Base.partial(Clipperz.Async.callbacks, "EncryptedRemoteObject.test - decrypt_test <encrypt data>", [
+ MochiKit.Base.partial(Clipperz.PM.Crypto.deferredEncrypt, {key:key, value:rawData, version:version}),
+ function (someEncryptedData) {
+ return {
+ 'data': someEncryptedData,
+ 'version': version
+ }
+ }
+ ], someTestArgs)//,
+// 'encryptedDataKeypath': 'data',
+// 'encryptedVersionKeypath': 'version'
+ });
+
+ deferredResult = new Clipperz.Async.Deferred("decrypt_test", someTestArgs);
+
+ deferredResult.addMethod(encryptedRemoteObject, 'getValue', 'key1');
+ deferredResult.addTest('value1', "getting 'key1' works");
+ deferredResult.addMethod(encryptedRemoteObject, 'hasAnyCleanTextData');
+ deferredResult.addTest(true, "After accessing a value, hasAnyCleanTextData returns false");
+
+ deferredResult.addMethod(encryptedRemoteObject, 'hasPendingChanges');
+ deferredResult.addTest(false, "if nothing has changed, the object should return not pending changes");
+
+ deferredResult.addMethod(encryptedRemoteObject, 'deleteAllCleanTextData');
+ deferredResult.addMethod(encryptedRemoteObject, 'hasAnyCleanTextData');
+ deferredResult.addTest(false, "After deleting all cleanTextData, hasAnyCleanTextData returns false");
+
+ deferredResult.addMethod(encryptedRemoteObject, 'getValue', 'key1');
+ deferredResult.addTest('value1', "getting 'key1' (also after a lock) works correctly");
+
+ deferredResult.addMethod(encryptedRemoteObject, 'setValue', 'key1', 'new value1');
+ deferredResult.addMethod(encryptedRemoteObject, 'getValue', 'key1');
+ deferredResult.addTest('new value1', "after setting a new value, it is correctly returned");
+
+ deferredResult.addMethod(encryptedRemoteObject, 'values');
+ deferredResult.addCallback(function (someValues) {
+ SimpleTest.is(someValues['key1'], 'new value1', "the value got straight from the objectStore is correct");
+ });
+
+ deferredResult.addMethod(encryptedRemoteObject, 'hasPendingChanges');
+ deferredResult.addTest(true, "once a value has been changed, the object should return that there're some pending changes");
+
+ deferredResult.addMethod(encryptedRemoteObject, 'revertChanges');
+ deferredResult.addMethod(encryptedRemoteObject, 'hasPendingChanges');
+ deferredResult.addTest(false, "reverting the changes should return the object to its initial state, without any peding changes");
+
+ deferredResult.addMethod(encryptedRemoteObject, 'getValue', 'key1');
+ deferredResult.addTest('value1', "also the value of the changed item has been restored");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'encrypt_with_new_object_test': function (someTestArgs) {
+ var deferredResult;
+ var encryptedRemoteObject;
+ var key;
+// var version;
+// var rawData;
+
+ key = "just a random key";
+// version = Clipperz.PM.Crypto.encryptingFunctions.currentVersion;
+// rawData = "just a random text to encrypt";
+
+ encryptedRemoteObject = new Clipperz.PM.DataModel.EncryptedRemoteObject({
+ 'retrieveRemoteDataFunction': MochiKit.Base.noop
+ });
+
+ encryptedRemoteObject.setValue('key1', "value1");
+ encryptedRemoteObject.setValue('key2', "value2");
+ encryptedRemoteObject.setValue('key3', "value3");
+
+ deferredResult = new Clipperz.Async.Deferred("encrypt_with_new_object_test", someTestArgs);
+ deferredResult.addMethod(encryptedRemoteObject, 'prepareRemoteDataWithKey', key);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('data'));
+ deferredResult.collectResults({
+ 'key': MochiKit.Base.partial(MochiKit.Async.succeed, key),
+ 'value': MochiKit.Async.succeed,
+ 'version': MochiKit.Base.partial(MochiKit.Async.succeed, Clipperz.PM.Crypto.encryptingFunctions.currentVersion)
+ });
+ deferredResult.addCallback(Clipperz.PM.Crypto.deferredDecrypt);
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.is(aResult['key1'], "value1", "encrypt and decrypt works for first element");
+ SimpleTest.is(aResult['key2'], "value2", "encrypt and decrypt works for second element");
+ SimpleTest.is(aResult['key3'], "value3", "encrypt and decrypt works for third element");
+ })
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+ //-------------------------------------------------------------------------
+ //-------------------------------------------------------------------------
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+//#############################################################################
+
+SimpleTest.runDeferredTests("Clipperz.PM.DataModel.EncryptedRemoteObject", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/OneTimePassword.html b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/OneTimePassword.html
new file mode 100644
index 0000000..a9bac22
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/OneTimePassword.html
@@ -0,0 +1,105 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.DataModel.User - test</title>
+
+ <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Toll.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginFormValue.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script>
+
+ <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script>
+<script>
+ Clipperz_IEisBroken = false;
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+Clipperz_normalizedNewLine = '\x0d\x0a';
+</script><![endif]-->
+
+</head>
+<body>
+
+<pre id="test">
+<script>
+ Clipperz.PM.Strings.Languages.setSelectedLanguage('en-us');
+</script>
+<script type="text/javascript" src="User.data.js"></script>
+<script type="text/javascript" src="OneTimePassword.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/OneTimePassword.test.js b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/OneTimePassword.test.js
new file mode 100644
index 0000000..0171714
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/OneTimePassword.test.js
@@ -0,0 +1,198 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+
+ 'isValidOneTimePasswordValue_test': function (someTestArgs) {
+ var otp;
+ var notOTP;
+
+ otp = 'yaxx k7ww - f8y6 tqz5 - 58b6 th44 - 9cwv q0fg';
+ SimpleTest.is(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue(otp), true, "isValidOneTimePasswordValue [expect true] - test 1");
+
+ notOTP = 'trustno1';
+ SimpleTest.is(Clipperz.PM.DataModel.OneTimePassword.isValidOneTimePasswordValue(notOTP), false, "isValidOneTimePasswordValue [expect false] - test 1");
+
+ return MochiKit.Async.succeed('done');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'loginUsingOtp_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user, user2;
+ var username;
+ var passphrase;
+
+ username = "test";
+ passphrase = "yaxx k7ww - f8y6 tqz5 - 58b6 th44 - 9cwv q0fg"; // OTP
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return passphrase;}});
+ user2 = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return passphrase;}});
+
+ deferredResult = new Clipperz.Async.Deferred("loginUsingOtp_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_with_otps']);
+
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(1, "This account has one single card");
+
+ deferredResult.addMethod(user, 'getOneTimePasswords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(1, "This account has one OTP");
+
+ deferredResult.addMethod(user, 'getOneTimePasswords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(0));
+ deferredResult.addCallback(MochiKit.Base.methodcaller('status'));
+ deferredResult.addTest('USED', "The available OTP has been unsed to login, and should be marked accordingly");
+
+ deferredResult.addMethod(user2, 'login');
+ deferredResult.shouldFail("trying to login using the same OTP twice");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'changePassphraseAndLoginUsingOtp_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var user2;
+ var user3;
+ var otp;
+
+ otp = "yaxx k7ww - f8y6 tqz5 - 58b6 th44 - 9cwv q0fg"; // OTP
+
+ newPassphrase = 'tset';
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return otp;}});
+
+ deferredResult = new Clipperz.Async.Deferred("changePassphraseAndLoginUsingOtp_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_with_otps']);
+
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(1, "This account has only a single card");
+
+ deferredResult.addMethod(user, 'changePassphrase', newPassphrase);
+ deferredResult.addMethod(user, 'logout');
+
+ deferredResult.addMethod(user2, 'login');
+ deferredResult.addMethod(user2, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(1, "This account has oly a single card");
+ deferredResult.addMethod(user2, 'logout');
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'loginUsingOtpAndWrongUsername_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user, user2;
+ var username;
+ var wrongUsername;
+ var passphrase;
+
+ username = "test";
+ wrongUsername = "tset";
+ passphrase = "yaxx k7ww - f8y6 tqz5 - 58b6 th44 - 9cwv q0fg"; // OTP
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:wrongUsername, getPassphraseFunction:function () { return passphrase;}});
+ user2 = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return passphrase;}});
+
+ deferredResult = new Clipperz.Async.Deferred("loginUsingOtpAndWrongUsername_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_with_otps']);
+
+ deferredResult.addMethod(user, 'login');
+ deferredResult.shouldFail("login in using the wrong username with the OTP should fail");
+
+ deferredResult.addMethod(user2, 'login');
+ deferredResult.shouldFail("trying to reuse the same OTP should fail, even if now it is used with the correct username");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'loginUserWithAPassphraseLookingExactlyLikeAnOTP_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var username;
+ var passphrase;
+
+ username = "otp_user";
+ passphrase = "yaxx k7ww - f8y6 tqz5 - 58b6 th44 - 9cwv q0fg"; // passphrase
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return passphrase;}});
+
+ deferredResult = new Clipperz.Async.Deferred("loginUserWithAPassphraseLookingExactlyLikeAnOTP_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['otp_user_test']);
+
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(1, "This account has one single card");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+
+
+//#############################################################################
+
+SimpleTest.runDeferredTests("Clipperz.PM.DataModel.OneTimePassword", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.html b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.html
new file mode 100644
index 0000000..c349e0d
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.html
@@ -0,0 +1,98 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.DataModel.Record - test</title>
+
+ <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Toll.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginFormValue.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script>
+
+ <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script>
+</head>
+<body>
+
+<pre id="test">
+<script>
+ Clipperz.PM.Strings.Languages.setSelectedLanguage('en-us');
+</script>
+<script type="text/javascript" src="DirectLoginConfigurations.data.js"></script>
+<script type="text/javascript" src="User.data.js"></script>
+<script type="text/javascript" src="Record.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.test.js b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.test.js
new file mode 100644
index 0000000..7d024d9
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/Record.test.js
@@ -0,0 +1,1285 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+
+ 'recordUseOf_retrieveIndexDataFunction_and_getRemoteDataFunction_test': function (someTestArgs) {
+ var deferredResult;
+ var record;
+
+//console.log("#### new Clipperz.PM.DataModel.Record [5]");
+ record = new Clipperz.PM.DataModel.Record({
+ 'reference': '<<< record reference >>>',
+ 'retrieveKeyFunction': MochiKit.Base.noop,
+ 'retrieveRemoteDataFunction': function (aRecordReference) {
+ SimpleTest.is(aRecordReference, '<<< record reference >>>', "Record correctly passes its record reference when asking for encrypted data");
+ return MochiKit.Async.succeed({
+ // fake server payload
+ 'data': "#### fake encrypted data ####",
+ 'version': "0.x",
+ 'currentVersion': {
+ 'reference': "<<< fake record version reference >>>",
+ 'data': "#### fake encrypted data ####",
+ 'version': "0.x"
+ }
+ });
+ },
+ 'updateDate': "Thu, 10 May 2007 13:01:21 UTC",
+// 'encryptedDataKeypath': 'data',
+// 'encryptedVersionKeypath': 'version',
+
+ 'retrieveIndexDataFunction': function (aRecordReference) {
+ SimpleTest.is(aRecordReference, '<<< record reference >>>', "Record correctly passes its record reference when asking for index data");
+ return MochiKit.Async.succeed({
+ key: '<< key >>',
+ label: '<< label >>',
+ notes: '<< notes >>'
+ });
+ },
+ 'updateIndexDataFunction': MochiKit.Base.noop
+
+ });
+
+ deferredResult = new Clipperz.Async.Deferred("recordUseOf_retrieveIndexDataFunction_and_getEncryptedDataFunction_test", someTestArgs);
+ deferredResult.addMethod(record, 'label');
+ deferredResult.addTest('<< label >>', "Record returns the right value for label");
+ deferredResult.addMethod(record, 'notes');
+ deferredResult.addTest('<< notes >>', "Record returns the right value for notes - even the legacy one, stored on the header");
+ deferredResult.addMethod(record, 'getRemoteData');
+ deferredResult.addCallback(Clipperz.Async.Test.isDeeply({ 'data': "#### fake encrypted data ####", 'version': "0.x", 'currentVersion': { 'reference': "<<< fake record version reference >>>", 'data': "#### fake encrypted data ####", 'version': "0.x" } }, "Record returns the expected encrypted data"));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'createRecordWithoutAllRequiredParameters_test': function (someTestArgs) {
+ var record;
+
+ try {
+//console.log("#### new Clipperz.PM.DataModel.Record [6]");
+ record = new Clipperz.PM.DataModel.Record({reference:'--'});
+ SimpleTest.ok(false, "creating a record without all parameters should raise an exception");
+ } catch(exception) {
+// SimpleTest.is(exception.name, "Clipperz.Base.exception.MandatoryParameter", "creating a record without all parameters raises an exception");
+ SimpleTest.ok(/Clipperz\.Base\.exception\.MandatoryParameter.*/.test(exception.name), "creating a record without all parameters raises an exception");
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'recordFromOldData_version_0.1_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var recordID;
+
+//console.log("#### new Clipperz.PM.DataModel.Record [7]");
+/*
+ record = new Clipperz.PM.DataModel.Record({
+ 'reference': '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a',
+ 'retrieveKeyFunction': MochiKit.Base.partial(MochiKit.Async.succeed, 'e038652297f981d5ca917d88fa2c4c3251a12c0fa41bf7313a4d24a9738fe6c6'),
+ 'retrieveRemoteDataFunction': MochiKit.Base.partial(MochiKit.Async.succeed, {
+ 'data': '4ec19a7093534e7dcf7c796b889283c6cec224b1895720ba3ff43ce091dc72c61fd5ea56def418ba3f15239f73228c6c8558585311f5e6673efe57482a1f9c9fe71e921576989eace671ec543685e3ad8f976bbfa4c2dbc629fab936c227d4fd4da3a1561ea79e553bae7b758ff91762572c1448a2d18bec797e12721238ef5ba18ddf1fba8ae773a8debe1040b3b158220aec6be9c7190687139f589a30d9c8887792fd7040e3c7cf3f9999fb9dde1f9f334d17c996996d538a7e374ac93135acafdaf5fce738a1702182897b63d2cb8e308b94156473cba63dcc557d17dcbdb55fcff63d9ba5edf68c42855052e34207d6fabe94fe024c3db616b45f494da42c62224d3897e320080072cc442d4212e7b1e8d5b3d9e3c25d48f4e7c37112ef4c6b2c0c8aff0bd3ce05694370e4378701463dde26c7c0322f8a9eb5a724106039b16b35050a9a9b5717b2eec803efa962b88b9655742f5e7b180ea567449671fb5a2ce563d8b47bc25705821938192eae420391c208182a788dd06fb6448b9858a4104a14efd7717671c65cd08fd979a4da7c01712bc5d4e949a10ef1ea65caf1f07cee34b063bab01bfb7a59047fef30c3059ea652f1c92b9e72aac515ac8851756703772e1fa05384ee7f0d5c7a3c',
+ 'version': '0.1',
+ 'currentVersion': {
+ 'reference': '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a',
+ 'data': '4ec19a7093534e7dcf7c796b889283c6cec224b1895720ba3ff43ce091dc72c61fd5ea56def418ba3f15239f73228c6c8558585311f5e6673efe57482a1f9c9fe71e921576989eace671ec543685e3ad8f976bbfa4c2dbc629fab936c227d4fd4da3a1561ea79e553bae7b758ff91762572c1448a2d18bec797e12721238ef5ba18ddf1fba8ae773a8debe1040b3b158220aec6be9c7190687139f589a30d9c8887792fd7040e3c7cf3f9999fb9dde1f9f334d17c996996d538a7e374ac93135acafdaf5fce738a1702182897b63d2cb8e308b94156473cba63dcc557d17dcbdb55fcff63d9ba5edf68c42855052e34207d6fabe94fe024c3db616b45f494da42c62224d3897e320080072cc442d4212e7b1e8d5b3d9e3c25d48f4e7c37112ef4c6b2c0c8aff0bd3ce05694370e4378701463dde26c7c0322f8a9eb5a724106039b16b35050a9a9b5717b2eec803efa962b88b9655742f5e7b180ea567449671fb5a2ce563d8b47bc25705821938192eae420391c208182a788dd06fb6448b9858a4104a14efd7717671c65cd08fd979a4da7c01712bc5d4e949a10ef1ea65caf1f07cee34b063bab01bfb7a59047fef30c3059ea652f1c92b9e72aac515ac8851756703772e1fa05384ee7f0d5c7a3c',
+ 'version': '0.1'
+ }
+
+ }),
+
+ 'retrieveIndexDataFunction': MochiKit.Base.partial(MochiKit.Async.succeed, {
+// 'key': 'e038652297f981d5ca917d88fa2c4c3251a12c0fa41bf7313a4d24a9738fe6c6',
+ 'label': '<< label >>',
+ 'notes': '<< notes >>'
+ }),
+ 'updateIndexDataFunction': MochiKit.Base.noop,
+ 'updateDate': 'Mon Oct 02 10:01:52 CEST 2006'
+ });
+*/
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ recordID = "05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a";
+
+ deferredResult = new Clipperz.Async.Deferred("recordFromOldData_version_0.1_test", someTestArgs);
+
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('hasAnyCleanTextData');
+ deferredResult.addTest(false, "When first loaded, the record has no clean text data");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('label');
+ deferredResult.addTest("Card encoded with an old algorithm", "Record returns the right value for label");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('notes');
+ deferredResult.addTest("", "Record returns the right value for notes - even the legacy one, stored on the header");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('hasAnyCleanTextData');
+ deferredResult.addTest(true, "After reading some values, the record has some clean text data");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(function (someFields) {
+ SimpleTest.is(MochiKit.Base.values(someFields).length, 6, "the card has 6 fields");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'removeDirectLogin': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; // YAHOO (4)
+ var directLoginID = 'dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496';
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.removeDirectLogin", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
+ deferredResult.addMethodcaller('remove');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(true, "removing a direct login to a record should result in pending changes on the record");
+
+ deferredResult.addMethod(user, 'saveChanges');
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "after saving there should be not any pending changes");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(3, "after saving changes, the record should have only 3 direct logins");
+
+ deferredResult.addMethod(user2, 'login');
+ deferredResult.addMethod(user2, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(3, "also reloading all the data with a new user, the direct logins should always be 3");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'removeDirectLoginAndRevertChanges': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
+ var directLoginID = 'dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496';
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.removeDirectLoginAndRevertChanges", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getDirectLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(22, "the user has 22 initially");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(4, "the selected record has 4 direct logins");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
+ deferredResult.addMethodcaller('remove');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(true, "removing a direct login to a record should result in pending changes on the record");
+
+ deferredResult.addMethod(user, 'revertChanges');
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "after reverting the changes, the user should not have pending changes");
+
+ deferredResult.addMethod(user, 'getDirectLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(22, "after reverting the changes, the user should still have 22 direct logins");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(4, "after reverting the changes, the record should still have 4 direct logins");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addDirectLoginAndRevertChanges': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user, user2;
+ var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; // YAHOO (4)
+ var directLoginReference;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.addDirectLoginAndRevertChanges", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.setValue('record');
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(4, "the record, when initially loaded, has 4 direct logins");
+
+ deferredResult.getValue('record');
+ deferredResult.addMethodcaller('createNewDirectLogin');
+ deferredResult.setValue('directLogin');
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('setLabel', "New direct login");
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('setBookmarkletConfiguration', '{"page": {"title": "Parallels Account"}, "form": {"attributes": {"action": "https://www.parallels.com/account/", "method": "post"}, "inputs": [{"type": "text", "name": "Email", "value": ""}, {"type": "password", "name": "Password", "value": ""}]}, "version": "0.2.3"}');
+
+ deferredResult.addMethod(user, 'revertChanges');
+//deferredResult.addCallback(function () { console.log("###################################"); });
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "after reverting the changes, the user should NOT have pending changes");
+
+ deferredResult.getValue('record');
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(false, "after reverting the changes, the record should NOT have pending changes");
+
+ deferredResult.addMethod(user2, 'login');
+
+ deferredResult.addMethod(user2, 'getRecord', recordID);
+ deferredResult.setValue('record_2');
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(4, "the record, when reloaded from scratch, has still 4 direct logins");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addDirectLoginAndSaveChanges': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user, user2;
+ var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; // YAHOO (4)
+ var directLoginReference;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.addDirectLoginAndSaveChanges", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('hasAnyCleanTextData');
+ deferredResult.addTest(false, "When first loaded, the record has no clean text data [2]");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.setValue('record');
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(4, "the selected record has 4 direct logins");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('hasAnyCleanTextData');
+ deferredResult.addTest(false, "Still no clean text data is stored on the record, as all accessed data are stored on the index");
+
+ deferredResult.addMethod(user, 'hasAnyCleanTextData');
+ deferredResult.addTest(true, "the user has some clean text data");
+
+ deferredResult.getValue('record');
+ deferredResult.addMethodcaller('createNewDirectLogin');
+ deferredResult.setValue('directLogin');
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('label');
+ deferredResult.addTest(null, "The label of a initially created direct login is empty");
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('bookmarkletConfiguration');
+ deferredResult.addTest('', "The bookmaraklet configuration of a initially created direct login is empty");
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('bindings');
+ deferredResult.addCallback(Clipperz.Async.Test.isDeeply({}, "The bindings of a initially created direct login is empty"));
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('setLabel', "New direct login");
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('setBookmarkletConfiguration', directLoginConfigurations['Parallels']);
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('bindings');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('Email'));
+ deferredResult.addMethodcaller('setFieldKey', '4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9'); // "userID"
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('bindings');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('Password'));
+ deferredResult.addMethodcaller('setFieldKey', 'ef2dee54322bf401540657d469e158a50e9228bc0a192a31d2e3ee56a77e565b'); // "password"
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('favicon'),
+ deferredResult.addTest('http://www.parallels.com/favicon.ico', "the original favicon is the expected one"),
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('reference');
+ deferredResult.addCallback(function (aReference) {
+ directLoginReference = aReference;
+ });
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "after adding a new direct login, the user should have pending changes");
+
+ deferredResult.getValue('record');
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(true, "after adding a new direct login, the record should have pending changes");
+
+ deferredResult.getValue('record');
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(5, "after adding a new direct login, the record has now 5 direct logins");
+
+
+ deferredResult.addMethod(user, 'saveChanges');
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "after saving the changes, the user should NOT have pending changes");
+
+
+ deferredResult.addMethod(user2, 'login');
+
+ deferredResult.addMethod(user2, 'getRecord', recordID);
+ deferredResult.setValue('record_2');
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(5, "the record, when reloaded from scratch, has still 5 direct logins");
+
+ deferredResult.getValue('record_2');
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('4')); // TODO: accessing directLogins by index is not really nice
+ deferredResult.setValue('directLogin_2');
+ deferredResult.addMethodcaller('label');
+ deferredResult.addTest('New direct login', "The label of the direct login has been correctly saved");
+
+ deferredResult.getValue('directLogin_2');
+ deferredResult.addMethodcaller('bindings');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('Email'));
+ deferredResult.addMethodcaller('field');
+ deferredResult.addMethodcaller('value');
+ deferredResult.addTest('joe.clipperz', "The value bound to the direct login 'Email' field is correct");
+
+ deferredResult.getValue('directLogin_2');
+ deferredResult.addMethodcaller('bindings');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('Password'));
+ deferredResult.addMethodcaller('field');
+ deferredResult.addMethodcaller('value');
+ deferredResult.addTest('enfvDG1RxAsl', "The value bound to the direct login 'Password' field is correct");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'readDirectLoginAttributes': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ var recordID = '2977aa5f99a9f6e5596c1bd7871e82d7328c3716c9ef8ba349ae65f10d97924e';
+ var directLoginID = '03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c';
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.readDirectLoginAttributes", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_multipleRecordVersions_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c'));
+ deferredResult.setValue('directLogin');
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('inputs');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(13, "Amazon direct login has 13 inputs");
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('inputs');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(MochiKit.Base.filter, MochiKit.Base.methodcaller('needsFormValue'));
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(1, "Amazon direct login has 1 field needing a form value");
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('inputs');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(MochiKit.Base.filter, MochiKit.Base.methodcaller('needsBinding'));
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(2, "Amazon direct login has 2 field needing a binding");
+
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('bindings');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(2, "Amazon direct login has just two bindings");
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('bindings');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('email'));
+ deferredResult.addMethodcaller('fieldKey');
+ deferredResult.addTest('5e822c34aaf1a9fbc0b52585c1915f3a3758abd51923a4d35ae85373bbb839c2', "Amazon direct login 'email' binding points to the correct field");
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('bindings');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('password'));
+ deferredResult.setValue('passwordBinding');
+ deferredResult.addMethodcaller('fieldKey');
+ deferredResult.addTest('01e4bb6dcf054f312c535de8160bcf50bdccd664bdc05721b10d4e69583765f7', "Amazon direct login 'password' binding points to the correct field");
+
+ deferredResult.getValue('passwordBinding');
+ deferredResult.addMethodcaller('field');
+ deferredResult.addMethodcaller('label');
+ deferredResult.addTest('password', "Amazon direct login 'password' binding points to the 'password' field");
+
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('formValues');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(1, "Amazon direct login has just one formValue");
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('formValues');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('action'));
+ deferredResult.addMethodcaller('value');
+ deferredResult.addTest('sign-in', "Amazon direct 'action' formValue is set to 'sign-in'");
+
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'editDirectLoginLabel': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var oldLabel;
+ var newLabel;
+
+ var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
+ var directLoginID = 'dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496';
+
+ oldLabel = "Yahoo! Mail";
+ newLabel = "YAHOO! Mail";
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginLabel", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
+ deferredResult.addMethodcaller('label');
+ deferredResult.addTest(oldLabel, "the current label of the direct login");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
+ deferredResult.addMethodcaller('setLabel', newLabel);
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "changing the label of a direct login should trigger some changes");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(true, "changing the label of a direct login should trigger some changes also on the record itself");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(true, "changing the label of a direct login should trigger some changes also on the directLogin itself");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'editDirectLoginFormValueAndRestoreChanges': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
+ var directLoginID = 'dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496';
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginFormValueAndRestoreChanges", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
+ deferredResult.setValue('directLogin');
+ deferredResult.addMethodcaller('formValues');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('.persistent'));
+ deferredResult.addMethodcaller('value');
+ deferredResult.addTest(null, "original formValue value matches");
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('formValues');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('.persistent'))
+ deferredResult.addMethodcaller('setValue', 'y');
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('formValues');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('.persistent'))
+ deferredResult.addMethodcaller('value');
+ deferredResult.addTest('y', "the newly set value is retained");
+
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "changing the label of a direct login should trigger some changes");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(true, "changing the label of a direct login should trigger some changes also on the record itself");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(true, "changing the label of a direct login should trigger some changes also on the directLogin itself");
+
+ deferredResult.addMethod(user, 'revertChanges');
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('formValues');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('.persistent'))
+ deferredResult.addMethodcaller('value');
+ deferredResult.addTest(null, "the old formValue value is correctly restored");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'editDirectLoginConfigurationAndRevertChanges': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
+ var directLoginID = 'dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496';
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginConfigurationAndRevertChanges", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
+
+ deferredResult.addCallback(function (aDirectLogin) {
+// var newBookmarkletConfiguration;
+
+// newBookmarkletConfiguration = '{\n \"page\": {\n \"title\": \"Yahoo! Mail\"\n },\n \"form\": {\n \"attributes\": {\n \"action\": \"https://login.yahoo.com/config/login?\",\n \"method\": \"post\"\n },\n \"inputs\": [\n {\n \"type\": \"text\",\n \"name\": \"login\",\n \"value\": \"\"\n },\n {\n \"type\": \"password\",\n \"name\": \"passwd\",\n \"value\": \"\"\n },\n {\n \"type\": \"checkbox\",\n \"name\": \".persistent\",\n \"value\": \"y\"\n }\n ]\n },\n \"version\": \"0.2\"\n}';
+ return Clipperz.Async.callbacks("Record.test.editDirectLoginConfiguration [inner call]", [
+ MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'),
+ Clipperz.Async.Test.is(directLoginConfigurations['Yahoo! Mail'], "the current bookmarkletConfiguration"),
+
+ MochiKit.Base.method(aDirectLogin, 'favicon'),
+ Clipperz.Async.Test.is('http://login.yahoo.com/favicon.ico', "the original favicon is the expected one"),
+
+ MochiKit.Base.method(aDirectLogin, 'setBookmarkletConfiguration', directLoginConfigurations['Parallels']),
+
+ MochiKit.Base.method(aDirectLogin, 'favicon'),
+ Clipperz.Async.Test.is('http://login.yahoo.com/favicon.ico', "the original favicon is the expected one"),
+
+ MochiKit.Base.method(aDirectLogin, 'hasPendingChanges'),
+ Clipperz.Async.Test.ok("changing the configuration should trigger the pending changes on the direct login"),
+ MochiKit.Base.method(aDirectLogin.record(), 'hasPendingChanges'),
+ Clipperz.Async.Test.ok("changing the configuration should trigger the pending changes also on the record"),
+ MochiKit.Base.method(user, 'hasPendingChanges'),
+ Clipperz.Async.Test.ok("changing the configuration should trigger the pending changes also on the user"),
+
+ MochiKit.Base.method(aDirectLogin, 'revertChanges'),
+
+ MochiKit.Base.method(aDirectLogin, 'hasPendingChanges'),
+ Clipperz.Async.Test.fail("reverting changes should reset pending changes on the direct login"),
+ MochiKit.Base.method(aDirectLogin.record(), 'hasPendingChanges'),
+ Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the record"),
+ MochiKit.Base.method(user, 'hasPendingChanges'),
+ Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the user"),
+
+ MochiKit.Base.noop
+ ], someTestArgs);
+ })
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'editDirectLoginConfiguration_keepingTheSameStructure_AndSaveChanges': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var user2;
+ var newBookmarkletConfiguration;
+
+ var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
+ var directLoginID = 'dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496';
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ newBookmarkletConfiguration = '{\n \"page\": {\n \"title\": \"Yahoo! Mail\"\n },\n \"form\": {\n \"attributes\": {\n \"action\": \"https://login.yahoo.com/config/login?\",\n \"method\": \"post\"\n },\n \"inputs\": [\n {\n \"type\": \"text\",\n \"name\": \"login\",\n \"value\": \"\"\n },\n {\n \"type\": \"password\",\n \"name\": \"passwd\",\n \"value\": \"\"\n },\n {\n \"type\": \"checkbox\",\n \"name\": \".persistent\",\n \"value\": \"y\"\n }\n ]\n },\n \"version\": \"0.2\"\n}';
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginConfiguration_keepingTheSameStructure_AndSaveChanges", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
+ deferredResult.addCallback(function (aDirectLogin) {
+ return Clipperz.Async.callbacks("Record.test.editDirectLoginConfiguration_keepingTheSameStructure_AndSaveChanges [inner call 1]", [
+ MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'),
+ Clipperz.Async.Test.is(directLoginConfigurations['Yahoo! Mail'], "the current bookmarkletConfiguration (1)"),
+
+ MochiKit.Base.method(aDirectLogin, 'inputs'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(26, "The original direct login had 26 inputs"),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(2, "The original direct login had 2 inputs"),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.itemgetter('login'),
+ MochiKit.Base.methodcaller('field'),
+ MochiKit.Base.methodcaller('reference'),
+ Clipperz.Async.Test.is('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9', "the original 'login' direct login binding points to the correct field"),
+
+ MochiKit.Base.method(aDirectLogin, 'formValues'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(1, "The original direct login had 1 form values"),
+
+ MochiKit.Base.method(aDirectLogin, 'formValues'),
+ MochiKit.Base.itemgetter('.persistent'),
+ MochiKit.Base.methodcaller('type'),
+ Clipperz.Async.Test.is('checkbox', "the original formValue has the expected type"),
+
+ MochiKit.Base.method(aDirectLogin, 'formValues'),
+ MochiKit.Base.itemgetter('.persistent'),
+ MochiKit.Base.methodcaller('value'),
+ Clipperz.Async.Test.is(null, "the original formValue is correct (1)"),
+
+ MochiKit.Base.method(aDirectLogin, 'formValues'),
+ MochiKit.Base.itemgetter('.persistent'),
+ MochiKit.Base.methodcaller('setValue', 'y'),
+
+
+ MochiKit.Base.method(aDirectLogin, 'setBookmarkletConfiguration', newBookmarkletConfiguration),
+ MochiKit.Base.method(user, 'saveChanges'),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.itemgetter('login'),
+ MochiKit.Base.methodcaller('field'),
+ MochiKit.Base.methodcaller('reference'),
+ Clipperz.Async.Test.is('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9', "the 'login' binding is still valid after the new configuration is set"),
+
+ MochiKit.Base.method(aDirectLogin, 'hasPendingChanges'),
+ Clipperz.Async.Test.fail("reverting changes should reset pending changes on the direct login (2)"),
+ MochiKit.Base.method(aDirectLogin.record(), 'hasPendingChanges'),
+ Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the record (2)"),
+ MochiKit.Base.method(user, 'hasPendingChanges'),
+ Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the user (2)"),
+
+ MochiKit.Base.noop
+ ], someTestArgs);
+ })
+
+ deferredResult.addMethod(user2, 'login');
+
+ deferredResult.addMethod(user2, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
+ deferredResult.addCallback(function (aDirectLogin) {
+ return Clipperz.Async.callbacks("Record.test.editDirectLoginConfiguration_keepingTheSameStructure_AndSaveChanges [inner call 2]", [
+ MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'),
+ Clipperz.Async.Test.is(newBookmarkletConfiguration, "the direct login has the new bookmarkletConfiguration even after being reloaded"),
+
+ MochiKit.Base.method(aDirectLogin, 'inputs'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(3, "The new direct login has 3 inputs"),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(2, "The new direct login had 2 inputs"),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.itemgetter('login'),
+ MochiKit.Base.methodcaller('field'),
+ MochiKit.Base.methodcaller('reference'),
+ Clipperz.Async.Test.is('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9', "the new 'login' direct login binding still points to the correct field"),
+
+ MochiKit.Base.method(aDirectLogin, 'formValues'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(1, "The new direct login had 1 form values (1)"),
+
+ MochiKit.Base.method(aDirectLogin, 'formValues'),
+ MochiKit.Base.itemgetter('.persistent'),
+ MochiKit.Base.methodcaller('value'),
+ Clipperz.Async.Test.is(null, "the formValue is still correctly set"),
+
+ MochiKit.Base.noop
+ ], someTestArgs);
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'editDirectLoginConfiguration_changingTheStructure_AndSaveChanges': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var user2;
+
+ var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
+ var directLoginID = 'dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496';
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.editDirectLoginConfiguration_changingTheStructure_AndSaveChanges", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
+ deferredResult.addCallback(function (aDirectLogin) {
+ return Clipperz.Async.callbacks("Record.test.editDirectLoginConfiguration_changingTheStructure_AndSaveChanges [inner call 1]", [
+ MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'),
+ Clipperz.Async.Test.is(directLoginConfigurations['Yahoo! Mail'], "the current bookmarkletConfiguration (2)"),
+
+ MochiKit.Base.method(aDirectLogin, 'inputs'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(26, "The original direct login had 26 inputs"),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(2, "The original direct login had 2 inputs"),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.itemgetter('login'),
+ MochiKit.Base.methodcaller('field'),
+ MochiKit.Base.methodcaller('reference'),
+ Clipperz.Async.Test.is('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9', "the original 'login' direct login binding points to the correct field"),
+
+ MochiKit.Base.method(aDirectLogin, 'formValues'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(1, "The original direct login had 1 form values"),
+
+ MochiKit.Base.method(aDirectLogin, 'formValues'),
+ MochiKit.Base.itemgetter('.persistent'),
+ MochiKit.Base.methodcaller('value'),
+ Clipperz.Async.Test.is(null, "the original formValue is correct (2)"),
+
+
+ MochiKit.Base.method(aDirectLogin, 'setBookmarkletConfiguration', directLoginConfigurations['Parallels']),
+ MochiKit.Base.method(user, 'saveChanges'),
+
+ MochiKit.Base.method(aDirectLogin, 'inputs'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(2, "The new direct login has 2 inputs"),
+
+ MochiKit.Base.method(aDirectLogin, 'formValues'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(0, "The new direct login has no form values"),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(2, "The new direct login has 2 inputs"),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.itemgetter('login'),
+ Clipperz.Async.Test.is(null, "the 'login' binding should not exist within the new configuration"),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.itemgetter('passwd'),
+ Clipperz.Async.Test.is(null, "the 'passwd' binding should not exist within the new configuration"),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.itemgetter('Email'),
+ Clipperz.Async.Test.ok("the 'Email' binding should exist within the new configuration"),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.itemgetter('Password'),
+ Clipperz.Async.Test.ok("the 'Password' binding should exist within the new configuration"),
+
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.itemgetter('Email'),
+ MochiKit.Base.methodcaller('field'),
+ Clipperz.Async.Test.is(null, "the 'Email' binding should not point to any field, yet"),
+
+
+ MochiKit.Base.method(aDirectLogin, 'hasPendingChanges'),
+ Clipperz.Async.Test.fail("reverting changes should reset pending changes on the direct login (2)"),
+ MochiKit.Base.method(aDirectLogin.record(), 'hasPendingChanges'),
+ Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the record (2)"),
+ MochiKit.Base.method(user, 'hasPendingChanges'),
+ Clipperz.Async.Test.fail("reverting changes should reset pending changes also on the user (2)"),
+
+ MochiKit.Base.noop
+ ], someTestArgs);
+ })
+
+ deferredResult.addMethod(user2, 'login');
+
+ deferredResult.addMethod(user2, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(directLoginID));
+ deferredResult.addCallback(function (aDirectLogin) {
+ return Clipperz.Async.callbacks("Record.test.editDirectLoginConfiguration_changingTheStructure_AndSaveChanges [inner call 2]", [
+ MochiKit.Base.method(aDirectLogin, 'bookmarkletConfiguration'),
+ Clipperz.Base.evalJSON,
+ MochiKit.Base.itemgetter('form'),
+ Clipperz.Async.Test.isDeeply(Clipperz.Base.evalJSON(directLoginConfigurations['Parallels'])['form'], "the direct login has the new bookmarkletConfiguration even after being reloaded"),
+
+ MochiKit.Base.method(aDirectLogin, 'inputs'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(2, "The new -reloaded- direct login has 2 inputs"),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(2, "The new direct login had 2 inputs"),
+
+ MochiKit.Base.method(aDirectLogin, 'bindings'),
+ MochiKit.Base.itemgetter('login'),
+ Clipperz.Async.Test.is(null, "the 'login' binding should not exist within the new configuration"),
+
+ MochiKit.Base.method(aDirectLogin, 'formValues'),
+ MochiKit.Base.keys,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(0, "The new direct login has no form values (2)"),
+
+ MochiKit.Base.noop
+ ], someTestArgs);
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'editFieldValueAndRestoreIt': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.editValueAndRestoreIt", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9'));
+ deferredResult.addMethodcaller('value');
+ deferredResult.addTest('joe.clipperz', "the current field value is 'joe.clipperz'");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9'));
+ deferredResult.addMethodcaller('setValue', 'fake.clipperz');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(true, "changing the value of a field should trigger pending changes");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9'));
+ deferredResult.addMethodcaller('setValue', 'joe.clipperz');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(false, "restoring the value of a field should revert pending changes");
+
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'accessFieldValues': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.accessFieldValues", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('fieldWithLabel', 'userID');
+ deferredResult.addMethodcaller('value');
+ deferredResult.addTest('joe.clipperz', "the current field value is 'joe.clipperz'");
+
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'editFieldValueAndSaveIt': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user, user2;
+
+ var recordID = '2977aa5f99a9f6e5596c1bd7871e82d7328c3716c9ef8ba349ae65f10d97924e';
+ var passwordFieldID = '01e4bb6dcf054f312c535de8160bcf50bdccd664bdc05721b10d4e69583765f7';
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.editValueAndRestoreIt", someTestArgs);
+// deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_multipleRecordVersions_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('getVersions');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(5, "the selected record has 5 versions");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(passwordFieldID));
+ deferredResult.collectResults({
+ 'label': MochiKit.Base.methodcaller('label'),
+ 'value': MochiKit.Base.methodcaller('value')
+ });
+ deferredResult.addTest({'label': 'password', 'value': 'HRRd7ycaFVG6'}, "the current field label and value match", true);
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(passwordFieldID));
+ deferredResult.addMethodcaller('setValue', '<<pippo>>');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(true, "changing the value of a field should trigger pending changes");
+
+ deferredResult.addMethod(user, 'saveChanges');
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "after saving, there should be no pending changes");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('getVersions');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(6, "the selected record, after saving a new version, has now 6 versions");
+
+ deferredResult.addMethod(user2, 'login');
+
+ deferredResult.addMethod(user2, 'getRecord', recordID);
+ deferredResult.addMethodcaller('getVersions');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(6, "the selected record - reloaded from the db - has 6 versions");
+
+ deferredResult.addMethod(user2, 'getRecord', recordID);
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(MochiKit.Base.itemgetter(passwordFieldID));
+ deferredResult.collectResults({
+ 'label': MochiKit.Base.methodcaller('label'),
+ 'value': MochiKit.Base.methodcaller('value')
+ });
+ deferredResult.addTest({'label': 'password', 'value': '<<pippo>>'}, "the current field label and value match", true);
+
+/*
+deferredResult.addCallback(function (aValue) { console.log("FIELDS", aValue); return aValue});
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('4cfaf1e782086e7527bd0e0cc82b67eb773e8157ad0c5babe516f7bc945a02a9'));
+ deferredResult.addMethodcaller('setValue', 'joe.clipperz');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(false, "restoring the value of a field should revert pending changes");
+*/
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'editNotesAndRestoreIt': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d';
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.editNotesAndRestoreIt", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('notes');
+ deferredResult.addTest('', "the current note is the empty string even if nothing is set on the record");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('setNotes', '');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(false, "setting notes to an empty string should be the same has not having the notes altogether");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'loadAllRecordVersions': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ var recordID = '2977aa5f99a9f6e5596c1bd7871e82d7328c3716c9ef8ba349ae65f10d97924e';
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.loadAllRecordVersions", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_multipleRecordVersions_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('label');
+ deferredResult.addTest('Amazon.com', "the selected record is the expected one");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('getVersions');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(5, "the 'Amazon' record has 5 versions");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('getCurrentRecordVersion');
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(3, "the current version of 'Amazon' record has 3 fields");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'createDirectLoginAndDeleteItAfterward': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user, user2;
+ var recordID = 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'; // YAHOO (4)
+ var directLoginReference;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:false, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("Record.test.addDirectLoginAndRevertChanges", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.setValue('record');
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.keys);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(4, "the record, when initially loaded, has 4 direct logins");
+
+ deferredResult.getValue('record');
+ deferredResult.addMethodcaller('createNewDirectLogin');
+ deferredResult.setValue('directLogin');
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('setLabel', "New direct login");
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('setBookmarkletConfiguration', '{"page": {"title": "Parallels Account"}, "form": {"attributes": {"action": "https://www.parallels.com/account/", "method": "post"}, "inputs": [{"type": "text", "name": "Email", "value": ""}, {"type": "password", "name": "Password", "value": ""}]}, "version": "0.2.3"}');
+
+ deferredResult.getValue('directLogin');
+ deferredResult.addMethodcaller('remove');
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "after reverting the changes, the user should NOT have pending changes");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+
+
+//#############################################################################
+
+SimpleTest.runDeferredTests("Clipperz.PM.DataModel.Record", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.data.js b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.data.js
new file mode 100644
index 0000000..5684dbd
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.data.js
@@ -0,0 +1,1941 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+testData = {
+
+ //-----------------------------------------------------------------------------
+
+ 'simpleLogin_001': function () { return {
+ 'users': [
+ {
+ 'username': "joe",
+ 'passphrase': "eoj",
+ 'version': "0.2",
+ 'connectionVersion': "0.2",
+ 'records': {
+ 'record 1': {
+ 'notes': "Some notes here",
+ 'fields': [
+ { 'name': "username", 'value': "joe", 'type': "text" },
+ { 'name': "password", 'value': "1234", 'type': "password" }
+ ],
+ 'directLogins': {
+ "record 1 direct login": {
+ 'configuration': "",
+ 'bindings': [
+ ],
+ 'favicon': "http://www.example.com/favicon.ico"
+ }
+ }
+ }
+ },
+ 'otp': [
+ "12345678 90abcdef 12345678 90abcdef",
+ "fedcba09 87654321 fedcba09 87654321"
+ ]
+ }
+ ]
+ };}(),
+
+ //-----------------------------------------------------------------------------
+
+ 'joe_clipperz_offline_copy_data': function () { return {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ 'f527cdd90d0d47f8524b4e165398ad1455eba515d04abd101d1e93b3c6ae0674': {
+ s: '186f0c40bf73f2af236eaa6c429df225efa933050c9aae65240e93b7b362e3ee',
+ v: 'ac61a6e325ecf329926a86084f591d8852d0ad3e4a6080f2adc901b82395ecaf',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5":"0","13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551":"1","062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80":"2","ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c":"3","507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a":"4","d5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d":"5","de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4":"6","d620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045":"7","f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732":"8","36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113":"9","fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6":"10","6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18":"11","9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291":"12","6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a":"13","6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728":"14","8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39":"15","084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d":"16","7bb69b6366a8012f181c01e368ba18d4f7a82bcabb4959189736ad124c4bbfbb":"17","5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4":"18","c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065":"19"},"data":"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"},"directLogins":{"index":{"61e87fdc4f1d9112e3b30c1f6812d095dcdb24f014c83319091eb6c9899ec348":"0","989593d4c48929f0c8f1581aa96969c622807e99619ed4732026e967530a68ad":"1","9f7979368fa29f66c44bd97ecaf6c545abc800b1c7bb21b7655a68e1514c3906":"2","dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496":"3","aa18149164302d5dbe7e2d3724565b9550e00887b49978559783b2e38c625584":"4","1f9bfd677b531a03168d3f8bd8afabb5357244a7bc355dff50bd6c0a072114a6":"5","a48e38845713462ecc9f827149eeaae87da882031f98ef8ebbf9ee9537b63468":"6","6f7bbc4e42ea462b5246e6f51c3f86056bec50601ce2de6067c8c1d26f21c07f":"7","2df54059e78f5771f23bd285cce19595b38331b73d67020424d9a1b2257db09c":"8","065cd0c270e5e8ce50e4ea8e3828dccdae18c01ab030813d756a87d03fe68784":"9","ddbc8d01300a4f10631cbde09e1246332eade3a877a2205209f9eb9e5bc9da0b":"10","9b7a30e667afc9f76ba77600658b2c13bff52432d444261d39bf3d069a160afe":"11","9fd2929cde3d32d9cbc5f1d787f2f64729a5e12a14410556b31c0c099762c46a":"12","f695fc36ac56bead80c0d20a88e01e382819c18dc268f1679551b7c83db7cb14":"13","f22dc41ffabef4b3bc8f7af804fec975bd50718098322a673cbe4aaff9464ae1":"14","03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c":"15","a7b32e72502804bf2946a2a8856139cbbb759c5777e6b3e673db1fdf7e3bd06e":"16","cb9ae0bba1957075ccdbfd3b3481704d62087687a2ac7c411a4f07d444bde0f7":"17","7e1d069b7fa57c03bd7bf48807520feb953157834503aaff8c9d493f37dea69d":"18","24404059cabc63b2dbff0f42ba57183108b8189ef53ab62fa25141a1caea824b":"19","33cf9758477460a8056deef0295a1ebe65b39b392c361ceb920a83edacfe5d78":"20","e9a16316f330e3d150f6ffd194f6fd8acd1426757b097de4b88ca0db875202e4":"21"},"data":"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"},"preferences":{"data":"EZMrwxNFFd1sMGycoYE7IrlGGrfLixLUnLZmWMkFysfISe2ay3ueO0PGCApuKqh9hA=="},"oneTimePasswords":{"data":"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"},"version":"0.1"}',
+ statistics: 'SfGy/4mpXQdDOv+Bcfie4Yt/',
+ userDetailsVersion: '0.3',
+ records: {
+ '062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80': {
+ data: '7sgxSQlqR+wh3g06M2+sWp7raQxjjQ9jLIz2OcEB7SckuQcXNrhMlDCbL6ncSljtzgqhioWrOB409kIG8lc7h6ekghOE/Mhi7rVwAiRfNGB7r3mYxpEXRe96O2RG7E+NcSp8ezl+5gJ9D0o1abXPeFQYGcr95hUioCfyY+xrxY8TJVwdb9nHkYvBdKV7rCl1dTxgsKWK3nlo1T7e5uyiz5YUAE6BrCtTFAqtprLI/xOpRti9C+llohS7D6s8hkCBPZfp3chKFDrgpsCBFLhXN8jrBKSjHi1PJdRQzpJsgrxyeBj0dZx3gTsYOXqrYgdIzFUo7K1Tqb30yNprBiDMr7j0YYXiSvEb7OuOIP+HTXGN+yt09bk9LggyY6Fh0e+tenjQQ3soySN/XznOBpEjXbzXoz6fR1MXVnE9GgaX99LVNqwWfq2rIBdSE/FfspRiWP3BY5jIrEkNeRclS05U1zw3K3wxOL+cB9r2IynSXnK8QcrDNNRZ0W3PhsSFfByUXuviLSEOPuJa1mYP29L9Lj/WyHL1Gyl8xLbt2H41S6+wvIleKMuc7teH6wPXbnYphvbwBowoI6HZTEFkz3dQKhhY6VF/81iCXsuaz6BjyrzFX6SkQ4S3lN1tv4opQMJFvnmHb6EkXqVWfeIXzJIJO+owL4vDOf4okpAD+HPjjlVXhq6fvyM5UBIK9+tzJW78X/zifrQOfWRIhwjVsfUdZWmZ/S35vnHWNuXkM8GBYrDysqxanDtah3U8XLAiIhFtBOzpzr6qGaNDOKKgG3K8QXT4bYHOq1rQVUwzQuKhlCyStrRMQrC5Ry251xmLy6dKfppRarVeGDtzB/30BbtFNdZmzMNG2g+Jj5tFCrEtCMvMiQEWZHMU3tGMFxDef/KKdv1fFTJC16jmaUiCHUZmNjB3EO9R6xPVcMlAVKf57n3efrpRk/GTmm9JhAFkuF/wsveH4JjPpDUdkHYFu5tHbb30sbga3ufBAXbQL4ck10S24akU/cKraFGLvuKGaR2U0i6ih911TBSf3pAfZ3RFbBhVIl+6rSknC5+IXoBR7MRstBPW/xC9pQVjN5Qyn0g3aUjUSI+q4jcTuvMl32NtTJbWRMGhfkrpVzypZTyPnIh6XJkyBghlUARXw23MlbjiZxmY4ScDmcWZRZJWIknHlqjDKFDKNnwrfnEI9qWyMDno+jA/DEQz0mnpdZYEsoz1/qAmAeDt89vx',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009',
+ currentVersion: '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3',
+ versions: {
+ '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3': {
+ header: '####',
+ data: 'GCNNIhDQjMJQZGVSf+95fPtU6eOnFWVhuGm86r8WZGVR2Gf2EjbG1OJ0ZIGpZ/AXgirCMpo5AFxJe0Bay8IYg+xmBqMFhwFxzAgJBYCIts+raSaNRipuY8dTEqDxAqD1cChcG8EhSoiFgQ0fG0I7nNEUDJi0pIt4/ygBcwvAhuAenEp9ZW+oQA0+YysPQRqkz3IieFaOoSEbe5/SqpUilV4q1gTVyzNXvrxzxx+rlvEyGFgFN+vgtUZ1NrwlPk4gVksTpylvv6CFaMGEWKhgMG6efo0rJckKosaJTu1pldJdnmMK4EKNMLOd+jZ6pEhEhYyadrA4+zYU5TlmZA6ASzTaps8piSwZodoi9qY0ch2StK4mAbzeEGe2HdfHuAU9Tyq3Ppk3+VfNdKgpQfYrQOiSlXbKzK636tzXTN/gyrfOTHjBrRl117ywibgSX63ayAYNfcLpKotC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ }
+ }
+ },
+ '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d': {
+ data: 'fGzBu1On7e/6rAoSB1a4fq/CkS8Be/T8UP5cQ93asBTWndSYu2lW4DQ4SXQXSindIi3OnNx/f6SNv/extb7OrMLREF92wXI045ipPwy+DIICb+cQNMJ82Sh4cXaIcAWcyrm+MYri3qq9LBKbpwkILcebZidJ86lmKYHJozUezmfbMcwNCljHs/gYkHVzVcuw9L52Ugc6wC7sjsshh+UH6i4/2Frlrophtx+b1vervNd8eoYiKnedHVXVfW7UJcQoF27eHFgzwYnGvRW0KNXFFhqmPb61TSkIvNdCCvBKDP4SXrWvGgzU89wipvWdUPpQ+fCT6Mp3hPRrbJxwMunmjujZOzBld/HkjnXoiNfBb5akA280WvdyzWYATrjV1ZFx8yQY8G0+lRt/MxjKDc38w4y+Rf5WeRbXboJMvFatwooHUggk6qSRmZVvgOmFmNuDRnRYIFzqK3JclhJeVasnqhR6RiGSowc1Ffr1HhcZCMnXpQABGBkZcHD/zw6YjHRyh9Plw7XAm0xb16HMDtiwt7WLJpxLH/HP99j/A2hvMGWiUiFCaYv7AzyEPTmYbN32D1IsAEE/GC3FG0HypGTBolP8wpAfTRdlvWpJz8oRRdwuLV3Pgpu+kXh5sQyeZI6tnuMPQFmRDcMN1oo3E5V5V585nVMnKTFcXhBzD4UnoV+DQNkG/+iSPybQzz/EZmucEqGEYyjI3kl4MAX8UMEUxE4JO0fF8MzyBI13nxknowAceEammx1dGVaJCoIOdhadaPVPyOzXM1Vp1erVm5k4TsxSx1pll+GOm6hVoNHIuQLDueaMEpRxMhfwc8cDyXURqRGPTgTc0bint5xVjo10fnpX1gcdc/AWL6y3tXM80NW+uFJ4GI7VzyzfcMRzTiRaGi19z8MIx8PbIVGh2sw4FhgGujNsPrpuESvUVT+17M0+v8oEoABNlcizTMFs/sA1uqlPumFASltzmViAzClOsDuCh069hFLjdk/Ex5jy4vPYlwOT8Uq9DJC9ZWuZgiI1DrhWN/8QGAEGxxbvnSZPNCQ9kpD5p+iabinLLWOAirVNgKwIRJRyAu/uR9xKd7J9Wxq8q/ii+y5lGilbo2g24wbDwrkXYVhqp/4J0g+p8Wv1NBjCTSCqV39WEizUCRHo3ee9HnQnBJQDOyTBRuz2odTJtJ5tLYjWXZRdFzFSJrEq+Z1z3oq7LnhZy3YWaFXPeKmBCemMthtNt0nL',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ updateDate: 'Mon Oct 27 08:58:49 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:39 CET 2009',
+ currentVersion: '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac',
+ versions: {
+ '0ae362285f103722abbd046eee2b7d10aeae6a1d05cbaf2081392ce9df882bcf': {
+ header: '####',
+ data: 'sG6TUmPSEPFpiJ5YdtghWHmHbvUK63tZCZ+Q5iz2ALas//jN+lZCBhZcjEwPEJskBkK2R0MyAh14wWGh2bBHMjsokgTe+L+x+0c/Zi0epE/IC9gtOBhsTe/hZ2e2xOGF/SbzET3DAAYXvxduZ36f7SvvFnrkkKvpj8wGSdTFcBmzqMb9DL2bRyRCLGLMzE3F1a0q5CufCIRz2TgHm+Uw+kfvvwC7ig/F/5iLW90Ypz3vmEtMEFYFHZ9a8Oh0rsXGfevbMhFqALoywzihQEe/NiB8dwn7GEdYKSQ35rhvZh29ULWOZinqmg0ONe0HYaxx7DbKsVoue57S0CIUlgHLajzHfLfqQg2sFI0OT8TnHsGg0YZ6mM2EdKmEjJiER0cP',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:00:31 CEST 2008',
+ updateDate: 'Fri Oct 17 17:00:31 CEST 2008',
+ accessDate: 'Fri Oct 17 17:00:31 CEST 2008'
+ },
+ '10f45664bbd979a92f37886f1ecc6e52e49798b16dc997aecd37259ad9b2090e': {
+ header: '####',
+ data: 'RdKVaV/WWWchrCse3KtcXd47Bfm6IAwjqVUpaxoed3HeunI42AAm7xYYSjeK8edHpbNRJbhobBAX5OZtWIp/HmgkobKM8CIiWxrWz89FqyrbnPD7+fXdtgF2yTax/0sC1l0ibncdOuJKX6U829oPlXCpXIOjlomc4wEEAD/5V6FbORvdZ9IE/ME3LsG2y02cT2tIpx6+R6wC/PKXhZA2UDsTE6R2Op2BtIzpVORZLXsdyAp/4wvWQxq90i9cEpbsVQsMB10JVyNHNsRTFhIlHi9MVCaMxQvcrwRElMj/Y9x3RbsFzSGKqFLqdg7Fn/U+KYkpYtsgHv9hraPIb9lV5FH16+iItU/HBM6FGezIj1ZkoQ+dgjPfSjTZzgzDYwyb',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ updateDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ accessDate: 'Fri Oct 17 16:54:23 CEST 2008'
+ },
+ '2fa7b67e569d5e268d2b70b3d4d3a960d7e437e1937bcb324b67d0b9441db8ba': {
+ header: '####',
+ data: 'dpnI2qKjk0+bfyKktw4ZCWf+rWZ12hO5bda39CwD29JH7KtdpLCLe2LoLd+KKF2wOdpDsoI2iTiwRgFpt77e7DoWJABxq/0aaRCVN9XpqZo08iHiYhJyNlIszO8CdEhX+M3AeZqzTnd6fs91VfIEWggvku2Z+jwr0CbclY6FnOcNnS+1fj+W79Z9XC383GOm2ujjfo3SX/fyNQSw8aX+7AgJIRGR9uHK7M1cVfsNNTbmDb/HDgLlYZ1Pqm/9poHpmS7G4HUoRM2/WjI0R6F48dy5s8vZRi11SCnlnj5oRykScJj6wh2DltbCyesiaTpAjP6MQjTXsZzKpaosaQcQClZw+w6hDD2cA54IaBIv2j5KAHyhxDh2ERdwbdnCsDKPz4+zP+fmKfW295d4OY0l1NCSdcY+75HWTmBWRAooZeDTo7AE8m5sRwxewE0Y8J2MLUYsrs7Rl4kbZCiRRHU7cs+us3fq2DVn2OLGEbkRrK3kA9swT9W8ABqINoA79+DmDaIr6TGxe5AlHkCAl5sYAN4g42UX1NKhl4fWI1Scj9O1Ixds/1UUvqzavld0mE2cR9yt6LntjE5sQSAaexvymAJbU5IIM5NTk7NlY7G3PEvAPjcUsL9SGw==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:00:13 CEST 2008',
+ updateDate: 'Fri Oct 17 17:00:13 CEST 2008',
+ accessDate: 'Fri Oct 17 17:00:13 CEST 2008'
+ },
+ '5a17723c34226d8cd663f91b11bfa14979e694e461818113ec8abf7194b46b6b': {
+ header: '####',
+ data: 'yRTvhkoY9zDRBwFYf0G5U8zhfS1XWIUfwes6ADNnFyOrHOr7JZvZZHSgkOPnsmN/f5ngcvFaIV9X3TNTmmPLzD/ewgGVMR+ofMLyOIMGhxUDzosSd1+HKqwDZWneZ6xNsci87W8UCfJgoEGrkAtAwktqyS04pcAas74XiRGBWNcv5mHZONwGPckYUnnaVG02Zf+qif6Pp7ugdvXrgncO5oi2AMSoR8GQxMP+tX53YzLwOpabA32PDT6o+aDPwMstJNQjWCXjeYLDIlb0GjL2zgjglX5CfdGw8vNT5hwGEK2D1FkvHkw79m++9sOWd5w9WdGgtS4mrTZP3JHWC1sPqvsIpq6PsrzRrbfCFH7C4X/ya5ciOIZTCNl4dEGAif94zgN74ueY5BF31PNFtaRaQ1waKkbsrU63MrbQbBar9b0hDZoser3BdgDGb1Ecc2GbJM1HbDITttmFDrzy/Ugh2kistHx7Dci8IGgfT7K94TntRFc5R6suEqYRrmOn57YJTZYrwSgbeTqAt/KOE+gL9LawiLJ0IdSC2RQnO3yu/aOEThHxpdLIKiVJoiEQXYVnq2UpnO79GNtplNnUe1hETQ/JT0o5X1bbENyInUsFjPuitAfChXofkAysIhDOHAdifc0Y+pxOHbQLkL65ZOsEDXWSlwMcduMNdQm4LVx26GLIV6yVsaDN+hGta2CxUuSvEIMM6T5xhaPfJ4K57LVw9MbOjRXpmFQz3QgEr8ZZdUxgE+Kj6CtmsjvzXtCQ3Bv/SccTLJSR/LQ8XRdIcPoOlDDy5jSQDF/8lxkgV1V7M3+SI1iWESPT8My5C+RH32F2MNZzthYq5hIFUB3wsM/AaQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:59:31 CEST 2008',
+ updateDate: 'Fri Oct 17 16:59:31 CEST 2008',
+ accessDate: 'Fri Oct 17 16:59:31 CEST 2008'
+ },
+ '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac': {
+ header: '####',
+ data: 'RgIWPbNN3sPkIPBE6lfvf9/EoDFLemTZe0Qh/1wZLrKxLRNzFpUk9+NmeGUp5f1hM3XjXw4cXRvP6GrWq69mz9zGja+1TA6RoW3dFMpSQkbONcrSD1mIjxV2zIvzA/Pangz0ZixbEeHCfwXLvgnevbTXXFjkti3kLHQlk2pJpM3zMl+rMJtcsefszuJ/0tE/bO7sBcFqcYgKAht2OyDQORBAGiW1kI9USKM5OOfJJIZDQ0gDhRgl2U92l3kIOO8hdnj32oRedwfKFmdSRkuMY7ykU0bMuVEVkLi/FWmhHxi66C2ovAztVtMd1IiyoNcHc4UH942GC4pT1A8YQpIHxBAJbrQVhpl9LfFkmJ7xUc6Xs5j0Nv8+z2JGCnJI/D4nDJqYW+iCYtRWu6vUmbg0vGfaYWQFGRZRk8zWfHzHXBvHU8p0QsIjYgCLKiUaU2SRRD2P7JCjeTUrm3I1OI593iPsEH9J2PHCM9OMQ8/Fsdgd7lWgH6P9jLdGUwtb1hGaq8mg3JGrHFXcrVkUEBfeR7xljeSHD7j4YahYrua9EeR8nvq6CNaOr406AWyHse9SXhaOxt8qXRLoELpyQPsaLgafUpsdLjJqHz7J76Rp77NSOtXGplKjAtU1xj+d/agaAKYCjvUJC8/APJI2890Pn7VSXr/TPc5biPEIopyVYEHFqaT4e5nZW1Ku1HXC9gwUwUI9rITG4GzIH1WMEm7oFLNUaSMrdK/UTdTJZ66ENE3B9v9cTUpR0NTkbI+iGKDnc8GHPRlr2ZJwN4KFTxi+o/kkEOBjvRHR55nRh2+dke75LS/fzHQZw5wlyqBv5ZeUZfRA7QHfkj9acR0fJSqqNX25AUzZQnRL3oVpOxFWCMU7QVf5VpnRm9OIOd/5F5EoY7Be4doM/UV9U40F3E6XPZQ8S0GKQzrDjc7jKyGPLNPLUWTmGB39mTNDHZQHh5Xv5Q==',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 08:58:49 CET 2008',
+ updateDate: 'Mon Oct 27 08:58:49 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:39 CET 2009'
+ },
+ 'b57a2d2ffafa8029123362071c09709bb9192f06a17140440f0e41d22143148f': {
+ header: '####',
+ data: 'PQ53T2Vo2D8PoLI1qNX//jLaVZFTDTYk6geT9+4RoThTxvlJ+beDPnQzgYhd9iASaF9GQEEL8JxsBnNpEPa6JPOY4ndFLmDLyFDKXMprxq1UIbzFV6kFoYAk3uCCCa3UCDzdr1KXB2CiiF9HrilaA+xkm8krAvH8I5kZD+j23gByz5cAFvXg7A77KEURpjujURL65DW5M+ceIjo6OXaPW9VO03xhqGt/M47ayObpoEGJZn+X9C8s0SE5wOXHbn38YZlRI480OMvtDAxbEYUeQKMmzu6lO4Nw5hhOUjoPSLr/i3tmDx3nPcDwnSafx6jyA4y31eW6yazqTEOP5I5ArC5mUrF7mAAiFvbHIsMoF8PLj6MONlRIOZgbf9HzCpFdt8xBrX/TXp3LaSAj2XTWgSTFI2cgmU3qqPyibvIfUsB5cVHQCXi692JpC+B85axJ0FLyMl5w3vq0txlPkf6q+dadPYDaLHGZEmDjkWScA1GM5xPJHWFwqGE7ejgXKG0sMYsMKWYk+F2LEUmMHtEvSlpgJBntvcQ1ZjYQxeu4hg5txu1ykkif6fXgkXF6wn6qu+5caeJeNhWtAB4q7WVD47111woYMdkmX7AnDTXSAQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:57:17 CEST 2008',
+ updateDate: 'Fri Oct 17 16:57:17 CEST 2008',
+ accessDate: 'Fri Oct 17 16:57:17 CEST 2008'
+ },
+ 'b713e0a1e2664ac7bfa7ba887329ea023204d10298973e322983b82b222debf6': {
+ header: '####',
+ data: 'H3gIieYrH7Oy8LEWCZpl9vGp9qYdHNCoBNGijYqlcfXt+1JYvPj1abPp12xLNrDUHfaOZklU2Ip4tOf0CDNhgAan7LYyPqFoy9ss2f9/5RLcbjwiIwSduySIL322HTAwqlzlBt/qaJdHHPUrczmu0fb7fT+0dO4gCL/e/IjcHLefUUgNPAbpHG0Nv0+4lNwKZkIQM3tLRtfJyFBIgWKcMcP1XMic33kr24rwybR8Pb0CHZrOOvvUiGqyoED3ZTZf1twUDVNXO7MWCAC5dBc6/Mk/vSmbbGhppXAH02N0g8G5qzZfp3UVikls55VNhRYLHByVsgpkbIrKXyZnBPTwzm7qefpYAXDOgO+164L66/Art2FYGqZQRZLuh5r8oF38',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:58:00 CEST 2008',
+ updateDate: 'Fri Oct 17 16:58:00 CEST 2008',
+ accessDate: 'Fri Oct 17 16:58:00 CEST 2008'
+ },
+ 'c4cea1cd88a86b05f48a99896a37967c3456228283a0406331ca9f67c6f29f97': {
+ header: '####',
+ data: '1znWPwc9JwCe7iOFiUd2iGm4xJd+824B4VRqEtzCQkW46tg25RWfo7XagvK46USB7t6pC8WMLU0M/EC47KucsfpWUqHGbseoXT/8g8E8GoLnIsk9qFyJG7LGd1sUvqBgszLZwjWWG3t9zifmpW5nY9GialBYNmeSLS3bg5xDH+eCEilUUfDe7zGuVSuu/XkHacv/DYUst97e+6u44F7H8Kv8dTywJZpqbmveNPeWfCej2aBXdVV616J5lIRaj2uIYuQYG7blYJh9KZ7yLStdPndl6h65hIJpfWo0PM8nLJuo0lWNHz7misrutnmxJEjkwVIZ5YAmqp1Zz3VC8zw4IxkXrC/sPmp4PaNXgKz9ZJRaY2KV69WmHf7BUQ3QneGngbT0tN526SS5qDFwTGiuIlnYGWvTB2jVrbns68n/d8Fps8sSWfJBvvXJUEkaZB+1WqNilOPGXvyJ5k2O/iucFbRlxwlEHDny+AgsbtXZdp8cHQ4C/O4G0mnUMZuS38gn6e2kQ55mUhxKeORM+J6Rx1y4Iiu9KKNbxyS5eBpAlFB4xS/o35CS4g309vyOEhi37F24bpp4pM0xEPG4mcc/IyChHzaHUGEp1IX1ZO/r3ut9RIN2QWrGLUlZV/9rFKpLLAy6BkY/g8VYNrV8PztOL3rqy/qwqNZouONwPw8w8SA=',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:01:59 CEST 2008',
+ updateDate: 'Fri Oct 17 17:01:59 CEST 2008',
+ accessDate: 'Mon Oct 27 08:57:58 CET 2008'
+ }
+ }
+ },
+ '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:53:11 CET 2007',
+ updateDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:25 CET 2009',
+ currentVersion: '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854',
+ versions: {
+ '106a1116d22c2395906a346da4d830c7afbd2da9a46210d0b7a11de238016783': {
+ header: '####',
+ data: 'jgDUvByveAFnchBQKhiHGYDNDtj/7Aja2RePMer0FCOkkEu5GRAiLkxA3/DD3eiU+g+mCxnjnOaEIYL1O5o0+JP08XapsblZHTRKfveeFfs6sWwuqEHGYULBaXx4XSfK2B12HgpBwa5aD49489AkuyXi7t/aAXcKKJcLB1sC61DI3NsmajUaXHBi31Sp7nKAUpMuiWyguW0JVfH6KUPqyldVDBTBqHAis37c1qoR6aFHFfGgAfb35+syfmPRgemujMRkj2XO6dbt9zAYlHVSYFp9393rwPZoyBfXMMdDtSTmq7H9qbmx31GecHZlFN3NymtPPDYUbQ9mpPVRbxE9NjtiPrI5eGFvb++OdOx75PKjYjCAPWWFZ+4aryNn+h+yqab7pAuoG03ACVVrAFIOn09g1ssol/vqvalulEf3hAIviedyiNAC9D0UDHtzUwyIiELvR9qouXLZ',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:13:41 CEST 2007',
+ updateDate: 'Tue Apr 17 19:13:41 CEST 2007',
+ accessDate: 'Tue Apr 17 19:13:41 CEST 2007'
+ },
+ '111a8a4b6b912b808a93cf5e8785ca223112628d05f0bfc5dfe1eb40cb72ed8a': {
+ header: '####',
+ data: 't524etHmXljCnLC+IM+WPD8Q5VE7wDsSHVNZzFU4hQzk119t/N/vhtfHYz5HgNstU5T8c7h7RHKvFk5f+4ZwgNgDqSH7H2PrH+7/bV8+uuqbe+/3GYOvELjTF7v3xMyYs1B7ruHpT+291HVNZqxajqCl/+9nbG0e5feqNsTXWUTdLzF0szJuCTNr2I+fhxAO0LRVaf8h+MBPYyuBDnfFDuKm899IsgF9YoYRvjaYO69DkElvf4VP2jrXIJsRnGIUfUaIS/wQ54+X4JBZM/9M09MVOw1SVe+cwG+P3xyPUkqnSb77ECo86C0MktzeYFmPnPv2SM2KFA6slctXsyudoaNlReh1k+6no5J5BjaawTfqYjYrAtWSPsuhxYVsZym/X2CVbkz4rMSn+J5Uio9N5uZ6AqgCKdhAJlwzVb3fIIJwvFpVpy/0LMskb7aG2i4eAxwzx1H6rD3Y',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:53:11 CET 2007',
+ updateDate: 'Wed Mar 14 14:53:11 CET 2007',
+ accessDate: 'Wed Mar 14 15:24:35 CET 2007'
+ },
+ '144d6eff3eb5f1cb70c8906741d88018cdeeae3a618ac4066598ad6b04242364': {
+ header: '####',
+ data: 'NPgSZF0eSOzy0/Ns+15Nz4bjSwh4o7fWYgKgwXLRFrF8y3EdbiOH7AiEmmPrCpT1raeYLWCcDIrRTz+/9uvIrz6kK6BjU2emr8YdyLai+PTCRY0SafWS3QiYixX6DJiKIt0SC2F6dfmSHwNsbfTHilFhVXn6wXTJpWvC+sRzw+h42cYpQp0BoLSuFV7vPz/+wtuQdl28BiBgLzGsrtPud0tPcfldGox6Ia/1SrOPcqUr0tnFlNQiUvPU7N0JZgRNyr1PfpAEhmYRI7aEJidsZ36vGQpE0ZQMmQE/9tLS/InALRZT1YXfMsytf0o3y4QlgJrvRgBL7fGiQOZJpU7igLk15xAwU+OLIaYIbr2xlKDJvndHOcrFoYKry9/A/aZSnEYv79wsaf64bBgIVD2WJGLuSFFmzlFnbg/O4kGTin3A8XBpvFA9V6iCMvnEMkrqxD3Qgf7WhxFE1A==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:33:00 CET 2007',
+ updateDate: 'Wed Mar 14 15:33:00 CET 2007',
+ accessDate: 'Tue Apr 17 19:12:56 CEST 2007'
+ },
+ '1f1bdb7a21440ac20c6d913d676aa30dc360252d27059e77df51a1be36b2e263': {
+ header: '####',
+ data: 'TaOHH6IoHPKLLoyLyvsBszgsPPcDs6CiLVXzXuXjFSTrhPxzUw9suSsisgDRRs0ncjZ6BCyqoCxMnw6QVvGN4viUwYVR8AWdCg0NMQZ+LkNfq/2WN0M3KyASI8sIdMCwTb57NzOn9soB1HmmmETZfjr7HpY2cc+lS5/4f5rxI8XTEK60lLed+aEuJamAjeZUdgIyu30mMKKjxPfY3Y9iWMwn1OD0zF0mAW+hyEoMhhK7EYlWKCy+4qN0QM+yNFXQyERb04o2n4XrM+qr9df1GtbQMH8igK5VzXIrKjdHjKoLo9G7D7mfx6mRLsmoAJuE0R8gyzotgdBpOgWasHJ82iWEa1dLRKBHJ1d0Lnumv22tvYfasx2DIR5Tmx3kIQ3hFieLSXq48cYMiaZH/IbLiapIOlMgtWDow8JuySBLei/8FAV8jCxSc1Ui/SjbuK/kCvywaSOhDVIxGw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:26:35 CET 2007',
+ updateDate: 'Wed Mar 14 15:26:35 CET 2007',
+ accessDate: 'Wed Mar 14 15:26:35 CET 2007'
+ },
+ '70720f026f37b571e9765d27c51d3d60c7be0293c3266f1f987c8de9c6b5c416': {
+ header: '####',
+ data: 'NYaYljcgfzrlN1DVgrbyj4AeVhXGjXPho3IQwEKD3ZOx/yEZxldCNSyFsrk7PoRB8Q1T/6VV4CGa4HLRSB7QVCrtVqWyu4KbbmFoX8NIQ0H3xv+TSo3S/b3dldUeyW32ScaGbspaf8nFf0CffsgpGusd+kHdiE3gSLJvH9y5j47KgpyyX4TteVzqgez4dcXIs5tdzJq2eUlknwU4651QeKIuRSmRaDRhhOP4yRgUo/qXMlTJFmHviCh+IumvBdmDoPe3Vc1vZ1r8PxpDJLvDoB8GTDE42NhqHfVrew9ym1xlTD9wswwIEikfOyTq3JM857qPOHRqSqthEvr4WHbm1VW5PReIyse0lugGyOzqtCnADp9NvNI440VjaTd4NBQqF7XrRm56+1u1uTdfYGFV5BRiH1KmrM1sxXQ6PlOF9Lou45ALo20xxvJOLKG0RKLMr8gmVT2bNtOSJw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:30:09 CET 2007',
+ updateDate: 'Wed Mar 14 15:30:09 CET 2007',
+ accessDate: 'Wed Mar 14 15:30:09 CET 2007'
+ },
+ '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854': {
+ header: '####',
+ data: 'xI3WXddQLFtLVzxJaZWQaw8wAgSuXLjLnyoNXnFuLecTH0BzU36PatglVh2HK3LM8aDLzzbHILdlLNnJ9CY+YnhmGh8hswF9oKTgq0Wsesgdc20QhSMNFFjmMljY1LSXmcAYK04Q5mIzi6Pe/04DRdj+e4zbe5QI4vEBhp/ohEpxZnNqc4BoX6J0eVf6LA1pwrKWvxzMxorWsJrrr+mn3svdlF437n+MMr89k5sQJogufes2GZ9tTvVZ4247ITxXqxgAhwXtbuIs/A5UqqnNdsxlHfpLKG5KjxB6F0h7TtFA3gkZCve5UmAibBnoBCFaIVWQyVq+VO9iqDm3DeXsK2pepvgIvpSID8Poy+uwN7T95mivAsHG5p7MtgN9KwQzNW3Iu+BfO9FlPBMngSk8L29So2CIXe6lEsXSGEi5Yrgyo6hZi6IkGCXwIQ7TCEMnlQEGyKnnAVik',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ updateDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:25 CET 2009'
+ },
+ '9588b523f39cdfc14efa1e15ea7716c2d8eac45d8efd7bfeb19d716f9df72d66': {
+ header: '####',
+ data: 'q6DKkxhgDFs1XkqOYf6dvojPF+yhJbniTLFpSOS+I1sum3EZIJfYxJXyi2Jx3KOVNBMILw1+vrSLe/fh5SSWj8ZBoeppkPPLjyRNdiUyd4IfcRM5OSv2YcTxCubKCH2kIMFAzY/29A6ZGPG+AN8/kxkEHc1fxKaNcj2Cs8qejNR8yK1iKT1Ut9VfEee+Eqy2Ohgdq8wL/xAD5mUzdqHeQl8BY16pXGIYncLxMzR+EJ8E5jJTuGv3O41UbO31lvBSfCt2pfz2MrtsuqNoI8LBHJkcR6t17Bj+rHZUniHlyxSW/1rQJ1NnwpPgUJ1fhfQJZM8Faoif+0bvWFY4xWs/tCCD7oEvf0xM0I3FfcJLbYX8M+wyO08t9BmGdEjnr3VUcuS9qKaJRpdpMP7aQf+vJvioeQDXdOJ6Ceo3BDFc6JdNta1Qc+agGzN2KPbIPrLDL+08hWl61yu3GQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:27:35 CET 2007',
+ updateDate: 'Wed Mar 14 15:27:35 CET 2007',
+ accessDate: 'Wed Mar 14 15:27:35 CET 2007'
+ },
+ 'e5b71df0d4d79a195c7ec3288dd7738069837a7c4da3bccc1ebc05d8e4f19d79': {
+ header: '####',
+ data: '1NvK9Y5r0Q880BfB1W5IqdOR77mmqQU0d1GL1XUeQT75R2EgYE9rK1X1jLygCXboPhxzegEe7TDhUsn5XcHN0LkXcLYz8gD/7+He2HiTFxoHd2oQbI3ceBxDJ7+5kWA6Aiqy42QSCuA+TWIQcDVthSyFU7nNdqNxeBYeXiI4jgwcH3xvm0+pBf1OYLtywjUK1JwntP6o68b1LMQJFinDG+sqRcm25ggaZyxDtoLh1IBdSpmXk0papRnyyTGNgsws78dLxnH0Iqxb7FhqYfgLDIvN3i7+IALI0lF0EuTS0hSPlr/1fTz1/6bVt++wI9GpUsrdafUJJMPerXoCK+gAP8EMneLq4f5487HIkwWh1qON6Hvpg+tB95NOSJpqE72VpVxN4+wTQWyDMhfjqXBuQ1wKvTsD/mUsdinU0Wb/YT/zIWBNZPdqur0rjOC+mrOtSdlYSCH89Jj2',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:15:09 CEST 2007',
+ updateDate: 'Tue Apr 17 19:15:09 CEST 2007',
+ accessDate: 'Tue Apr 17 19:17:01 CEST 2007'
+ }
+ }
+ },
+ '36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113': {
+ data: '6fhueIibbxKRA7Mtb9TPcWiUKajnikM3D7PbOROBkE39Vw9E/nG8KrtJlwwPQeOGCFhssO/KX3ymYehCR8rfaEL1f9pfdh5x69mSxKRlOmtEknWqUgPzcb1yPenRbQagERadh0LF4zu91M4WjXK9qynEHoxI/pBhwQb1IsnhwtXl4ELtajudv+2Hv3p75v4XOXFsGQMsHPY+Zw7dkFFA8EXhvuxjiGvnxCUkFwNICFRdHTEovkW3VSerLdrYo5lDgjY6ebr/g7wDGuu4RLfUK4+HpzFwZ0+aOrjpFq2ePg2xObvkkMNNjZ2PcR6Cue0sf+aNqzIHIlFPpY2Hmrob8+bwxocKA6aagBu7z5GiUmZNXGE/Vtr/WWBV2+xIJyzXZPet0MLmSnGiALjPJveeKnnFdDtA929ydcAb8efc0/snfU/uDoXDiO5SWEQ8DDNjj1bSo7VPTtvZyFormE1KjqimqSwaUJzbIS4CxPnoDezaBtQmlG4z8mc8jXq1HfPu7s9PUzcbG30gbF0ch2pDj4h47AhE0ZoeiV+VYZTaYateSifQXKBQKjPcuh9PQyDI0HVua3itbbwxXpRubEM4fbvlcd+7gu+Zq03slYICD07fP0I6XGrRHVTfYpDbEb4GJBvRIeZLwRTQzOeFbPLpBU9Lv3zXxfHfcHy9oK+giIxefPdY1ZR2ZFPKOO0xYJsTr0vmTuXeXzy56bKl+yP2lFst5l9QG8j2JcQEotDV1KQS6mbcLjfIpEnltu5fc2t10Q25Noh+F3kF+LcMIYsDjwanojYlOC93mZl01hmSJdimRTk9otjlRTyC7NWwiyy7fe5IyVi7ACNPZyeUYJUPtKWcPbT73Vtf8W3/+HdhmyYNyMQ9PDCBb9WKMon+qW2+ZVH5yv/KqMHRY1fflAfxpHNhrCkwqcAAGw+G/cetbvQjpkfVT2/u/uLupMsITN2Tgvr/8D2IMm3cyDBUCshrp0AfzARRygHFK4x/0uLfCtQSNjw6zMK8mn80R5aS5bZi5gRS8JBMZ4Q0iG4kBlLpIYtsXSBwl8faljjdl/4XvNNWWrdGJn2k0eM4cESlOFFk4s3Yu0Zspo17nKAHINjHAiP3VlhuKSnk5C9hMU5i3vZO8anQmx9UEwUgQVm22azCjyNtUl6jVPYSNsal7A==',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 18:39:35 CET 2007',
+ updateDate: 'Mon Oct 27 09:16:14 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:35 CET 2009',
+ currentVersion: 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463',
+ versions: {
+ '381201fd3b67549bd6630841e8902be1499f3ff0c3514dd464ad9679f22f3561': {
+ header: '####',
+ data: 'DgjIW4YcJAYnckuEUzBFkfEC841LuanGopPgp+YkyMn3xuzdpGq/ObLFMVQaeAuyErh1B0REHPbq0E/SRUZbeXLXWN720GU4GXvY5bnen2h7pHvl/H4yz+kvyKh3EHJmmBjuz8s0kclFJQB48lter+G93TEmUaFke9c9m0IkKlgzwZ/PQKZyIyfZA09KFaozdSxdFRbswZj2Vq8Df2PQsKLapZWX1wYQ3lXOcyvNdTULy9MCXwPwX6te6hTLWxQOiSPsvB8LItlhQUsSbrJcJEvWPlBupPu5SeI25zDnqKDETPep63Ks2GWf45nXZzYYmQMzL0l2cenYFxlE18TcOd1Ms24TQ/iDKMhi60zZoo13qjVT5AKZ80KNu46t08qbACxjv/LeK2aM5TNycTFixGskPywpnb6MCo8ibRe5rs1WcTJRMD04sNoiuriivO2fiyo4rxjfdyfueMlOz+Zeztk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:39:55 CET 2007',
+ updateDate: 'Wed Mar 14 18:39:55 CET 2007',
+ accessDate: 'Mon Oct 27 09:07:56 CET 2008'
+ },
+ '99dc86ebeb20a3db0c5393d6d94bc1150187b04316a876970dbbcf517b55d6f2': {
+ header: '####',
+ data: 'AJwqCWNKC9z8DC4TUI0hWnqHvQ40Y/x+jXylnVAkyO2QYQcqg51odLFSfgP0GiGEGPYwDc+kUxRrfO+ITgTNm+hHi2iIWkP/ljAC+AQ56MAEKsU/USTbvl6ShZ0XTAdRpwI/oqqOhYThVs6jTm/J8+lx4tWoMtNj835py88c/9eW26pLQubr7VysLSWuIMi+iDp7zXZZz/0gxGKDe5xNq4MGIYw8/OK1iJCOsjBdrRygLlS/Mz9sRlKkwdrDsohtRG0F/NdsIoaU4FttGs/rY91SCedvHy6ovh0zXhxOO44O6MiMbP085D1jCjWJn9S1RBxjxc368MGfMJeZja87nuvgSnLS2tGDL6zFtVJMNcH/7GqQPXZv/sNEykDNWpypchCnwYUJxvBVb45FcUzagPm+SSiekWK1hrEntZkZuEhQZp7Ud9RcENpa5h7wXUJSV1vPl8xBylx9HWmxez7D9OYRqbOlCRAEDqup4ahNhYB9',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 09:09:11 CET 2008',
+ updateDate: 'Mon Oct 27 09:09:11 CET 2008',
+ accessDate: 'Mon Oct 27 09:15:58 CET 2008'
+ },
+ '9fbfcd3e7fe30d549a813f0e6c1be58ed45c3ae7305d7367bffefa097b424ee6': {
+ header: '####',
+ data: 'nZ+Lc5LWWLxnPvUrRrHhxG35PHq7GMbVENHfV1oS0Qw7/63NecssNoEbiOwFVMjAshvfUK7IjnzyvfQhNtFRbj2yzHOTWCd0eJ0O0MmvGzjpUntSDu9/G8RFeEu9jDKugwi/NhOa5legjT9pcsEAqR4s4NN/Ac6juQb6D/Z6Wd6wO0JQhT5/QPk1KllDpDeo2i/GPUKvEi/dXpik0KQcVLVylU82rf6hwEgvRQi+j0O5hnFW1E4ttxClrnPBEBv60jkNwcIpD0r+rvomDe8+398xUuB4DVDJoM+WUYfu6Sm3qI0yBfET+tJvjn8WsHhKTgZpOc2BXC7EdF99nNEg6kV5pSxV6AUA1XUz5kW+YfcSzAXzUH74OqroC0SucHe4+BtRKnbJy4h5vRfjTD+FJaj1Va02cxSR55tQhxm/k67z0QeyB98dnU1l/pPHwBlIWa1eR74gswNSeQ2jrzu5JeQ=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:39:35 CET 2007',
+ updateDate: 'Wed Mar 14 18:39:35 CET 2007',
+ accessDate: 'Wed Mar 14 18:39:35 CET 2007'
+ },
+ 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463': {
+ header: '####',
+ data: 'm3yhZu81UAjCY6U2Knrgg8mK+LX35Y/iZgIEm8MuRDAlg6UUz9Z1Anu63COFV08YyYQRuBzTgR9YQ8wrUD1S9FG2ZmtCDemqvd+5OUMgdn4sK7G3CuzAc5osOa5neU2m4y19WuobkGnhO78ko7pVVjO42q0DeMT92uFL6KE/2UCkWlq5SdFyS5qXEJEWs2IO5C8nVpdlO/eZ36Pl2+v+afl3QQMTthCVIUR4/zVP2ajbO48yjDXhYxzskFjtXMYLApEn0wO0dcifcsYhPkozz6Locrt/R6IZXnfZfuW5XXHbqhutoJFPK6L6t0Ib3B2r1TNkPaMsVs2g5V1g3ENRd0IlbG/uBk2o5tgeu6gOYlA1scEiL+/ad9ZxiqYB2ENCGZ8DXA4VNMnzxVPbO96OIUCb9suV0fldGOg=',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 09:16:14 CET 2008',
+ updateDate: 'Mon Oct 27 09:16:14 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:35 CET 2009'
+ }
+ }
+ },
+ '507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a': {
+ data: 'ncSFmp/+n1pYUKi2fwhMCevSwFYO5irdcpOlSxC6YPOKYavK4iUbtBsilYWd0hpvUHW2ItaDwiyNFxs2Lwegex6dawKrpMYkPBcaZQDa746yACGgCkhz4MAGnUn5HCmz6xhpCVXMMKe3w2nEOjRB+pOMOeJt2n7aw0hCJ9tQ9JTFNrZOxeXrqoexrd210Rmr9FnKhLIvhNTN1/vXRqP0ys10omJ2mowzF4KoEVmz3ET6pS2d7tGjt9M/OYsH/ETWWc92doF5PO84g5/3HePaCo8NCqq4ul7AWJEbdnkxxmd7urJzIscPQPcoLxL7GfG5LhHTFyHlfFz9dNlccfA+OPftjyfjXTjLYZzbxxbi/nAB9Esqj5AoHfqaJM1ZOrZ+qAvm8Am3+HAXrqtiybDITrCLmGH9ukWDsx7R3lYTlvjArwORBUH+4w4/uYGscVm9kOYj/Rmz/ZMH9JibYFcPcOnr3rWXPFUL/XsXTrm9lzOvPyEYJmkENzd54AHC4Lr5vHpeuipWFLiJOrtn2WcgDG/DdLaYGKsmISXj74XDtP6Ee5lKOtbwwcmVNrl11UCQBEFHNybhXvpil5laKddOauLJDKtaDL/mKYPbr5YSk7HPCzRyE7HM2dC1MpBHuJ8g+hDkgU3wQcxYduKLRpuC0uOqrODigGWhVrdiKdZanlWUq9EkE3eH+E2A/CA8mHl7UNaH89XSvgV7uZyOmK7iZ+1kd9OzhBLQdJnK9qqP467Y14KsTt1E1+tqlqVAuK79QMnllaR0e3ztBRAQsyf5SD0KuSGXWz+z9/RjbhamW1s0UFRGh3voQMypU5RcYfYUA5KVg0BiVKFaiZBZKLo213hKbrgE2KoqVDEmIBFmwsu/S3EDzUY22tTB+o8ZKQiYesAUafGtnvsOLa+h6weF1ZvQVBerbD3fhb2o+d4ZyPkoRAsop+5it0QxsWuZL+J2oWybaikxIP/1ZM2ow4QZLaAVqihyHxqhF5UxZ9zrWxfp34BIPzzU9esSifrD0gXZ3mwutaCukZoijnGODJZtFOy9Rl1gyS1IbpyRbwz5O/YRl4BsD2aOk4InajT13Sa1BLPblQcrau13aeg/IzQhcUJ6n7enkrqiJFTP8N1aFAuYv8ilu0V2ymIuCLUtc4cbo7KyA+gnHhZA+DjjrhG/izOyWtQY/WtDsqvo/6ILwFk37JDjHfkchPEVcdl9qT7goG/4zTGX+lx8UTKKZJjJhLjA',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:01:24 CET 2007',
+ updateDate: 'Wed Mar 14 16:01:24 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:11 CET 2009',
+ currentVersion: '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b',
+ versions: {
+ '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b': {
+ header: '####',
+ data: 'sgq3FGcsnlbhTLetMa3TQQE6uFZv/JL6Awha1066IimKoAtQGbAr6E1+mxRmvJle91sL7oRfi6suvDanYHfAI+rrG6qCOtESn70ssS+aGFyO3XwFgypzG/Qa34bjxJ16Aqd93H8IdhzdtOxs2Qmou3CjyxbT7Cq+YW/fAo1WfctL4yE4GBNPWC5lfebxSmINlBY+zTjhv9Pf2aK6vL4p3obHl+zhz0YdKAMBwbDyCLa9tYvhGBnq/W6lFUsyZCPVJJP3bQCQww0TNCcLJLm+SYVSiC0NwCQJq+yNqDkWTvv41p5EDB06eOQ2VqC7l4i/JLE/ql9h9Z++gck74/Qs3ppdVdG7sTzWyPya4v3RW2OTc1awFRZipAX5Zd7I97dyw6Yym4y+/9UT8z8iMDYykQ4+QnOhksDIE9a8q6agDF/rbZ/BCRcMWbFylGTdudk26mu0GdPiuLDu',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:01:24 CET 2007',
+ updateDate: 'Wed Mar 14 16:01:24 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:11 CET 2009'
+ }
+ }
+ },
+ '5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4': {
+ data: 'Xs+z3VzIqsWa7dGBqepwq75lTsx3yemNhTdRYYDDc3Kzpycyp961SgnKXHjE51266mfmj85ASFi/FKCOwk17lbD5UT3iawtc3TdgrQ18vBhBsmOA2F4JAa4yC58bTaXbyld3c4izDp7i9+iyRaFN52NWJznN82SXuRtPdWRtAxXB1V5Tyg==',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:45:25 CET 2009',
+ updateDate: 'Mon Jan 05 17:45:25 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:21 CET 2009',
+ currentVersion: '00b3a4cd7400cfc1e7f7b369bdc3dcdaa50d6020233e131b30d755c89249ea9d',
+ versions: {
+ '00b3a4cd7400cfc1e7f7b369bdc3dcdaa50d6020233e131b30d755c89249ea9d': {
+ header: '####',
+ data: 'uGAV9pZTjrTwBy24TX/OUQwGmgzTnXv1JBIxdGkeoLCUhP9tAjbpUVylrUI5+VRrFYkXYyZ0o2HEgKrun2f3PODTxlmAbfkUldOV5tyV/EUxN0vYSBtgsMpqQm3bOKRIAo/uzrhSE3iwMjvKOTH2jUrkmX6hmqhXWZfa4X231GovrnOjek8c7t+LUBmmIjXEr2GSc/UbBoFnni+Q7ZArwtU68xoeCjLame1e8Y9wvCO8gIfAzXQAHsDgzn1MVeiWIqiCBTs8YKCO1yaxZpkzXV0yWzX+bHyXlKWwAk7Fu9w0CuaRULZmRCQhv+MMDw8DEXciTm0R5dRiVmSCFBy8cL9qlSeSX0GlnKl8E4/TSqvhMJblwJJsgmGSZ9cEt2u0E08tHxKuoeaaT1rpAOoiqx+z7BdhqjWOQZOGM4gR3EwqvOQoNYFUaXjAdmiUzW+e+TgE1IBQ8udRFl/D2zCcqFO90Hgc7hHsTDI3aGYvi6bHADu8hFpmZtJAjOMv1JgCX4Hm4n+SsbHd0DIfkEUMeGlVO47lcGWBZNRRm7xl8luZ4sZn',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:45:25 CET 2009',
+ updateDate: 'Mon Jan 05 17:45:25 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:21 CET 2009'
+ }
+ }
+ },
+ '6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728': {
+ data: '3oUg1TD+Lu4ou06j/MddOTXDqRM+qSKD+6Iuzia1Hop1w7v/BXidqeoKJZQI2VY9oO9B70Nr3B3wDROF+ycy6Rq+FM/xqUGHKXn1lAaSc6Wgj6TLQ6eRF6YZKSPqTj7TDWyw/2pEWk4HjcT8drTrCaC02tzAXMhYWlYPQPW4fUdq4hawoHIdopUN3vafQuFjY47OhqXKav3bNao=',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ updateDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:33 CET 2009',
+ currentVersion: 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc',
+ versions: {
+ 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc': {
+ header: '####',
+ data: 'fehYRMkg/wFj2t/aWu7szbXwrCyCDpjQN4UNck4/OiDlth70a2ve6ow5lAi2jgdlV9WiFrPejfa8dD0Z1g19jx+BBsuUYnBEKD0K+NapdJBBeI0We2nj9nYIij2dfZVx7cuvhy8sN6+DdylUQLsFHbga+Gi5hWcMuULT4GOAIy2WanSQL1RSR4ruA6zm/t+VVboEkkm7PPT+w3LuRl3wRaD4a8ZwYiSV/SzgWooFrh2S3YOUeshdaGCiYpTbXscsOxsCxc11i6wQGBqYSjksmtZDvEegdQdzCmxvq4jaVWJElYYS3av612nD5K/w7Zei6RccBiODBPATjrIczYg7HwmQxIM/6QI9/LQn0LP0yqRVUUtfzaODf0uWNpFzml9l/1lwXuBJyQFBp7H7Th46ekw9yEuPD00oZ+eXvKwbwfUU0JshT4hnEBtIjM8fH974PU0y95f0yLAJ1+M6DVXCxGsBix2aKJx9fuZP4KGpaXg6qCb/6327rph7MGomcrGPIiDjYwD/NTMdGluc55OZfGXtOZUaJCUM6nihqDwU7Ly1ZzYorgcvkX/t/0RNcOkFzGYNByp7mdcotyiHqCDKspqz9mEXAd7Noz3HO5GFpPqbRo7htDigGU1f7dvgbbfRoTz17Bt9Mw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ updateDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:33 CET 2009'
+ }
+ }
+ },
+ '6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a': {
+ data: 'b2mcYUi59l434kGl7ij6dBu3063UL1dToMIu3Zsa9RV9RzeLKnezJhLKunqoAm7KwiJeqDo/REexHI1cshGYtHasVXXuyJfMx1grH7yhoWnkSRF4Sax6w5E5wnGkEpGJHOxXJ9rOjWHZ7yqCUUCB/dqLw4FwPOtRb/ynkBEYztEJA6EKGJuz0vrrTOsT8HMXtj/w6MEZ7qI3fPs=',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ updateDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:08 CET 2009',
+ currentVersion: '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3',
+ versions: {
+ '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3': {
+ header: '####',
+ data: 'pZEWSdYIkrX8/r6OYmO0GEuKG9baUgn40Bmw7hXZBd/kfWuRjWsL4/pc5F5Ojrx+N0dxmQn5ZqKAzOOri29Rm4ruxnCbyK+oDsCDyMSnWy/VJcvystnDKzKmBRQVAOSEJtzEb3OtGzvqm0PQ1Dhx1YUAx7L6KlXysmG9h9+MjOcErRL9/1x1LZ33ytR+zK4LvTAb7gN5/9QgwysFyCkNP8bG4nyCzPMiUrBnP0odMTUvDkJDlY0Oia6VjGW6oNxnGIgA5fDraRrW4JH2oejQcrL7+X+jpCp05g==',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ updateDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:08 CET 2009'
+ }
+ }
+ },
+ '6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18': {
+ data: 'jzjPgxRHApIJA/6hiY4XCtb5+eKzHlOeoiGwfVDvip95zU7ThHbdmxOUomeyCOZ3S1SGPT4lHvqZgfVG5m5RvH3JaAIa8EY1ZElRohoX3rETVPJzI/Ov5Rp3lZjtWlu5meNrcJz811HBHrtBuJxAmSjYcY3CCal+oC2zcK2fLZR/iOQ+69ONVFhdV9KiOqzNf8IisIa1sIgFopqsdHXiZ9oLe0a7Y56q+OplyU3A+TmxKLI+Qq+WkjvdMzZDDqzYH47me5niugYPdkQwN6WQUE0sK9QPs0uU4TOwqCwN9nPH/DoQ6oXWAu2+R4iCyt6ZjLNkClbps4s8Cwz6wfFQ+4T8bcldjveJenmrYwiUzxSd/4xa34yFVXVw2OD0n8yZhtvNFvfoPy+X9z+Y4f5HlM0qzL9zYya4KwWjFQzhOxFjni9JyGM2PJ1BctB+q1J+CHuhlVjUF0Y5zIS3zFTET8jjDGBZDWB+Ao9E8fUD+0OJJUdKJ4kUfn4ZUZUG20eLBjmJqWBGYZX7UFaPv8ksahoK26Ol6FnBE4KpPStQeDgXZDzGsiLlEsxHJLUFkNtAUXozw38bWWQvi2VIFtkw/ZViPIenmSNT14kUVWdrlKQC8x0+wECeh5ffv0i8UUw3v8QC2ZE7GV0OMl4ySlRCuDCfZ53YFoB3HIR1hSZMhHlHJDPUz8JOuXdHcUQaJeNrfWoC2KkKb0ZecBj9iXooDh9yGi0g7TS7eyhlz1LHpzEWB0CPsZqhNGMxmfFWur7v2hrYzoHQOeB19ZSmWzfUwd4dRpqMp0x1lZaF97jr+yyYhnuQvuO6lru15Pg6FqjzhsNiLtaqtyoaMiHZ9veZs04qZZ9Fn3U7HeJzjZSAssdLnvopXi363cXm9JqoClyV2OemnVoRwOZN2gdSZxGeOefKR7U+lrBAbJwViMnmT0Nd7AC8C1k34iEt8HJmpztXeOgX5CQpwUPENMCUPsookFbIh7e4aByllEQy0gBbxUz8JMIWYyw98hdASnZ4s8bQfSmiMM8Iw3YxCexKB62LYYJn1UY51NSnwCtwRep+NhaKDk2d6SLh9owxnFbjhw22RriPd5f1InJycjtpvMzWLavl/hDsjjj1kWpnCUBTM46LbERmjz+s4x7fSf2FhhguBT36elz69ivXoiXI+7p0E8f8HsSwm8sgN/AA5m1svsXsdWeZFUiWtAwLg0tI8YNHlazbvFCXfIC6Uhq9eDv04iqdZ3rn2c1rwSx336A7ySTBFdxOCJ46F7ShIhNKm2N+5Qf0K5B2L882fbwqiLsa64+X9aKvufKTsd11vyf19Zivg/Ze0FWoGC8D63Nh91k6Hu32RT+uAtJIjQIZxu9yXJM9lMaRA8ieER+ghrLHaGQqF9J3WmueER3UzU1midvTynOV6g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:09:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:09:05 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:15 CET 2009',
+ currentVersion: 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5',
+ versions: {
+ 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5': {
+ header: '####',
+ data: 'BbXNAy0GcKKyDPiwhP1Jk9mIi3uXMHQdhuxpDvoR2C3YITOUBpurxGhhvmCg+a9pS+fKJdZPxL2mPbJj6GfWTEsm7K/ECEjrVkSTHi6PTUUgYVbCumq9EHjUspos+7VrifZry3c73+qAvIKamvUlNB86TchMpOXVJIyx8UgRX+bdhrxk9ZCEVOiLCG1zGPX8IzmcxPmBRZFlHYqE4ibhl/CLEzWXZBYCofTusClhOh7YM/jBgvDt64W7aIN2y2KiKwmFySkFZdnOvbAb34tXVimwqjqWPvPwd6MujQeX1bmaDD7Y0kXac8CJxqasIezLo2WqzLUbEXdIHGilkaPT2ZKpKhKkpHJHFrV2lVuQJVqwPUr0Gf9qMKgVnsyU8kUfq9ox+fhH70+v7BQSjT7bxxDLs0UesQeL7G4SqvNet5hPI4GQEpOY8p5MUFReIBTRm72NQEU=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:09:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:09:05 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:15 CET 2009'
+ }
+ }
+ },
+ '7bb69b6366a8012f181c01e368ba18d4f7a82bcabb4959189736ad124c4bbfbb': {
+ data: 'wYPZIt0UHiNVefNwtGc7z7Lu3YoQrXdfKmWqilZp8yeIrNfSLB9p60DLMrL3GDq/CsvDYkGAZgj1C/6NVnzVsXsJKq7NDZn1UPOGt+hCnw3lEVbD7zHkoMM4VgFDn1sZdjLe8wdpIFfdlQESTipT3GVXv3swG2qX2O2yuwtlopR8yZQTLg==',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:44:30 CET 2009',
+ updateDate: 'Mon Jan 05 17:44:30 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:18 CET 2009',
+ currentVersion: '23f5fb503e54c0cafe3d4944ddaf40bc74fab8b5d96e2bbddf693b1afb225e5b',
+ versions: {
+ '23f5fb503e54c0cafe3d4944ddaf40bc74fab8b5d96e2bbddf693b1afb225e5b': {
+ header: '####',
+ data: 'IpYj+7t3DhSVD8r9PkLbF5xpGrHhg8omY014P1vkT2KkGDEUj+ekQAbQ1g66Z7oNhRDpjS1/dcDjzH0IIQLjGuQ0oRfL0xZefVTx3N88ZLE39m3cJz10K2xyg3xp06jFBmdNJuCkgRhMzeUXeEJujw4lS2kv7cO04Uh2Maui6jDR7E498rgePY3L32vG1S66li/xU1vPjNn06aFTqSYxUL17/mlJNbgp3XWjGC+l0dXLLfXy1wOm+/I3zp2caTs+a2zDUZ15s+3XeaAWpBH7QCaQsvsQmoBqPbMvkjOQwW3taDvV7Hvkh+qTjCEcLjRFwhZkMNn3N2ewcLWQa2aVIjxt6Z0F4s/1URztWlKVzCfto8RmrLajYRn3ggG12kX2xDJFjNPNfs/7A3tMn+FqXQCCNG5GI06JZ32aQfpnjtmXScUuEs8UeFgsNeYclQhcm5R0sUwISK+D345B8859w+4+9OTY38NgYQQ9o/tmpCjWj1tLYLx/m/GcR2em7iyDpBdcnWUb+tK6Ah89qvXriHwPLSNzhOH2wxmi7nXTRQWMv7g2',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:44:30 CET 2009',
+ updateDate: 'Mon Jan 05 17:44:30 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:18 CET 2009'
+ }
+ }
+ },
+ '8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39': {
+ data: 'pOMTY3PnUAbwMLDEYNJCMzp4iIA42YWr6gqoomg+P40e7LFUtbt/RQRelQwNIztyUSVLl0rilkZZkBUVvxrtTqvibKITCjJQGQIzvcb+Yl4mNosl2Rpp0xxMU03f1+G7eGbuCc5hJXYVAglhEYplaAPzHbRWXMY8iZXZPBuLVf5PN+rdpgAfkGeZ7Uf9RsQ9p/EglrWXYnTwXi3saUfzIjfvSHm5C+dXTY3FHpIc1YkjFrdVgMkhYQGV60JtZcwFtCEL2NpVljAbRgHoIXTOkzUvep4vxrtfBBWWMuAWEI06432gtnH6IQbrR6jOpwuMt7k/09qy/fARPHs3r4qTJ9r2uqWHJ7tjJw+IChQPC+3l5HcPpFURiw8LGAN1NyY1hUrF6N84RSn7AKS0bLa5qN++5lcjjxn/k8+JqmeUqN1/SYIbGwNnJeZ0vA8yvOxnD20iVADX5kOVqJDwXRPLaF6Oz9KkbOrmANCh+PmGw1i6PduB+FgAU4HViYCw5IGOUZ30Pm1NJofqfbhXvgzn7ey2+kUIAwDyOUpJ9fW+9jW/JU4rcawmzwBYN2V8apOoyc3wQJICm2984wIfVBpygCOZM0QDyVgNo57qKtYH3yMDQSkKvpEUmuhklMYhcV+4X5ggdqx7lYXO9IMDnFf2ZDiZyieTlOlRv/nNVecUB177Xpnq2e+X/ik2rCQWVrIymiV6ltr1DEv0krXKfvXGG/FMZHUmo3m+B5bG4xVhmt0GnHseqvY2Vrl9NksLgq3hTDOGSGIy5Nv8kfrd8B4/6Tavh0SumiyXnrTXyYXzCK9E7IqO/0KAln63VkcHsbOtS8mj1drN0YQ2KKaeIW+Yr3Gm0pbcODsgA6aFfz1itZVeovBqUklhXS+/Es8J8xOSvvSyD/TmlFjuErHa+wwNQvftosfwk9ZTt0eIJS5aLHdU2QsCjdfSy0DEPkk2siGhBX5ZhRzqyIAyXApSmy+e7PIqn/dDR51+D1ZHwoTQyTrd+F08jBWZgU/OvS8MRxNZSxQwsi7bcWZG+w0utrIDB8eSOMVBXI5XBeJb4h5Bzut18C1shGHeGkSJp04=',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:10:17 CEST 2007',
+ updateDate: 'Tue May 01 01:13:27 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:02 CET 2009',
+ currentVersion: 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8',
+ versions: {
+ '8a032b53f7356e2d8b28665211abbe2cf1c79fd8eee4752e83cebdced1c19911': {
+ header: '####',
+ data: 'OXpNHHSkdsaD91hw2LER+9XKpf8+bh/O+OcLSgG/gAx228UpifOCD4HTAOs0C7IJ5zhAq1L9NjCGb1QWWTFErYEtDEBRBV4kogscP9HWPxYyZHxjwPI0wE7Ri2eD4Rma76Utb+xVnXWuT+vNb8eRUCK8Ur1rlhYafS0uzAYvVqHDNfZaICksxeVQojil/kSPZDMu8ASz5pMNFNCF4SlwDKPRrJJDbNZ62A3px59YJtsla91DGVyOLhb7VNRxEwnXyxENfP78yA6OjvQDc2KhKFUpHbZws54IolLK1I1mY/Z8BiDXPSnOa694Q1eZxy1Kx/jLINZUIPgGg1++YWITx213awOISdf7Oy0/dUpu10Vr1hgAqCVlDp0IuGK01CswRzEdLVpUk1DaGHuin1rryZx9vThUkEJgQQc3ivr8',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:10:17 CEST 2007',
+ updateDate: 'Tue May 01 01:10:17 CEST 2007',
+ accessDate: 'Tue May 01 01:10:17 CEST 2007'
+ },
+ 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8': {
+ header: '####',
+ data: 'tvSUu+NPKHkwt/ZLXdLGdDm4jSxTEtJfsecdpjJ9UGN3Y2EBCmijU5i7q+hMfNDqBJ4/m5Ayju4zYDAKGp2pt8l1TFoDurITdFcV12jL8j3dc4TTD//uC6OtowRN+altgC1Xc0LsSvEPabjAlwfVC5xqirfm5t2mVmnFZ/GALkGLGxRJRduylT6goPwfunkVGwUdqMa3md+9mwYn2gm7CyC0lpcKX8AZ3B4Oa656yRa9m3Wjgb007TtorLIpZO2MzVwxcHBqqy7YpN+zpmZz6Md9VK3L4F724tuXXWnDeVzGxBO7aZVr62hwPMXM6ibCjUScsaS4f0chivA/tBJoyx7OqKhBxREGeGjpHTeLxyHcekbwXhXyeqxBuwG93yGKutUhGLVYcXwe8/+xSeaBGj/j2RWutKbNKG2yQyNPGj2cxJWsR4YfOQJTSOSWT3K6Mmf+r6hLhIo=',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:13:27 CEST 2007',
+ updateDate: 'Tue May 01 01:13:27 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:02 CET 2009'
+ }
+ }
+ },
+ '9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291': {
+ data: 'xXZUJjgxn62OqnzAvScHJNo4WjYEFp1vQ4ueBe1sk8dH4pXZUKV6m9c1d2cLUgBj4rUNP5cC66GiFHV7G5BDZGLrfrxUlYU6BWvzAz4eG463pRDhHXQgPrhlIGDlK6ovaIsjwaifvHaEfLREoXvLFluqu406KG58guhtWdIFK0rLypyRo8uyltGbTz8wZdu8atY/JYQnb8NaAf4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 16:29:06 CET 2007',
+ updateDate: 'Wed Mar 21 16:29:06 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:01 CET 2009',
+ currentVersion: '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7',
+ versions: {
+ '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7': {
+ header: '####',
+ data: '7wg/yWfSasUjJKV/5ygFfteazVSdqEJ8xGAqtS7m/W2q3rOR+2fr99Il2TzxXCnOe5zV+iir2tOqPQt6BCGbVf0NVwZtvfO/lvfMc7DIwyWuhZ0sS44LBTD9VY9fruuIegktVHSNBoJTCIfAHN/ut1iB80+51An+TdpYT3SGAVM4RdenQ9IdvDOnQo2KE0E7BzHekga800VJrbqI8aJEtmm5mOjte2xHYSPFDCtwURQclwxbNv32hAY/IUkaejqg93WGIzHIIK0+SSDzQwHYQo4yzVGCKKy75eghpvGyg1zbzlv372bND+OuA3laocARFfe4rRd5I5nh8vmSJ+vybh3EIJJzloD+qWk6hsEagkYI0RYu9I2uOfA8drmZ02GV5/ySDsBHX7uhaTPGx4J22rNJoj8s1L7UoaohUHFvUerBvQTir2LPbzqT+B07wZOU0ibtHlaN5C2XMKRxfvGATeR+2J3l7WisCIoRdpQcPFHA7nlTTShBiCVstLxolvd7MMzPOilsi3ecxXLQSeWara4JILqXQCJ4yLbQCMnSpIrZ3TXbwbPZ8fjKjogHNUaBPnmd1hWoc7IVvK9RSFBEdCh9U/hbyPMCiSjdsUCTclmhFmhiVIlB73IyWixmLwHSWSl/ckMxcUK6rB0IPuWcT8iJkxfqOziFhMvC/cNydpN5Nj4WX21c/1M7lVlX10FRx6NIYH5szEXULmLnkfEwr35G9mKJwR2pgZ272UiW2cH64/+M+Kh7XnPbQKxTwVR3FOhR/qdSHeA8MTc9FDslFaTT6YSeJEPoQiLg4c4UdbB7w5nA0o4qg82hiiJbTfT2zFHZeeWOpVO1z4V8SidJrQkh8aL1/Is7KaDVNfL+Lx73gfO6tdSviCJJhD29iTgn+MW4MlGwpeLKpvq+LkXNXi/CVjIa1VqtR/Flk2BqwT2hccgw6E1ML+QdW1n3TvTtdLIvSGheOM5kLdnF76e8Nj0kHDFbnxQMlO7lutngaNBRAvhvSLccT76TMG4OTxNZk5aOre6AIOuUfrFD3KDeOqWie5zpkvTOd/JK/JDFYgbYQh8AqhwJ7VWUH49vfd6AqfwHwdNWymI05F6/0Co4xoQ6qN+iYNConUXz78Uo7AraJuBDQ3a24+wL2mLjnc8jUDFUaAKM6gZUv9+bx1vk6zVdaZcuqgZc6dcyo5Oy8lmbJ/SmRb8BF/Q2nW3SDv77R+p0bKPLmjcytczlMNct58Q1LoiLnGck5v0wByQ0XIMd',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 16:29:06 CET 2007',
+ updateDate: 'Wed Mar 21 16:29:06 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:01 CET 2009'
+ }
+ }
+ },
+ 'c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065': {
+ data: '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',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:45:43 CET 2009',
+ updateDate: 'Thu Feb 12 12:54:37 CET 2009',
+ accessDate: 'Thu Feb 12 12:54:37 CET 2009',
+ currentVersion: '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a',
+ versions: {
+ '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a': {
+ header: '####',
+ data: '/mnLRePyLGwPaZ+EkbTRHdE4jz4gY99jnHcIp7AeMfcktEpPmUVNWLwGSJUH3ANP/cO1znxACVQPzC+g8IVIK0muJ/lZ4Iw+HkpsfPtBjPZc+bfhsY5Mud00YBsImleIMlbbJGv3l79eSPcea49OwG30xro6b6I0KK3BmSgr+BG2AmBrKVlFRTPFCHRbO+hG/LgW/xqYgwd9f1dnbeVYCm5lA2zdAnwmMwlUIi/J73MbnsSO0Qg858iF1SPQ2Ne9Q8SCyKKEZwBY/YeSgDzoO76Wvqbzk8uPdmZldaF4zql3ffBeb9ZS9KIyyk2vJcLk7c3DUc65vaT+w25+2GSpEXD4YIV6VSr6Brz4w4gzcDMeLve0U6oruqWijz3CDe40yhd4mMt6wTVs4xo0KHc6yKjTuC1ZUQwZvuCiS8T5czaGpc0+fLyfuE+pVBxTlpOjkoZqzk6NsH5lcKMzB1TCscJ8fbOdtJso7DRUvijIE5+ayY9IktZhMeHsk2zurKV95A==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:54:37 CET 2009',
+ updateDate: 'Thu Feb 12 12:54:37 CET 2009',
+ accessDate: 'Thu Feb 12 12:54:37 CET 2009'
+ },
+ '4ebfe3bec6d419d61eb68a1f25407824e404e3439c23fccde1ac19225b40cb06': {
+ header: '####',
+ data: '6VvjRN9LKi7tt/HsgqmU0bUdZQNVjVAYNLdCrfKdRJCx3W/GZHHR/AQF0FcvuXIn0MWMUypHpTZW86V459OEoV4W18HXEisQKEiqBnUCBaxBd1NKZDpYsThISXXOhZSbXylbLoB+kBaYzT+Fc7utDheVvVPeMo+iEb3ih42B3En3ZXcgUAdEjfbRUm6st9Jiaz4onwXWknVhkF5QewA0GXDhT2JdakFxfUDay75wKvspq5IszbEYwsu+TEgsbuO4/R/bktgsQUrbhtKIEIiNSccDNx1JkUKvIxrRfp1m0Ar3XJsDfv7YSJSLdyVheOEdIpBkeZ40LN83uzGRMZw1bQsKf+XOFTfacYZBBzwVj8e1rJC6AWlH6Fbn0jXw3JcEljA4zUh5IrYhWtyIZW338UVsMSIp91USeM4uCvPsOLAdyCXiWu5H8MMYGz1rJxVlTbMiq0tn1w1f+CL14v8EiUft7l8kfZzBZzdLvzdedD/wHQ==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:45:43 CET 2009',
+ updateDate: 'Thu Feb 12 12:45:43 CET 2009',
+ accessDate: 'Thu Feb 12 12:45:43 CET 2009'
+ },
+ '7ef137cf242e00136e57ddd262edfe6b418b6f57f3b5e5e15f3ec1232867f6c8': {
+ header: '####',
+ data: 'N5eWFfsQGHR1WytyXuVySzJ3zenJEB6IaKr2vgWRHTlJFzexXzJmSLoozTP9Z4TumDOLsNrp+EUeIa3Yo+RqSyQKQRFDHXlUYa6c9PPLPXdexSA9JO3AHzMSpL6K0E4gN3BybjL2rbcQwUqJLvCKy44OdiJvORGfIIpTPx2LQ1o4P+chcpOwwe/ZhgLWmNC6FmkTvsU/xJlNuApyD7tPX7Cj3lP8WBfYEPr68BqTKAa9cxai6ZF4BRC//rFob/4pQNHE+7qjOSY9HOnV5uCtZehPYBwfpBiDYhaxWJxXN6sxtpe7GC5CM7gAAHs5lgVaFSWffOAL3zeX7I4vh3j1nYdXoh5KowZJVVUUfhwqJo2T3YDVsaXNibZIaPd9GlbeBBk2HL6c/ao6B8QNwRU7GvMHAdJKta2I9mtU2NCnr0Uwi4rZRR05V4k0HIMLEJxRo/IYAysAYETNIAXzk0twIokOF5JPjP4uTXRZ8LdiS6JqfoUu3Jv/7yq8wrKZM7DaQA==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:47:39 CET 2009',
+ updateDate: 'Thu Feb 12 12:47:39 CET 2009',
+ accessDate: 'Thu Feb 12 12:47:39 CET 2009'
+ }
+ }
+ },
+ 'ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c': {
+ data: 'zbQlGR1fT8HoH6KvOPBoaIjMUsVMh8MSNIzPO2muIMJDVfXB2rEcPnIFl8fNv9BtE9OLecuex3BQVJKGXdVGFYVNiSS0SgPoEpyD6GJntEIOaB7GnhVflTm8fT7Ba8ArS4r+fIL32Jx9F8sYrL6jKPWeuImGHK+x3X32uORI6znkRac7J727TiTPlbj03X/Fj3Of6Bp9Wa4xbVMwzi+R6NRKD4A6Za3mqhoSpYFeHWld8+ChJU/w2wFkj292OjPBzvvz/SR2Zth+AXTChreQ3Zl1hWNGmU2Ep8ijFCYwcamgPkQwh4vBk9NJlzIgadORcb/0EPDxn638VNA0dbpW8MZUCIMWVe3A8VgdllWxei7dDy1ri6xsKlFovLYjRRPXgAqRSqVATqwyXqhBWhoV6VZ5NaSUGvM8okC2GQSweLuz29py0F987MISmLjav4gdvcMA1wn7FOIaFTNg7oy2CxZefGhHT3sHfX/PIvs/ovfj+7TewI0k+HR414az2D5reo7S5I4+roCm1QLVpPNcXUxbAmEbjF8JCsTtECZ4kdpG39dN6BaMlHoHSN3wu05uTSn+sL7g3Cg0pVLlnHo9baw3fUnVJp3MCEgZJELaiI/WF1Om2y2S9UeLur18z5T7hHFv3Px28D7c22HEDdF2CObeh2uOlZGAa06lp7YlYeoNtb4CqLlZAMK0xIHfNUceC4OMNvqyGswd5WJsYQEnMry20OkxY6YinnQfjAml54B6WlvNVlg/YaKjw5AVinUHjzEFfQbcBFnFGpqg5qJk9hZmb1VI6Ujhq73fPydSfkvfScTImqxCNPD/BR8ovoaJtNpE2gmcoX9A5zhZgu5xUnUnXoaQu0l7K9kWof/UmCCl0O1A6j41aebWr+aoFMalaOPzNJ02vfLuW155IwjFQvRuAp6EuktZ2dFKyFl3QnLbwsMnitReXMoW30cqTYg7ODQnopE73RIb41Nj07qdx6FQMzw4gAIEFBe1iRvlMHQazZCb2ndVvgtK3ZcPNtDoahuPRxMLaKZlRnpa8E5F4o8NHYNivshawZi36Hk6w0dOimCiuk/zvJ1mtx8hhX7B5dsXlNcKxLSvI1onEm2x9HL318xJeT0y29alzPYVFuQs5kq1+UV3h2hL4E/H8h+5mWtTLf/MjaTZ09okW/etuHFFjCmLoKwugk70z2yLWEJGmbjw',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:51:17 CET 2007',
+ updateDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:12 CET 2009',
+ currentVersion: '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926',
+ versions: {
+ '3895963f82854530ff754c8e2d1eaef8d884a8cba7cd058b8b7adcdc12be3da8': {
+ header: '####',
+ data: 'rXmjQYZgxv9jpFus3T/qa9Qc1lxt+mDF+dmZeDmDG3IiE/LnonGt2MqL+YlbFzisF99Uv0IQGOZCPigtBwOXB9m6R6R3lEy/YhD/C6b10s80OBj3yr3PoTsoTmbnmZMYd4r+qx8SaoLLkR0aK6NADYZXebR5QgVtwF/a01EifI6YxH1wm1RX3kyRhIrMzOtL8zHbstPvW4sRtv2YpZqlZqBTdoiqztDUZTKEcCcU5QLnHYMNAVpDHE7D9WvQy8Il1taAbxg97Ir+2ktZLjqfJdKhU7ZLv8fcJiRgnQKPqDWcqpjA+CXM6Ak1HCf9SRJh6Hl64+fk3jEVAPmHvry/xq2RPCG2YnVNWZ+uL3QNuH4zt+IbP4FnrxkCAprmEiNwvuEefMgliGRd+FowIaiFWXcEtYxxQvRDujZN6eoTUU0KVnuy85PKi3ih0ZECoDM88MFhztwCG9/nJQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:51:17 CET 2007',
+ updateDate: 'Wed Mar 14 15:51:17 CET 2007',
+ accessDate: 'Wed Apr 25 10:37:27 CEST 2007'
+ },
+ '5311936f6a95cf123007ef867388adb5c1ec5b2cf1173d66e501daa16488e42e': {
+ header: '####',
+ data: '+VirbcZ59SiN9UJKrQkjQx0Z4avHIhvw12Hq7fs+Qnoz4RgCS17fqzYyJe+jYorjlMPjzUcALYOTobqJJp4Sp8v5nOilHW64Gny2XRp59PQPg0zE4TP22l1PzK04+qJusR5NLPU39hYbW+InkDapdIhdf+nIruqeA311bRLg90A8xmpzio6PkZxXmhZMabbEVfXsYFBQKVBFloTMusBG2eaxTjeK0hOAk0uEc9RGOEwCOvZvjRFCP8DyZ5T6QV1pYYgBFBwSFrB/koXmBmObj8zscJXQ4H4UWC0yw1B3ABbhNX7vC9q+vgZTxnGqI6GvzLcrzaXKTEyfa9twq+vKFX1hqDmM0UVLw0dPOy0/3tabJjFrYbz5EEKVin9UqWhuy5YIvHEJlMkH190Zo+lPMuHvD8TiAU1M/n1bTQSBQb/8STD6uqefbKS/s/bXcS+bdVKBmSgCuutBznYO',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:39:26 CEST 2007',
+ updateDate: 'Wed Apr 25 10:39:26 CEST 2007',
+ accessDate: 'Wed Apr 25 10:39:26 CEST 2007'
+ },
+ '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926': {
+ header: '####',
+ data: 'P1LfM+8PA/kyelFsojabLfBW9D0Aey5qDClz0OTdSamMT2Mv1U35eKcr6ilUrbtW+dKJotAzs3B1dYGzaEQ1j9HnhiL2pk4wgT1JWGe5c9frmFX/3YGO63c2ngnaC/Rrv3LC251cLVS1aoWNPskWkjZLzF7EiWbAeNYTplSa6MWm2LdHAm6xq2dcgYx53RJVvjnsCzpghQdzL96G8ScJjnUx8FC8mHW4Ds0rkHTeoM344Ao8J3o1XwoFqFFJ2X8+lSkj8LVVdjff1EHIicjrMM0oJG8VyxK2TxMvg4mnLWP4ALfh24Wrb9XmrM0NjhQXBo07tL9dwa7sHHKiBrM74644vBR7NB0+Laedg8D+6FmgNoR6icB+qvxCIIvAhOpJ0er9f0CGDDS06knx/lDtVVNewzxx4ATuG0HQn8M61eU83EfbKWG4Mg+9jtRcW0/bdFW/FQr/OeKg',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ updateDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:12 CET 2009'
+ },
+ '5c622bec0fb939da012beb98a858a4e16bd670b3e6fe1f7c92a247f88a65c747': {
+ header: '####',
+ data: 'XGlplDTD1xamZO04H6RiqcLd7XaPwxI3MqpKTCVHPBoMEkwE4A1izGjFKdPqHbQIuYYcT9xDgPOknlkP89jDTfcR4UfENtKHFgFaMee4orSER+MhldJRxMwPLorZmMNNZzVmTmwJS7FI9jYiXEvDbcyw41kN+SA0mxzWpc9emaX4TmZHzlBpY2zXKJLyN3otYYzcTWzuu7DJejWrB+CnNp925X9vVomBPfp/Gt4tiOFsE2ZyEf1B/7cDmMszlQgEgGJONS+C8Qyr+X3GEh5iPoYsGpMNmF7aYnZNciE/B5lP/ABVbZIi2KfmRlSf7Cc+kMkUXyHxOeZHuVv1ZlzfIe3gXlD0/yUJFHNju8ai+F3hpSkhMatf71mLQzD5oFrTmKatH+zQZhGPP9dQxG1cgZRcjbyUQJMazo+0TJuNXNndi/oiRzRJjYRUbZKsfRzIAEU=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:51:49 CEST 2007',
+ updateDate: 'Wed Apr 25 10:51:49 CEST 2007',
+ accessDate: 'Wed Apr 25 10:51:49 CEST 2007'
+ },
+ 'bad48f8ab053804a02bec678db01baf24de35ef04a17b90e1362e67fa352e4a4': {
+ header: '####',
+ data: 'SXl3D4C5Yt81L/117xsHYjZxT/fANq09VZsMNAz3Gcn2+2gopG+1K0JFg/1Mbjt4EMbe5Or42zBlJPo5EAldAfWu4MoTkQzo/wKPzgOWlIi3A9QwZegw3yCuHvJv8iNcpjGfpY0OCzTZKNomTtwc75l+8FqgwPDW4wDkPG98275ERDR8mFSZfUAiQxlTnCbskFneUQ6hdN2gywkyJKuTEcrMkIpzwe9uqPaQg8GjUvvy162/LVaSQAVRIiTbW5URCD+hT5cKOkmFeBejHar8zR3SQQ+tIJlKERBwfE0sNR+RebSboYxWPECYPp0DMj30FnHbfYIVTgRCIlepy2hfis0+9C7dop0jK2nFREjcxSIqonF+juCrfJDt4cTlpn2SmcoMJQsUOedSh6ZoWweXm7lu8buCbA2Q6SY1L6jz7okwIikIinxGDq3qT1pWSgpntI8wvYZ8RD0umJsoAzPYH9zlfQ==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 11:01:21 CEST 2007',
+ updateDate: 'Wed Apr 25 11:01:21 CEST 2007',
+ accessDate: 'Wed Apr 25 11:01:21 CEST 2007'
+ },
+ 'c03d1fcf5b6981741f5d4787315534641c61daee9aa3c063540fbb704989ded6': {
+ header: '####',
+ data: 'sbn5IDJM7VtYov3sqW9+/0USxZEw2xq8di1XVPMMZ6kN6oZZrAY7ukxXHYh+mfuIa1/uV4i4v1YCaKZQShLgUS4cchlK4nnNVL8zejGwB+PaY0E8Um/Jg6E4UAFAZ+haZwzWLQS8lJ1r4hNMTeFqsDRUhC30awJRz8e0rBejLZiS2Hk/jgpH3i8Za1GwDzogw11iHXejYI7MaQGB0E9eQsYYTxGjmzcLfVYkd4AKj5pSEHvsKZklSuWIyDzwaFiIO7xqcJmS/8Wkm63JGNOW3nLR5Ao9V/2vthFHBqS2lQNRnkPWXbmNK3v7vi57zu461w1Nn1U/70EvhHRMk8BdML3XI/U6WgDARjQuVsB8FnTkzapaORG5vUd7nTtWjPdyQzOqacm2YKWpAiG6fUQTZiBusEd8jdnv8BioGUTbXgNVG23zcRbbbEdjKc1aizXHQE1LnROvoHZHkwg=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:59:57 CEST 2007',
+ updateDate: 'Wed Apr 25 10:59:57 CEST 2007',
+ accessDate: 'Wed Apr 25 10:59:57 CEST 2007'
+ },
+ 'dbc283f49de6e303c06a52725b8187f344ba7b433b0158d704f094edba782710': {
+ header: '####',
+ data: 'fbNrpIoYF+gpMUjSxoOc9Y68qRlE2yk7FPPkrHTu07HHWkAWy7H7nFw4BwGiFViMkyEC2orUrMeDYhKmMYFj8DEcALk6452BtNutGZSoqDhD8xnSEPF6fP2Xyy+vZHp4JWDXZt/xHk4vPbxcwTTlmRz5aO8ChXIH5iqfRL9+Dx+gJDKgKmCRMZYMT1pyOUewmsT6QDYdGFJTRRiDmoLfCVAXhJRtqQSBcx3kN3kuf8gyOMAeJnFGISTAj7THzo7eGuQol1omTMgGbDZoL7WJNfZIDamiT9TWwzp3UmQcKIsRvA2ZKtePWRmpWyq6WydJgFXHUuUDVpwT+kc1Rn9Wq2zwm1VBw6gqKCp6W9bZO86rRMs2CtuLT+agSpqb4kz4SEYDCW0+aUsJDCYBXx5yWRM26r0XAbU6X0D+xopGuaVzsV5G7chkCO8mUsjHzZCK7hOAz6OgjR2+',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:38:17 CEST 2007',
+ updateDate: 'Wed Apr 25 10:38:17 CEST 2007',
+ accessDate: 'Wed Apr 25 10:38:17 CEST 2007'
+ },
+ 'ec525dd942f72b71b5fa1aca0a36a9960b71608bb27f32bc7923713bde021b12': {
+ header: '####',
+ data: 'AHP4MFiGukFCCnjLDGoqJUDEr6QNL+KoZlcwOqJIYusRtl5qmhZSsODHbAEpmadxLGogDPrWoH5/XLZ85ASGRF5ALzDgrFKP47/bSEzKVTDABY5BJSqvKgS/lCf2LdR7+0HWUVJ6Z3GOb9GqsXC70pMxDo/RfclOQPa+k/sXCW5u0TmLb/0i/dZEM8N++4umXsyy2WPLtUVzQZ/VdTMDwl50FeQxu3aNGy4qYd4XFk/7gxBH9skBD6/GqpNajHJrcbi/WZt7PZiN9skoVZHhm3YLmteP5hJnrcCGBFJHWuQpXfB7NR8rNmd2c6maemKYmUlX25wQF7JPcROOcyT8iYpF4Hk/eSPs0CSkaDdqSD0Nj9E4kqZrHfVGMwBbDFyAzdHTN3EyGuC4cBXdfNZbdBqwghuB1x7RLXs/pbXg1xqukjRdPLTxUogPdaQBHGo=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:56:58 CEST 2007',
+ updateDate: 'Wed Apr 25 10:56:58 CEST 2007',
+ accessDate: 'Wed Apr 25 10:56:58 CEST 2007'
+ },
+ 'fda6581f0137dd641387a7be193b06edea4451835817bcda38d22ee24ebeb77c': {
+ header: '####',
+ data: 'QwDMobl0Kds+J8mknphumnONOIF9gH+pC/AJpxGmuy/rvKfHSeEuuWAZ/yWj8J/I4V7OjpyTs9/uCWeKs9khpdkcxtObB36IfcbWBHGOgFjvqKgwMa7eZSIUPZz9k1NsqJC9nU9U7w5EBzQKVIjJaey1EdhsggdtNOpQTzt7iu2mWKo33dJKQCQ5VEwhpGh6SH1TgKFbdMkOJJY8d5xPYUxR66LVFpFzgHP0ML5M5U53PK+apT95UIAlqf7N32BjPK63Nsj1WPsnuuL0vWA3KmefHzwKGeatTdsgck+1mwnCDJncPWv7hTwMLGPUaY+Yww3K3YPihuyCUtUdV3fer2VHVAn++JdzerHiLI/86T8gHiLAi/anFFh6i2kMMVxqzREh+62n34MrgdMqbSFQb0V4Dhm45FVJH43uuEaoe3OJPtyvj1HbcSR4VEVgGkDeced8aAK+Dg==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:58:33 CEST 2007',
+ updateDate: 'Wed Apr 25 10:58:33 CEST 2007',
+ accessDate: 'Wed Apr 25 10:58:33 CEST 2007'
+ }
+ }
+ },
+ 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:06:54 CET 2007',
+ updateDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:23 CET 2009',
+ currentVersion: 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf',
+ versions: {
+ '12bd9887eb84b99ad40c1e413cccaa9ffd4deed340c71fe53610088faff349bd': {
+ header: '####',
+ data: 'MiAIw+S6GDmLLMcGtkl+wveV7dZAFrL1zGZh/FPvG4kpOBbnyaolRynNrL1yeUbEp4gLL2cK2BGYiVc9196PMOvKPHR5Rqp6GlT6h4RUJ+nFFF5/3LNGzQtJbiY0rrYKptqyPBC8mhlqtdK7sQkQonj5LPhKeCX6AyE3juBPEuFYhvTv9a/iRPub7BdlAocz+bb8ObpbVHnNvbGhiRpx9MpUg44JRxLQYhtDUMi2UFtURidKaK0k2lP81ckPDCgVgxy65FjCq05vSaCW0hanNrIwl+zAgi+3ChriqmflvsZYC7TQzUBPXrAQ8bKmzppZWlArIOppRF7+paWrHA3Qcz4uO5Sw3DvMwbgl+XINnmkE/EbA6VJOjrWYJjsibvbCw6vNr4q1A4Yxwy0a7EXbjFiwpEr+jMUhsq8+d0DxP3tQTusV0l9wcT2OWrDRKdjDUXLQOV9BVw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:27:40 CET 2007',
+ updateDate: 'Wed Mar 14 17:27:40 CET 2007',
+ accessDate: 'Wed Mar 14 19:00:21 CET 2007'
+ },
+ '35af99615d1be9d9841b4a37488fde9aac291c73c8c3aaa570cd05b3fd0baf5d': {
+ header: '####',
+ data: 'lv0pIfnhZZ6ktahFGl3AgAfdcveIcUyAh9x0iVOCzmQ9VjelBztlvxZEo+uByaFh1ptM+eqOFT/Vk9IKhNjRWTXrDXioP7oZ8IZ1kLfk/XuMFH9AgYzm3H1T/yLq5lg1WqqZ+OfO9m37Z4kbTjK9+adIAJ3TwsMxIDpIHYz+qbznjJocubYCbi+DC+4wo6qu5C44gf8n5QF8DOCGaBCyamxFvkqrSMo/Y+3SG3yt98MSgeMScGESuwKKGDHZX0v3ZXvl4UFbxywUtdbipDv4PAlzh0aadMsGqYwO8bPKEUElCWBXd6kASugaqiJaZFtb02EnC+nncv33ZSx+WyJqwKIBk/Kpd3/YDJnX9t3QU60j0YKf0my9oX1746F5u0XGX1DNRaw/1g95zRHoMu6j2cSTTX7CJglzIlTU8kglSO1LOasxm3Gt8iT+8+Lhh4Dw86ugqHXl',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:09:07 CET 2007',
+ updateDate: 'Wed Mar 14 16:09:07 CET 2007',
+ accessDate: 'Wed Mar 14 16:39:40 CET 2007'
+ },
+ '7cc6c6f2eccd8bdefddca21a59669655d7515f440b025144b9ba6b18472cf189': {
+ header: '####',
+ data: '3W8FqWzBVaEbMZRukwXcm03WbvITt8WVKKuJlcSszN0dCJEsIZ9vLAiDp6dfsFF4PEPcSkiy9Ww4FiBYSg5OLW6snRNdA7Wo62dJ3lqn8TjBzv/Rt+khf9mj/WwJZZ4wum+qdwTRPyaoZcAWgA6PAPPVp85iDBP8UBdiFOs+y5kz9GiB3psvOvqC9LZ/RyK3J+H7ierfWecnbqB9LT5Yuhfi8SO/gw+5vve6z1v8sVcexI0o8gk97rDV1W2gZz2WNtO7K5+233Z7aZlzouEbDZEOGG+zEYh6SctWCspgUATElf8vZ29fABsk3uZQO2tnBvINChs6jCRxnbmnjb2Y9R8u2QRtHjjvRro9E+zhQf3laJc0G0ZJp1zN0wwKx+sL7uM6kG1aszNJkzpykR/Uz8bKvoOfG9vkz9+4Pczh5xR+k9rCE8nbu6Yt4EMiUfdfjZJHAhST',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:01:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:01:05 CET 2007',
+ accessDate: 'Tue Apr 17 19:20:33 CEST 2007'
+ },
+ '95ef5754f9a4514e5bf883436d60c38c3cbb15c3f5452d512a05839ce20125ca': {
+ header: '####',
+ data: 'Rko0V7wG9GEmH9pZtXSfxKGDLRhZr65ef/DjkwhsPoYfLryET/ViMjcZcM2blyiLKOxjiS/avGGcXUmInz2AyD5dAFTGge3qAZ3QtxTcNn/fvfJeN+JyGJPIsTIQ7P+jd0uJAb3vPuymISGJluTsP0MZ8zxahSSRUV/VIYwm10tiMVvWEq0+8FynKfWDqJ1eU4pnI47CAdN9CuWhxi12RkMBYgiUzNzTh/tbPTFMc7DIyRfR+si6TuPS3PmtnKt4FMFAX3FznGBCNsonUFf/n7Zy+EYEU/B8wJO+18mqbui5YvmPCPPKiW/pfVuaWarF7zcIcthYoKQfTaCaulO0VRtTA+Wg2LtJv+QcWWWTiY2A9FC/PppLZ8+nFDeng6LqJYKoGnn6qwtSVH38s3Inzbs4r8mSOR099tqwfCnZc9zZHisdIbVm82H3gnqelPmc3IXb3nHb',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:17:20 CET 2007',
+ updateDate: 'Wed Mar 14 17:17:20 CET 2007',
+ accessDate: 'Wed Mar 14 17:22:06 CET 2007'
+ },
+ 'cc7ee01d38e4f1de010d2a235e3b76e838ca05fe70223b8358a5e41975bf2b7b': {
+ header: '####',
+ data: 'TJ5ClYK5JmZvEuNCA+/UeUJQ2rGXbPnFqWP31GAGXqhZmC0RuDNjl3sv0nFKmcdMa/BzvLSywJhkidoRhfKGwN8nZc8M0VpujFkpvdXgNsod6x+5LTMP67qCyvD67pkYMa7O+aosKi/ZWWnYBavZSdhyuWnU1wPxxk+wwcjjIrA5Tm5zTXM/68nLLnIWs2bQbUtcwHgLrBEUshG5oTUFGxrs8zYwodsYUuT1CVwODZrzMxvvbHfH6Lqt94m4hBF0oIrDCd1cSaXghS4PiZkJWQVxJNSsuYF/4PlPrV4ATZS3Jm+DqOxLOOnU2Xu1Qe9DxBppnXjs/WpohYuMV5YeD8iOJLXTQbFKhBJNSCoLp73QywWazuKkasC6cbBrTHYykEKXpt74iE6oKg67YrPkIZJ/jKEGnZ7wsY4ObeDTS7OUbHKxPHRM3ZrmB672R/8ktglg',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:06:54 CET 2007',
+ updateDate: 'Wed Mar 14 16:06:54 CET 2007',
+ accessDate: 'Wed Mar 14 16:06:54 CET 2007'
+ },
+ 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf': {
+ header: '####',
+ data: 'CiJDd/ShGw3rE0xCNZspkdH6hRzvSyaNiuQeMBI0NR1MReaa9uVMV6Ymj+BWVQ8FaOziQ94aolsWre51EKwDWC1otdovPXWHxBXBBI/Y5A4dyQisBeR5E456juUwDtLKX5En4iIuOL14IGt+keUtb5JyfBGuTTA+EnohYzvDxu9MDh/7nzCcWzUxh2zHEBSyowfOwJhx7G2xEvbBgTg+TkejMudbq9k3Owebe9QNdhU9rsY1UMxjL8+HgJmgyo0C0SA91tZXBB3i5ePvg++ze/SW/r+XO/nnVzcEwCJE2UWAL+vNh8tUm+sEbWaqyKwjHNSquxV4cYOG2Lzo45Wp/vZwiUR/8MK9THf0FO1mn3QCd/37AMMneI1Gqk0TNwNtoQKgLVBNhhgX7dIVpRxB2iiSBYyUK6N9LlFahW2QVDS7kdnKH3vk1cP50dj21E45jEhhd75v',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ updateDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:23 CET 2009'
+ },
+ 'd65b23008b22e5000726db3fd22b074b08553fe82245c3526f708b8d89f70963': {
+ header: '####',
+ data: '0y9WhoXwZSfzfxuql8LBc5/RiclPKQxcBYjcdGv7v6B+WuGrB6uu6d8pjNoUtsZnFv/25sefW3ggVgDuI5iZNg2lBQVIwgcvK5jPM5foit49d3RSWl74XdHY2XqykRNDbboKAiNfro+abo/YYQXjkhNBOC0dWSUUw+HmgK/Bm5NmJD4fDTV7OYFsvX4ExjnX9pktaB6aiLZWN1cZruW3Lsszx/ryHpDtcPrmK2hgLQ4FjRSXunbqXKJLOADQiMbGZ8DKZchB5NcEWlE3AfL6ybJzTyr4jXuS7A9PyitxYNKFHAHpJEhxGkyuhUE66QMt1n9NKzkNx6yhhGdIUF2zVGsBUb/pRrL2gt0X2lsZ+CnWFu4jRAeSi3KfK4VrvnoYkVlJImxPiLrzJAvqkuA6TyQRpJ4yFVJ0dgxBoxZVSN1fp9Yvkph+Os8LZscJtpYPPwVDlCnC',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:22:08 CEST 2007',
+ updateDate: 'Tue Apr 17 19:22:08 CEST 2007',
+ accessDate: 'Tue Apr 17 19:22:08 CEST 2007'
+ }
+ }
+ },
+ 'd620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045': {
+ data: '+iiHiN91FfHKOXC8Z/tg+YynPECa5sgYGGofcoJeXt3FAAkAFu3NsLuwjYIaddJiB3MIxFccrCrB5eDDL0SzOS+j63GcoMCeeiXss9YfVunA4RQTTktiU1BknPYfsfHj8EOPDSVHkPFs7KhAnBlgyaDiQPjYko5Np1H2i7F7pRmfC8W5LGdisaqxFDa+1ghu8K6a54QIpbfOmolQU3w7T5qiOdoZv8GLDDoORvMMb4P09IzXpk/yDEZe1GJ4g1a9t+lHAhiKSvdnZf+MhK0jvs6R6ALlmO84lRP34DmT/35Fr5C7D6EJl0OxXkWgYWelTlfU4b8+SStYP5LPYeD38fodSmObpKmpp653T1v2yaTybI1hojgLbH2DuA5VcQAM5JHMjoSy6s76mf2AZZeRnej1dqdvIOTf1Q6CR+ZNIqnkukrtGq/6elF3eZZh1Ln1EZDiTzsMxUHBngtiRmRDofqRSJUGbEAjw90dBoiaIO/WwLAy4cTec0nJxwYd5M7nchEly8Cb+zz7naP+vEGEAWq991u9NFZhrw7WgNgHnG0E3km+X+SYvv0i2MkqjYs6ItDkBNyi0Udnc4CqfWuKa9q04t8mZiy49LU34Ho4/ijuez3rdOeCO/oIwkRkLZYfFO6IxO56tAI3d6iJqmXY+DX0YUZrJ6FT7bDsUj0umV1htuj/uEgQZyOnKOyA8cSjOTMRIkodI12HrtdrIA966BDznsKW4F7f31VaSxI5ezHsdiYEsTqwaZlFQMsjfZX62EvDLJksJTe3JG15BNgsDUUh1mqIDCmVswFTpUTTb+50ap56c/uERSET0iXP8mb4hKwJkmngrBEir3btuMEMS0xSFQ2jTRjlnWRQr9eZT2biarzgEhKHyu2qCUtsUj7TiieQJY09EXCP3g3Da+61nBMoAwi/VqTI6vQaLGtuDrA2+VYGc8x1SiahmAkRPpQS+5N9qPvxxFRbKforMOvmeboFVxdKesub7BHIXQsSOKsHFZnFHswa/oLBITomp3ewfp125RjBUf1C3hMBNg/tmE5pgLqPfQqWK7IOnfdyt0jc391XWb6H3CVcgC8DcPKJ68o7DBucg9xTNwlIxBTafupsBa9JUkBigqYOW8729lNjj/QTvTUaCxWub9SDT6/y1wQUI1wyyg+EaR0fHqumMhIMbuvIPd/SvKMmZ4TXtBc1U3H3IGbkqIfx0f5rI6AuNMD7/pXTAy2Ot1ZBohnQmEotXRvDwxPMqBvPU74t3USTrysyXfJqeFtHi8GTR5X0m/PYQKWCCHgKvjw3d1CJk7tTe3iV2ulk5cnO7tOydTMJFgPuT2oyDDDTp5jYJPRE0OzZcpAzvRSjELfJ111sFBOEzTqtBUHA/E4BnTIM13md0ZaMr33E7ii8rS7vaKrQAI5moonAtAEOVbx/ZrcZ3kGzHpRCISeteHgnM4I90x391HqDkc1A7b+iDQF8OY0H/0as/3gaVaqs5jsuhIByj0+KmoXsdq3ZBhEQRW151QDCdMKdulNUxbKTYV/t92z3slU6lO8fiy+ON/6sTtS6jgnM+oCLxTfpfBdz0uKG7jiSOyunj27QxNjLyu1nF2+mAcDhtMN18QkJGLXKYv39kx7ny1H74i5rba32/QEAFl5eLJNIQbJZfZG3HzKMVS19ZGwgsYNqV1G52x5+bZUTR8YcrLWmPTJ322UxlhTmyjQv+fVCnpksBtjLGntsGloemFF5YVlcl1AfyHb+KlXiAZn+8vpfVVBddFFMeehokzYE1G8Doa/3huhqdtC9qvAtpP54G2p3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:36:20 CET 2007',
+ updateDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:28 CET 2009',
+ currentVersion: '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130',
+ versions: {
+ '0bea892da673bf4b3d3e4e97cd3e1645eb177a8423dc761583b876c5ffb1e2ca': {
+ header: '####',
+ data: 'BmZz8j6Khuz7Q11xPA5zSECcqn7BOcMtLx8AmX2iE4OrIwKWcZ+u4B5kCBxtFPRZWLdWcxAF8VfaedkHx5jxPNeWNIa7NEXXcFLYQv9lwUaxmtqodYtVapAg7N+onw28UnV1vB/h7ll26u263jWYohtd5eMnXhEjIEbrQYpf84jQYlpMKjUDhsVQeZvTI/KfiXa6O38ygO9R+xlq8xKgPPX2bkXfPJiyzlA+GoLSORc0tdqseGGOK4BFyp1V/KRUQ/7uQmGs1yNWt/ijaQtJXpWkWXmjHyTjXsi0z+1s0KH8TwSOfu8yjVshMyIyEDd+EsmZeK0QwMCm96v311cRhMgAkQOqL8xc2uRpGygtTkV2frthF237GOV5vwO9IoMZQFlvKZreV5mPPPBeqfP+o4QRpdnJRRCaP8Ds/MmzGBqE13ntwmo1UVX1k408ZtMCO7h1eQVTgCZ/Y2RD',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:51:02 CET 2007',
+ updateDate: 'Wed Mar 14 16:51:02 CET 2007',
+ accessDate: 'Wed Mar 14 16:51:02 CET 2007'
+ },
+ '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130': {
+ header: '####',
+ data: '++u0MEaILPK8riF0UzCnb+MnC51GYcdqCFRKOP7XYt5QvzWtxhDMOvq8ugCDF8G9sYPAoBLiCxFcuCtnkG4fp563VeEeC/dRnArzMDvjILYKAETgpnLQAfyIR+D8RfUkCbr+aOJ4XEKcy9a240OQJFDT0whoTKuX/6XVzVM/D7F0r+hJiOD1ELsVEi/+U+dXXO/VDxoyjFxfa1+M+Ygk8ewecX4nVqwOiFWHNK2lXW90inip0p8yqDsADx0KhE2tjARWVsjoNdf5RSUOYr0Sb0syyjBMi7oF4jpbLvHpu9fe8vpIcve+aSA/MF0Acxh0/gToDcO8ER3K4wcJgNPIs9lXiSrmuklK7kmS+uhz/rWCtZZH/OB/ov5sez5H51EYLmSNQbx5wZGZhtJWNN+AkJobg/Nt4XKRTe98CutbeiiYUGPxQvwG431Erg4y/q216n55FmCBIHZcUsa6Hk7ezF66c52EuAnVEkn7TZLl7vvym+sv9lKev31xpAGwX5Gy0tx2A7cSE55ZoyqOS9kf1s5Kwprx6RSBzfy7sffLSWHxyOSBnd7B1MNZglVSsbB1r4gMgZdYG//MZ/3IhTFbUqqw2xXHzTvBPA2Hl96g5Xzx0dVx2wHWcPcTSH23VrLscQCwyiDVINwmIzyG4CVSW/6gzA5VM4QYOrUDX2ZA5ligkZpWs0HTqmCB4SoqYJUpafaF2sEtCWHUjuVdw+rQiTBCcRTr8f1Vah2q2xbXMedLCRS3Vq4vlT0a/3wGgVD05CsAom31ZzmHQm94hZrx3FTPenhxLtTOHtDYXnbzYWufWEBSJs6VNtG9F5Md63NZvzEZiggfxTREDRZ7I9MBOPhrxz/3tAo+xInwvLXOEnTNOHVATm9u50kDs1qkJgqiXlxi9pZKmrTu4BeXS8cOxJ8O+Yb0Nh9bExfw+CC8X5xiWE58OwalxY2qlvuoR6mOqdcd+L7YPbGq+hJ/7WgJlrvtQe8IjGF1sJg6jfO8ZeGaPMF5NnbQVxGAq39g00on/z6dW0BLZyA6uglv99si8aRLpMk=',
+ version: '0.2',
+ creationDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ updateDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:28 CET 2009'
+ },
+ '63760358c7f5783d11fd769c78ca3f1ce787113368743655ade89bfa67d0d30a': {
+ header: '####',
+ data: '7lG/UvX5KjLbN+OrHbDeqXmweYeOL+0p3/UoLi2K93mCYdwsvx8mg+zghxwg5ITKPiZ9D/QWIShqiPpl+dvQJGWgs9EcP5W7k32CS2RNFaZ7U820rSpahHP561HDcBU1++5wHWszLnqFFiCuDja3OU90dsCTLI3g0igFgqpaRbjLcRTddI/1N48xNfV1YieC5Kei+jZ34zzrfKRn1f0F7mTkCqCSfygjnpRBgZyo9BfJ9rHULBvplvpslUUfFTShkLnCx0UbWPXog7DIZUCOwvPr3KJvmcZtCJp/1nW7gm0E5PaueJF10+ZlB6pKvueu+5yEgVmVu/lctmPX/UwTYZDgY5VWSWS3C+JNAvV87ZQKKmp8N6aMFMNOLCsOYL5hFN9uWGtMmvtgawqt7OhO9HukSUs8pDTgNeXoWyrorLM0cH2fa6a78GxNs3nCSUmqSQchJf5eWmASZgvI5xXmHXsNbuc4w5R9BaEPzyrrSAIa6r9D3rpFbUhMm+qPv9pZE2HF9liJVdWCBOSF8ZfCjsq5suyYz+YCsFHnwwpYmKAqJNXUMIhxkjgOTi5lNIsvS/iNSN9kdkeWINZk5iQFta34uJbGgjUhRy930ZGMBEV36T+Vb5tz50M6/MnlzAoUDeZAu54btKcrIpIq1Se+8zldwd6UKGq5nG+dMPk7CyKfZ5LkM065KGbgEJfHO651AMWp1sMAsbIAM6h1gVKbRjNyNwO+UK8eDpIX1nXHVj8bDVh96160cFbZj7htsUnXZh2AWuY6ahwdrGwYeSFoVAnd6xUF2oH+zFz2coLmLjD4Xm9IuQFsFO0U1Vo7EKUJHkPgIsXUT9He9tl8/K7UYQMXGgPTpercQFQ1ctFEqlPbFoVNO0j7Z9lmeSBcLdvY67CCbsoBDVJzj/wLRdBQStfeSUe7bEI6ff8+0gVkEFFACc48fWWA6NLLtvJkYjdojjA+C/Xf6EGNeXU/VENMJokB10EJUTueVWKHCLGI/JDBQBBB3HKX2VNFcEMJxES7Gfcbhysm5bdmltyRUJAIdXvw',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 12:56:43 CET 2007',
+ updateDate: 'Wed Mar 21 12:56:43 CET 2007',
+ accessDate: 'Wed Apr 25 09:59:58 CEST 2007'
+ },
+ '6e0dbb3c582039d985e80e10d94f424a63f0cb5b2ffac6388fd806ef89c1da40': {
+ header: '####',
+ data: 'f5hBUeedsvb1VBTpmpQ+XgGbnuVDMVEAdbEN7ZLK5k++4Iuw7l52zX6AHCWUFMDRfT6joiD2DMj0O8B2g55SeOQIAtZb4PZnbf3+ZEqKMOOI7iYSfo2PctLbzzzztma8EUXYkg7sJKCuZuyXhkWZxikBqVQIp9WE/bhRxa/atnB0jJyttnDMdTAN8kxIizrHFfT25hSbcPI1cSzsmF2nLabO6hLlm7mdLZCOD6DSv9hMeOXgqXo7XdfLA4k8swnOA/85HZFmhaYjTyoDGsK8yoJny/xBbiaRij1HQcHkbG6k2QKcs96pjmiJPoCv2dmsU3Bh06l1O4OEXl/RL4qBGJBKsDW/TXy7Qqa5y6LCEnlFAfefTHVgzuEQjJ2qb/z//oIrmujt+8hEa8F7Jyn6+FGqMNRxDvIQn5Ty/CPUStS1lNL1PEb7TA3ChYkYvnuhNVq8HHf47neGMpUwC5ppk5Zzb/5zEP0XH4XXkNbR5/TYjcb0Df3egNLSQLdO13CO3mKeoccmtfcmaFCtOLXWc2xNNcu09s+/QlZMuiu1TAzhWXU2CAXT7K794mTXHXjgGEaEe86Pj1nO1zHN7QhKDN92WMEdYasRAVDu/XYdzpsKJZ3POhNJp6pynotVBOkPk+2g04S8uujLVSIPZIwu7p3RmPQGGvfMviswhyPvSsPqND77j5msYOLCnXXjeXhOe0E7fIRpxPK1F6/N0R4tZCYNJe9Zo248XdqBvl5ZQWDC6aQH1E4djPK/08CS7/kAECqGqOCDPRvvMUNkGOnxsMx5eofr1YR7zWOZajr2GnfhA9fjrLv6KxXPVU0z702aS/Mfnf87ckGpOKA8/ssJiyZ4fzP6uN4pEb6wEta2DnnacUDd96nMvB9HvGCDoYZH646+n4oev+AnkYTy+ZRpmnsG6/3Z85iH3RwN6P2I3DWvGuN2e+1zQ2kaBMDms8qeXVY1+8qWr75ihizHCJr6E8Rd2Sw7xM0+6mKpu6gVGIi09auHg1+6Q6PlCr8Hy/pc4Exj9Hx1m14WKSF2SB1SYOnm',
+ version: '0.2',
+ creationDate: 'Sat May 19 11:26:44 CEST 2007',
+ updateDate: 'Sat May 19 11:26:44 CEST 2007',
+ accessDate: 'Mon Jul 09 15:08:39 CEST 2007'
+ },
+ '84f3b8571428014d04d7c05528af73c89cedf17e23b1f9541fe7060512f4c1a3': {
+ header: '####',
+ data: '2/zsq97zQBq8wE0oAC15HW5pbbzgokoDkLSEGniP1VL+sW3b+tXYOQV+VSFJo8ERNlCSoy679G7N8tPKgA+rO2/roGP/iKEuE38et9R6v9nhCPfo1vKt7XpvzJYow/qDwdStylXbfW9QN12Yx12r/nkPldVTXCYQDF0Vs0h/I1XMjbILpq1smbNXAUdn9I3W9o8KpREvac2H1ir2vYOzq9Ubhq4jggX/9s+FGm40f5MX/OM+lJGdRPCMG3rfWVeFeWEGWpmg0AXpV7eEuKH7sPrWy+QLXD1IwNE03QLhuOh0qEPsEi6kcCaZyLlCHYlzJ/hIAR1CBlCtGm+vqD+WRr0mGQtl81MMl6/BoW40dya/6aIKNOWfmYNgdfplknkVqxFsJnwVqjQJWfCzbW1KqBvMHx/7oPNjbMS0KKhd8ctOsTLSvq4zFI+mvR6BggwT8rwcfa66shJIaDDC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:38:54 CET 2007',
+ updateDate: 'Wed Mar 14 16:38:54 CET 2007',
+ accessDate: 'Wed Mar 14 16:38:54 CET 2007'
+ },
+ 'a4218c7ece0287ebad7f3cdd6510f424245a4d7d42ceb083b664a4335bcb7690': {
+ header: '####',
+ data: 'hQ123ZhZ4AiXD25P/0Laq3MtRO2oSIrY+GoYe3UAiyEHc9HZDCvR+POEEaARXNyh+U6z8S12P1GvQbzo23ZCt5byhqC+UmbfF3Y4FikM7WmHaRPtWjv8JNf3X0iJ9a2IBLA1BlqgJolnVDtrLsFx+6rBIU9r8pI2jdcsw9w9feRbE9/0S0filh66azojT5RM1qLcIUVWGixROY6PALSnA9PCjA6IG5WUa/DX7DyRrosZ9V4ZheMlzlz8CgEKBTN/HREIbPrEocBOvmnbupIEpOvH3OXKDXf39KAGVBAU2IIkOrGyWfT12p9dK+Zf+MQUl4DDIdAbF81Lus+LQmqtQ1ieyV0nNiqFhPuglLvKRj7QZRFfHNyejkMTZQWjQhBdHRmfSxyEgmFrM17yVVz4cMis/44g3szHMgAAfFIc79wq09oNDEV+ZUMS2xyBCALjRmhedqYIMGRCAG15',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:36:20 CET 2007',
+ updateDate: 'Wed Mar 14 16:36:20 CET 2007',
+ accessDate: 'Wed Mar 14 16:38:12 CET 2007'
+ },
+ 'c6613ccf0c1c6b65798c6f35657a10d4c6033aa32204a90d9d0274783a1098ed': {
+ header: '####',
+ data: 'ATU61Uq3Fe24JAEauMRtY8vMjzaQcPtnt1fshTD4dGuptFH9XoZ4bMC4XKHI7JKbx1NUEbR2ySOj9K/NJuWEGZjRgZbNI/KtuxNedlm/7jEpHQx4ZfhXQ8OiUDd+2bB9g6V0Ck2T1gM4IyaZMJ1QfOlYmGGv8n4flhHC5kUzL2OIiAxNHvKQjdEOccnEsk25Gg6FveKHD6NqVunsiCqhxJ84VBNzHJscuCTRcbt6KwR1+dw7Y+nhTjdDFq9UidlxTO0BKYsqj9F4Kq1LXORkSyab7zKooFH5kNd8torb5UFto8dfI8/+DOVHMxNRh2aWSn3O9bzwi1PfYO1nky2O6OKR48Y65Hp1sm3Xj4AAVHWSGakYUSV5M5XxKKzvoKY6Qqhz8GhbkzM2FC0IKTEcmINMvzXdzKRTqBFg6i0t7Qo80i3sQSoju3/4CYRozI2RrF8W4f3/0XgJf21oUAdTXOmSePSZoqhdejXeNQAgb89v+ZextxA6NJNYqvrx1NjdKmWKJIU+o3AgPYj4UIwWHwVADHITKrIWl/SbOsGP5aERtSiLnC+xqfRUOpgfkAYLcytspouHxvQjgNY4I1U/2S1DThG/N2EzuPl7GLYQ+Y3RAvLObFbrV8S3DS6vXIkigxyJT++MotIKoPBq0xDq0ck6joyvwvg4jXUMKlJa8/LQewJlbH8Lszx7SwjynzEQUJcpCnmxixzSNfRzpzgEBQSiClEEqArYykew3rjz9lc9nkdXUCzz81WYsvk6rGJ6ZdDsfKsG9+kaybuLL8huE0ERhznKDJW44ehDGQLr0phO3CI8n/9Px0PhPeZ1hvoiiH8CFSW5f45ZrFaaQG8hNyzWCpCFoX0/dNsNPsAkOJnO4v0PvO0HDOif1JjgPjCS51vBzxu8gYhkWlPo2hZxHhnnrbhxeBUU9jhLAx+NmxxfTjIWkbtHtVjm3ea/D2nuL1YrZKmQ3Qs6GamKlh3WwkRWRAVU3+/mbSGOISxo0u5v8QSmh/IPIXltniaQgWweqGNnCLWluuTyhoqnqDo0II7q',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:04:29 CEST 2007',
+ updateDate: 'Wed Apr 25 10:04:29 CEST 2007',
+ accessDate: 'Sat May 19 11:22:01 CEST 2007'
+ },
+ 'dd2b4cdeaedfc97c384f79c2878fca9a981efde6ebe212138db235e51b80c64a': {
+ header: '####',
+ data: 'd7ZpqQ4CTF00+/UnTvNnnkMXB2Ow/K9dys8V09Nedq4sgMUk08E1vqi9mdWbzNfRD7aV3blru8PfoRrxXRLTG/bjQ6xncecQoAJeUtSplKEO8fhuzGqbMqz47/y3aQDHBbygMAGV3wLgJO2Pv8p+8U/P3cEJisd9OqTNE+EYQz4eiq9dllMNUQjDY9aLHE8H0ny/5r9uohGNjXX/LfFMshjeS4rToCG5mzRaJPaRs1jkjzSntpF0RLxfU1acpJX4pNSuaLscdJ1lIwc17vygg6f3xexqvCeeFZBot1RwwbztZKbMfap4pRF5KoftD9bXJwoFMXigeMGLy0scpzsp1s8zBIwLhwUxEE0IBh7qeStg/3eRSW9slazuIR452O3Rysb+n/jWMyAhIOCSrnncjjH4XHbzV5GgT2d4f8jfBPmOT7l7C1ev41D3FGFxEb5TZGcJTaIW6ofLi5T5',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:52:12 CET 2007',
+ updateDate: 'Wed Mar 14 16:52:12 CET 2007',
+ accessDate: 'Wed Mar 21 12:16:29 CET 2007'
+ }
+ }
+ },
+ 'de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4': {
+ data: 'ZYvHAVCnw96hB+0XxnBY6p+vwvup1BopHUeepu7yOOSdYNFFOFEvtCbxXXoyVaKZAeSd2Vd7YEwRP4TTJjjWNPapT0D65AFqM8x+0rEjhmVfQGZAS4L3QctzRAgBoR1qTr0iqI/46ETkNq6vHz9mPLHEL3MQ/zoh4Pp0T+uMsY5ptzuMPcG0YwajSm5J8XXV2V5ZBEANpgL91xjgh1I9LiKJa/Lv3R9HAZG1uuCvzqjA2LWYeH+6ZcSpadk/UPxDw9c78FUnSNbHAcjuYZ/yI3v5SaZTjEzsB1MtAh6AFiHtvKIMWpqoOs7XQPhz1xXPoGZ7VR64A+/bN2h+Uqn49bQrKjTRGegqkEWFcBwhFH/ZkYfSHCGmZQTVqOakqyofJ22tS0ief45gYaO54YvIliTNTY7SZMRCEhUzz6dz8ENqP7FxhUVcQRbBr0JTmaf6DAwu86iDgkvcp1cY2trnUmlvrgz2GW6TgXoFjFlchUkHIByFeIJ02olfJg4zP8PzgYp2zhwmXL8iXHXnwzuP9bQKq5j8o+UhR11zn4MFvWQyD1UEplK6vphMdS8iXDViLrOwuMz1XUf7RxNdW0gqXwx+qLU+CeypyWLMIlgTlOr1pBqD/S5Jx+Gbn5GHQViuFZHJUjJsU0xel001KjB2Wf1Y15OSdLZ5l0tn/4HYKmZLufTYpub0xrss5r3Z72RYz3wvAWFXzkxWa+oBiRQiF6+ix8DBPTc3tm+ORnQBYcV/VNVRziimV3MFSsD1nHgIF1zu+eXIKE7/b3lzY19KpvtiBio94dejWoA/WO7KXWv2sHH0JoZnRh6lzu0HRFgYqVm/052nCGVA6XSfrFtfIupxdBs22C9wrwC5/Rwanf1S8BQIXpm25P4dv9Y9cS6c2/DUHcle4tsUJlqC+LpRGKXRdolFkiL9r01V09Kev/K2oXaWGYmBLbRfIyvEHyHNeNXv5fnaZ3pTlIwXjJ9K9yKA/1AKAsAEuKlM3N5ep9pfyuyfOWj1I6RvBwVqKvcBZtYJ4u8n9jrxiyq3ZZ35eB62D+ceOAD2s5+LL2IylYjiJA1OO2qpu4x9rt1NHXM6LYJAruBnUrJ0Ylqz/ElcJn/lXAzY6RLqVcZ+tuV580AUkFiaXFEDcqdJbbzh0R15g9DtaeiQZd1PG0a8Xblj9aMQoRDRJeksw1GWO7TfrJX1Cu4k+sgARWRzZ0DvB0SJAxPcmhg2iBByn2ESlcxPvMOpzuJI11BUQsZZ7dcynubeMvdqBeKsC6HMcm+8DLEUPmzsC3HIfARlNbt1fOrGJNuKaLvF1AAdwllELoPf3lQ6EVZI120=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:20:58 CET 2007',
+ updateDate: 'Wed Mar 14 16:47:01 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:06 CET 2009',
+ currentVersion: '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28',
+ versions: {
+ '201725aba7b4dd93531e40ee08eb8156e3aecd3db4f11e54d4d88ed5508c72a2': {
+ header: '####',
+ data: '4ndloDtoW1Mhat41ZlW+nN+WkdEriCn/z/oclyBFQSljJRlMwUFvzE/OCVYc2fQx1D1GBedY/O13v+SCAiJXUrr0dgrMDOfmYy7ZtNo0hYshjaYQucJovt7UQLeFAuLO6rNK9CrsYA/AWoiT878z2iCYCqVq41sL8juCm9n+d9aR0eyjXAKj8QJzVz/uvdudoGQ5xL18x2yUZnemY5gQklYlm0u9zzCJ3rLOENnnAggFnSJ0oysNjB2UwQY6P53bqXzF8E+u6Rv3OoIbmCIZMaoK1G5ivnWHwhLzp9UVdIj8ipfLsTJnGMk+aZ3nnEJ7wQCaaLy/lY2RYmSeUTTZt2ImK4ZLrSxRC21QkD+juyIiaEBJdhP8UOfcqE8Hw+etc/Cl0QgBtv9AgXD4BiZs3HUTXsV/PhIzP+6TGyr3/A2kt8dv33V7Gh2Ba+28wtsG/+HwCMk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:45:40 CET 2007',
+ updateDate: 'Wed Mar 14 16:45:40 CET 2007',
+ accessDate: 'Wed Mar 14 16:45:40 CET 2007'
+ },
+ '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28': {
+ header: '####',
+ data: 'eSAwxBi9CLckMV3o9PxBjVZZ47g2AOIsbPt8QMPta7U+6KKUm58cXHV7BDfRkbin3JYQJGYfu4HYHmayGt4IcX4RD3riftxnG3UFNqG4LQQ8+fwA3xTMBisnUSq0JYc/PKdBKzxH9x8moSqZC/cgFWe90p0PxdY13otjd1qvDL2ALAgY/uEDboTcLTbSEhpGIYQHtQ1ZjDG+KXI8J7atuMvS0KFreNUm9+uMZT0yCXwNpGy+ez2+ZDXTEjZUKaFPLI7g/vyySn6VMXmlqJftGXZ+fW5UWGaxb7WFa1hh/nI2okPuRlUQh50xXQJXVvanw1ATJbN1PRfYEfvQKLlAAwYuoB/qL0y0vU+3OktAbgBvwt9prs3IsqjwMeaejVTo3Yj9pQPJ14a+6lxQZQRFUaLePIPdYvq9NRM7chkNYminW0JN6umi6bvJ4KKTyjAglBQ6X4s=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:47:01 CET 2007',
+ updateDate: 'Wed Mar 14 16:47:01 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:06 CET 2009'
+ },
+ 'c7398bb27021058c9965a332d678b0070287b8ad12694bc8732346e6d84fe9a9': {
+ header: '####',
+ data: 'L+wk8k9ejeUeVz0offdItFpy8drMl1hi0FODBMKlPIAmEcNjnHU/IktOlyLrK0YHj66DaplXw2EyRkJNcMIbfACUtavxhWBH9VTftOPepsbsrU19aP6Xk7R1pr1sC76w1TgKCjE6IyBnK5qk1oHqcGv71GJLMmiqGivKyYOXQ45SH9tbHC4GUrg0YxoAYRwXqg+SlwRHpSZkX55NzPCEZn9eatGKCznTZs7pg0uBoM546fOIEBMgGndNk6gnsAH7At8yYxDMnkGHUctsSExL1O+W3bDDDx7D3uPkkjtd9se0exPru0fmsfcKPrcRkx8b8MAdgcylOtMdYvSudPdR6foSIqKMqktH35QlH6Rr5E/ire3O632QlmCieKDoPk/cB/qL3gKedxT1NxtC7SNR3aumKBAKOBDTVSjWWq3sIImQPZz+RUdRajeqkryNDVVPLFyjdC0=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:20:58 CET 2007',
+ updateDate: 'Wed Mar 14 16:20:58 CET 2007',
+ accessDate: 'Wed Mar 14 16:43:46 CET 2007'
+ }
+ }
+ },
+ 'eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 13:35:58 CET 2007',
+ updateDate: 'Thu May 10 15:01:21 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:54 CET 2009',
+ currentVersion: 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec',
+ versions: {
+ '157b5933272bb6b8a70bbabb7fa0369eb2660f7f0848dcc653f592f5afd4f2a4': {
+ header: '####',
+ data: 'z8BUTeAbrs5GeJ+SxaV9ceaAoqxtW/touC8xhjkEqbG6+IgMrfuz6ABRn+vwiN1/Vmfw/tyad4kB2SyzKgaYPH7rXyBir1mzJi73/oHsXv5wWNhEePmjZginGGcWQ0P4AnrAoxlaI8tXo3fbsz8e40x1b56N5J6zIdvX3eewgIMU+J+iomZVPDQq5DNu0aGUL1xs797FNm4vLQbVRF+mzrZlT4XZNzOr/W/Br4vG/Ureoq1QRjAjj+8HRt7ojmzrpDX3RtmSbWqUPQqx/KpFGqVUNw0zs09MomVIYilRawe/zegW2KZKK4rmqoUm+mnWQTf/I31FYO2N8dLrI7OV71EWlVN4FSO2A7NRUd92uVxHzItMQPS3CSQ57FYAC+WhJh7k+/ikJumVSf18pZRSRaEeKPxbJZFJqrWsWk+SsqBIJ4EklAnBBU7zLmMVe3GO/ml3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 13:35:58 CET 2007',
+ updateDate: 'Wed Mar 14 13:35:58 CET 2007',
+ accessDate: 'Wed Mar 14 13:35:58 CET 2007'
+ },
+ '1835468626573e6189e5302f6f354628f49900efe08adc931990d1c11fd522ef': {
+ header: '####',
+ data: 'Bv0je7USknogpb1ng86CEx6GbHlysuN3e5Iy43kg1iN83AgRm0Hp6/yMivQe/mEmQb+67cjHfKKrznAESYzY8uv3b+ystxoIaQL7tKJ5HYu2NUVvZxRC+PE7AkBhc+O28OzpZEHXXz62uZFsjRDw2hC/KP1XfYW+Deuulnpz6sgjuyWIYXF2486DzaycCqX0NmYXKE7oXAthOlbo+Zsm8Y5MWh5ploJFrzhAm0CCzjsGSa7NBOBWU2o6vN0NFMcOG2pdjZGWpWo1QQ5G9tx9UvM5pTamwcg5TOr4yOd16JmYTDjK2Fd5mdUuG3zIxFR8StIKI/Sd1ah8U+DGbNlVYAVb5OREJxQxVv6I5dxGC43CGWbpx3fB5wuFT3Jek6tv+LgBJaI9Ika79NFJQrLVMFbQgD0qU8YgCmLbxIJ4gxMBUgTN+v6PraIDHleYlpW3KVIiNxv2Ztc=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:24:49 CET 2007',
+ updateDate: 'Wed Mar 14 19:24:49 CET 2007',
+ accessDate: 'Wed Mar 14 19:24:49 CET 2007'
+ },
+ '47f73115ba2079f4b3703f502e3455498900a21941625c25d52ebb7da31055f7': {
+ header: '####',
+ data: 'pK+wAHWg4IJcixnFodLQ5EH+SFQIOMOrthx52u21WZ1ziRWJLSYGwA8CNNK8/welwzPHOPWu2El+zE6cwLHrzmL8EARLvvJ2fEK11ZIvF2C3R06uNrA7QFZr7iu6t67osrpfljqbjKQrMECUCUDrBywRvlpaeIlThfA3XByezK2HtbyHD1/xnyQSenUFu/6Zq1EkVdm9iCkbej2KxZSxA6qMl1WcnplBdOqBSmeGGJ0+Ikn3LZ7t4ztqflsug7QYyQlrmI+d0UB8MFWpf6jYjZQwf1rMH5XHFvrWUCi5IbFNJBUPF3n3IfUlrnjUSBEcW3tmodJa16/biK9/iKqh5ImlnpbQgK7CStgQ8ByJqddJre1idCiK/dyR1z+IXHTu4qm24cJeGUk7la4WMG2O5U/otFbXG5wTVgbLsxfXlE6fzxHAzvEftEE1ZPNOBpRZ+LVYEHKFESIz',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:41:15 CET 2007',
+ updateDate: 'Wed Mar 14 17:41:15 CET 2007',
+ accessDate: 'Wed Mar 14 17:41:15 CET 2007'
+ },
+ '6564169ac5bce1a632c602c51e9e5d637bfd4e87c1fa276e2cf65f39405fc4c9': {
+ header: '####',
+ data: 'fs5hydWDsT/FxWTb57K6zYKwVF310zjHHHtRS/AeBN8XZqTcirhV9oxJW6G6TdDkD7nQfWf53AbsivXn46Tx7oarzoU4R+1mz94TRCkEe5X2X7Wa3HbTj38+QwbkomF7np4MUkVc06aRPqkUE5hvSDbGn4SyKCjo/AnGhuW/QJIqnWVj70tf7CNTb+GR/y41JhJd7yk6U3cIP6Imik+DAvM5pE0KqxGLfLs4c1ChuTFNHfiQbYjs3tANqJCO185t4S8UIY5VxMRcnqgRoloFK3uFACIXoyDGG3FjILgxRCw2ePFsrm2Jtxv+JX4BsM+KDk67OsN91rjQnK5vBP72SzSge4EDCKJXYKdA8KJGYNwRIzk5d5ycbZgW4YCizVw8v7sLMn60v7YrDfBwXAJvvlTP1chA7HoE+WALqXkfBW29AOCNodE3eTXbI7iWz3vcWOCPvSm3hho=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:25:28 CET 2007',
+ updateDate: 'Wed Mar 14 19:25:28 CET 2007',
+ accessDate: 'Thu May 10 15:00:47 CEST 2007'
+ },
+ '7674ea33b650e84f9a461a91928bfc259de5549ce905339fc3b23623c6cfd09e': {
+ header: '####',
+ data: 'D7mLcDpylLnklOtIw/kvYX0M+CR6Si2t8CB9bTT3ZR+bTpXP88OtI19g1k9iPEUPdgbtFKPVw4oNmynP3x+pc8R/zzn4v697SvVtQxdF39Jmry5dnB4SMx6oRkuaISs0nxvTrHJe8U+s5ehzvQ2WWxWZ+LaoBWaYR7slgUFKLdJFyWEalPwMPVu//DoLZeWg19n2C/0Sy8u0DGdYHJVserWrQqxxg0h0m0x1wuKhF7IGvqgyJ31T5w00nMHNZbs89cUuqB/2doMgoUD9BqV7F/53AveuBDcdCc6jlEe8NOdoUyMuhwwwTyKONfjY5e5Cu5W9I36o7GpeKlckoKrTIWFO+NLG8XZvP/f2WJCsIOrCk/LI3C+bxBP+bK4tHRH13iXLeJYUlMK4ibcf8WI445qNoggJSbZzGr7Dav23KZWPcxzRxhI2u6j25/kKGnu4kcMB8ke5N+4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:46:36 CET 2007',
+ updateDate: 'Wed Mar 14 14:46:36 CET 2007',
+ accessDate: 'Wed Mar 14 17:40:01 CET 2007'
+ },
+ 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec': {
+ header: '####',
+ data: 'u9HEcfobxZhG9BY3dVG68ZUYkREFcZ4q1o/xWyt3qje3icA+Nu9yCrZip/4fqe1daUX/MHyzUQdulIfjSwATjj3vvDSPjuGvrtx8oUjJ/K6GFsL366ozi45LkqkOaH02/nVrb+ik2HWIgcne/OzNrwf1mWLJoBF+8ZwQ44xqQK7ikG1mblNWWbZFFQE1B0QPmE/I/1ovm2hAr1ZsNj1l+N96hwGsdsdVFTzn+S7Sg8GTbxEFAxDQkBYEw1k/R8i9EIBndPoDZCebr8vP+c8qSEk/YmBXJ1MGVVvic0/Utn67iNLz9aBnv2z31DvvBj8bIwOxQpB+tom5Ivwe84tFkwwvpxFqYccrEg4bbMcevUo67TBVe+Lb2wzcK0zOr7iHhswbXaLzzOEQ6uF/v2ibTbATP2zNq09AIJjynoSDmrisGHsBrHgeXjiDspc9U70PVC83EsjPRwA=',
+ version: '0.2',
+ creationDate: 'Thu May 10 15:01:21 CEST 2007',
+ updateDate: 'Thu May 10 15:01:21 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:54 CET 2009'
+ },
+ 'e699fa287c2de3d483144b48064a47cd0bc56a436431ce23b48cb8d8c42ce851': {
+ header: '####',
+ data: 'hVD8NOt8g/DIe48JbUUo77e2hMf2UBN6ah23PrIzGTpq0LifC2K/0/s0yeL/PHUOncdT56NccKpF8Fp6EWJqDKoKZPWASuB1vHCEkdbcxlqzqo98VS3A7p2JFwQzSv+5t6y909hhbxobXMCUfZ10HBqGo6TaFc6+pkYqQ/d7MEnj2NuAXC9X9TLLuZSrZ96NCKGr8YVKzxinxHdiF3TdRvIppFByXPlbZ3xiielEnYm6pu/GffW7Hkwd7Vou6jwyggxVqvoVtuAdiIy67l8GX0gQUGipFkvvrAkXfm0sgtWGQvpgDuV/bXq/L5vX/sFpWI2u066lMUOsJQmptNP/Nkp31+ZNk1nCcUIYDDa6vcOy/gRrOFcenPTUQjRkE95KPaCqYBSIWsjoFE0EIB+iBnBCTK3laBSC7pplOtuLCY1YJcJuOkzCVQCVXjhWrNJM77s7a5OyTuE=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 17:43:29 CET 2007',
+ accessDate: 'Wed Mar 14 19:23:51 CET 2007'
+ }
+ }
+ },
+ 'f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732': {
+ data: 'vxOgJv/v3pP8GFqbFLTcgtBqw8V3zhCN9rRXUuWAfatABtr3pySWvt74ITeGw+sDtApBsu+zTY/95BFVtK3y0QJkC5cjJYhLDwvMwpqa0lRfCXWSYmuEhbPETwkW1MN0kAEOMqsUD9cQCH9GDD4A17W89AoTG5Ce//X03YBG0cDjbotgENsWjQpK88LXABHBQAoTF0BPDjN+xai2QPCgN0l1IVpUzI87oZJS7x/4r6DjGTOgcc3+vtEujr+8dGNaq9xTEfAFs1kv6GMeT+R/VkIQLVO+vSxi2fd+954EAXQplt047+aZ3c0c78N6B+GhSi9DgNnbTLu6sl332Zdgo9R09uucS8nvRp3HcTzxriKpx0ZMDh9K9ig5NT9Z2H49pDjCJKTukDU7b2ktOEUNZt58s+uIlw1bMFY1TMETGAHbTq+hld8Szg8f7nJGDQF10kV2ykVEQ2oUBMC9y9VCLyYD0BWId6DUcTNXyI+MqAC4j8pp0NhURY8VSjtnV4Rlq+b48ahP/ifJdq+xrSiT9ykGqc/EyebC1uCTIZewk9MtIAndVYPckMIe0xQ2xhX6/m2bdNboVa3dnS5eKFdbd++un6FD+QAjgtcBkXQnwfptottZoghclKL5h5gPePCQL/66CLYy5+3xctfCG9u+VkH97JKL2hW+XZ/KuxLPFkIAYmbFKsNdIizfpbk5WJvoSzacpo1mwNjZ53zn9xhy/VkSIz3lGl83a6FyoHuR9VklyhTaKrj2JNWzjLaQPiR9Sv2eFNjLTivxtxLwKae5Tz14WU2QlXATC5xdcLeF9nK7yYVarcKlRsYkkvetrVpRiWUVfy9mZQIHOWJtY5AcptKso2Q0v4CuD1C/wV18DMDXzwMXeOq0cKxCsZOuWjO6RwWKzfeZnJ99S+EsFmdI/wxqiu9slJ0xXvgLvjiJhJ03qWwZV45peU1qmvKQrXS80QqLp3kUfRGLbZNOvkZbyf5OK96MA7lok8PuCZGg5jZHFX4B3vxSQ32P7VGSWO5CqHpF45YwtlONZKB0cuvKTRazZ+B2zJfwMYRQloj6sL5501oPqmjVtDg+0aoqKe5DmTf+fHV4FwAxQ8RuW7/BVL+lwf+zjtd31I/yrlDdb/Scs6yayLV026yuHxdQRl+ByogtrXbY4ViuU3NCkVrme7K7meRHnQdXyidhjzHdoJnRPa0IoI4VW3VwWNENRRNDTta2whOdIKsQYtscWBWZnQplRmDChGikERYQVCWejDNgvnbnGrlyQYPF0/vcv6PoDpIvh7Pze9y0MLBU8DnWqAhpdqHPNVdjdq51OKlSitUk5TSN9kxePe0KNFZueLjxZHUFIZ+SIkTxoCoaRWYMJIWvYkcT5S9Y/7NbdapuUaLZNGDc6tgD+LVYRRvGEdPWaOHb7G+qOmdtx8vYxZUqq5mtwnIBRzEllTJyKwwK/kOfAxiRjLxf7SOXsubPuA7bHR9fI5rROSR5rcU+nOfSV9Wf4wZkYBlSmQYqzQfmwl0UCiipJVa1DwYwLimgo2RqhI0M38gEH+mrknnevE8zlUIaEWzxoOnyWbtCecakXS2XvE9j64dswJ3bbeQ3fDQr1308x9qKSjFdDl3eNcJx2e9YwC7wZnTmHeHzRXnZwXsJXqMPDQV99wEDBr71BjlDjMx7vG9bOWrhsyJ37EOvO2X41Ij3j0X4MYpbNgxBFP6zJSu3gILrtqQRpQq6mQJ1bWHyCN1ge1zKNT9pG6rGTRPE9LqHROQuROpgFM1R+DqW4XnGOBYSOtznnsnj5fxfdpGeFq+v/ftvVuN5XsgX6dnT8R77iNUs86Iz2mkxLaQokkNzXl5o1rnQIse9+kcKVZ72mf5SG9s9DD7cZ7bOtmkuZCexJpieIosqLV8jc0IA',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 17:39:39 CET 2007',
+ updateDate: 'Wed Feb 13 15:29:04 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:41 CET 2009',
+ currentVersion: '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74',
+ versions: {
+ '33ce5a03b6d36f59d0fbc9445dd01a515cb56eccc6d854cffbf8aa66f3e4a45f': {
+ header: '####',
+ data: 'pwMmqFOwpW/uSys3hm/AcoERF3eDj4dO+O5SdYsR2mJtmEfXcjhS9altLhVOsck0KMQJdxE3rNDFbduF35yVetXuQrrL+bSRlXMq03EXETyrRzIVhFEM4BjoCSS9nKGgixp04Ve9WSuwD4cXRmcN/L9kCJSCqflXqhkYkjAywQoj1KxHPdAqMaGRpEWioUIfX+NiWbO/qtOu/USAhHmWFXla6/A9kKQeU2d+P3zl9KF2Zm8qm8NXjPKmh2dkd70ATbdzxt9P3BafoRf/Ud8zLIVdQYTbv0pn6UMIiUDRK1ryvgfSY180zg4qkP5pBnxhEgOxbjT8JO6hCl8n2jUCRJLdUXHwgpeuHcKYDyZizc+p9Kbc4+d8K/2UEKgSR6gza6Cpw5TQbZQq+2LxWUoVb3HM3lTqBKUPM0FdY2/3twZm/1bI1uBMPnyp9x/JsQV+xOpu0ZulTA==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:39:39 CET 2007',
+ updateDate: 'Wed Mar 14 17:39:39 CET 2007',
+ accessDate: 'Tue Apr 17 19:09:44 CEST 2007'
+ },
+ '686ea579db132287e8e322194652ec57cba6e60274c00f734db7a0b36702c817': {
+ header: '####',
+ data: 'ilf8U30hSq2mqje9kZkKQAMiEFV0aptXrm8fOtoOR8pp36V29kXyUX6FEOh5eXSRr/jbqGytxKENJeAGxnsv5U+8GgbvlYaR4MPM8lbKcpAoBCc0+CCOiwnp4XCoXFCNttbTzfb6qgR7wqdK7YLnrvfzJieQqJukQZvtWtsVZB/Tis+5niomz8Ca8lo/FjFOIjAq6xtwrW4CS12+yZdTKNbj8e+HwoUcesF9RbCKQlpVHuwhZ/8ghdzDgjEE8z44rDepEv3Lx/aUi+67velLH3j+1crnxBUz7wP/dWzftwWgIxDkCR/vW63yY2Xebt77swDg8g1Qj5OJdYiAq231HKaZjxr10y88JI5HC1EvbbduDN6pknKUgM+qEdojpi2BmjK+9MtV7sVhJoWqwHG8q9z03kgGoFnWEb53HyMVes1n6HYfzwnw+idPFWGZJ4IB25WfJLfQuQ==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:12:39 CEST 2007',
+ updateDate: 'Tue Apr 17 19:12:39 CEST 2007',
+ accessDate: 'Wed Feb 13 15:27:04 CET 2008'
+ },
+ '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74': {
+ header: '####',
+ data: 'l18dnf2TRfinuu9KDraIo41yvG3mNFqiSCOkyMI6WZZD4RnF8R2Ob19fJ8zXv04eDx7TYyyGP1IlFWEdT3LBrOmmbtUmIvtYanIfKTkT6UGHNH2jh1HyHqJbpgIlr67mOm6Es/AgF44BiyJrk5R1y9tA90oeUQynMufiM2MFLpdalDYWEh+W7GV9WCmbBIU/soioTJ1ep2gvy4kJvTSrXENaxHevKfYwn8ucocvY+hjkWB4GWOR40qtaG06wWMLeRsrTBH1jBG9srzbBa4u2IQ0+NJjQrYdiu7nfu6Uyu7Ya/4bxV3Sukao91XvXSFIhcI2OuKl0njUshv6BDEfHwXIQuPtn7KaTx2uYl1pUeTv/tAFvf8Ng9OFNgK0siIMkeg1thFwRiGSmxjP0QZipDtcCekIxj2k=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 15:29:04 CET 2008',
+ updateDate: 'Wed Feb 13 15:29:04 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:41 CET 2009'
+ },
+ '7ee6a662d1980467eea86a58cd7299ee02000740693df2a7ab9dd64347dbbaa4': {
+ header: '####',
+ data: 'ZnwtGdkg72+TQKCJQhZQIqP9sz79FcptnmH8VJEDQY9xTburh4cyhgbgROBis+awp1C5OyiAAoWfPnuRAN8Ai3d9f8M8yjnDGJ4BAJ6OjQ5r4RDQxNycCApXWO3mJpBrx56wMsCVWT6Z8a4khzPrf5HlDtus4lRV4GRdhU9FMpwuaCfgVD38MhlYXDaPgyu/8N+6eQHuFxquXjOJmptfO6tVhP1+/tEHo6iUAX3sXMZAionssRgPllQJxfzrsu7GQk3h66PakRzgStTHUCcdyoEe9c4VnvUgaasTbhENA4x8xPrxjo24zwxfFpWNEb1+pe8N3+dOXTsIdd3CMKrxQ5KkwzyN/Bj9jXNk9YX8PC0geJiR3bCGtPsAd7aEFB7E6y0RVX/RL5f6x0utSYw8mg6lfprlr5A=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 15:28:28 CET 2008',
+ updateDate: 'Wed Feb 13 15:28:28 CET 2008',
+ accessDate: 'Wed Feb 13 15:28:28 CET 2008'
+ },
+ 'c860f9bbcab5fa70854212e18c11a3e9bdc2382f91cfbd25636955c443a05f8e': {
+ header: '####',
+ data: '1rztZ6mKVFVjlL1kEoUsXEMketdElGbOpYK9iy3g1/WeMcTd4D/UjgHvmQHzzNuYJc/yx6cCMMU9dofLe3vWLKhqDAPAVCo49qiH527hP9rQE+0SNO1v2Ymk80hL/gqBfju51bIYxPKAD0uYA+GMX7OdL+S7qdealebERcnVa0K1AHiVU8lu5yIKk55U8zwitk0u86J1zwcraiM3RGXir/x3oZRIKDwT+lhUJPr8GbVjgKlPu07Ii8OdrAGdHefETDlyNnaKPJHTbGXkd3HZ2CYhJCQZGn1Hwfs46iRd5aO+3UErYtgIHl6CXuXd4E+DNW4UJZedP9YV860DBkpqMiQokEMYTh8Y2sOUyf3ZEOshfGvJUhj8O5p7rNm4+2BYO3XhREdV39tn4vUj56wYj+GL5CekEl0c4Mx7ViTQA+gLvk52V2w/5gFyFNQ9U+jUQpb2n+d9cw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:11:33 CEST 2007',
+ updateDate: 'Tue Apr 17 19:11:33 CEST 2007',
+ accessDate: 'Tue Apr 17 19:11:33 CEST 2007'
+ }
+ }
+ },
+ 'fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6': {
+ data: '4zgqvaaWm7nJO09LKN6o5hbWwGzOv7VVmXDu5T+JCHTSOXbteogax2Zrv0uKLkfooGFThJBk0rXfXxE64vMOq3AeHXGw7Chg7hz8Z2Lpjr4FfE6q7Em7UuAlAuL1PiyXXJJK5iSsRY9tkizuYl19aXW+CgpPznYD/PyXgeYxqt9WLqK8cl5iAU87R0cQDhwl16ivzVgiiFeaB6B5FQqWBAHCEgXhqTsaw2gv4snbmPOqcUZbHy/Vb9hv4lPBJwGFNxQzeZUad92VBC8YbIjmbohDsXjteqD2/k1qOgpUB/U5BpyVwsi+5ahgb8gbS+AqYoRDYzkaj83ksPI4JzWyZhpqjhDauaI6M7hGnJ4GB8UZc0M3WPgrlf1r+TXCgpcfembqL1MyteM+C+ItPRP/QdaIXxLOmvGFOBKQYEI7UceUWBCSEzORlS2S2lltlqt+K4B8QTULiKaXCfRmF/u60FpJufIkUX0pE/rQVChxswSWvh7uJFDBIDx8MplTX724A7DN5d4/Ad4Yi2cj3V8X/DEErnHTvirP3tZ2F2oAe7kIdu+JuCqKcMaGB4hVijzv+yim2TCPvrGTFaMmg9PvcWHpik9jEIabCkdqAR8EGIkD29+yvG4vD0DTRKv2vPIfr60ZQnsgs8nlPPoNa6lNHvI/EO0nBGBYBc1TW+syV5h/zOG3rHX0XCHhISZmDMjra7eUETWChncR88P7ciC4yJQtzXFGzeXp2ktzZ8m5g1EQfgtlUVZsHN8e4OQ9DjKt0unfq5RFBj2jlG8TBZn6ZpebxWR2qOxp81KQLHJND9zRTy3h65+k5wo3MnnxE3GbeXg2dFIORRvGUT6bWsqW1fqR/pg1GO8KNtrt3CryZofgE52kuk6hlcmSk9974JR5523+1/hbts8n5VrTi1C6GWhnxpiJb1XIvICdag5g7C2iYppzLKVzbJcFMegwDUrapbmGhkqnGwSY1EQSDyagPr2xlziWhdWdCOVAYcyw8dOpdD97QhVef0OWrJ8nbgFKD6wn21475OFxooheWiMCyZwXqESVG1cVCjeaCsymBtEVPpmQdSkOfMdXpKVF+3osb4K2XDpPeU1zPWVozeMp68YhLztQ/g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 18:43:29 CET 2007',
+ accessDate: 'Mon Jan 19 16:09:30 CET 2009',
+ currentVersion: '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a',
+ versions: {
+ '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a': {
+ header: '####',
+ data: 'QfC77EWgmmnxz9JqLdn9Tw7mNztfQZPdNpaML03EdFpphsjgLloqBRX0UZ21oozjQGHpcUMMOsaJgzCuDlfh7T7ePVV60Ps4AJtzv7bHSVGKsj1iALU1qjtesOYJayp8bA/3peo4HEnVgP86jc5NTwJxpsUhNG0Ae93xVu4lPF0gL0/yjgZUHqYZXkb+oXrcybL0BSOjRnB9fRpA1dEhcwJwoelLTvg7il354qp/Wo+S9Cz5E/K+xnlJAuSXCRXboWea/ZZ9TX88q5uUcY5jLF7Xi2HoFVZw2f5tbycxwGtT1CKXp+OAKn6mQaBAYM51zoMNDT7MvBDXD3v4Cidjgh24GZ2zndfkYT0kHCtY7OVIVSTsXTR+5/XMedojVvDlX9LBa9ST99NLCUy7Di94rJtX72ev3Ei3I1w3qPvCl3jgD2VbIwLogCzqLtY+2IkLAa8M2EpX/D+h',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 18:43:29 CET 2007',
+ accessDate: 'Mon Jan 19 16:09:30 CET 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ };}(),
+
+ //-------------------------------------------------------------------------
+
+ 'test_test_offline_copy_data': function () { return {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ '9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8': function () { return {
+ s: '55a27b18e8fdf1fb5e5bcf859cfa50fcbc69c9a41f04e371606a86411a98f460',
+ v: '983a6c79e7d5d490c3f13645c49760180fca05cc677914bf60fee009ead5a65d',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13":"0"},"data":"Ki9chN/ker5c+7zB5NinstllVq1Vs+N5pezZIohKVVa15VLSIyre3DRilRoldy/94LbGaEM3SZsMlf28hYbWySln3ekNMIB+MItaYb8urw+8U6n8+QaRMAClHXukfi8te2d1OIlgjbrBQNMmzBorjIs="},"directLogins":{"index":{},"data":"54KM7x3emxWZH4CQDLBj4SkT"},"preferences":{"data":"AwOQXmReKkLpp8qZa4zjaWcY"},"oneTimePasswords":{"data":"YgSYIsDeVT87bfiASQqXA2E9"},"version":"0.1"}',
+ statistics: '6Kupec1ZD7Dw0WzK7pPesnLE',
+ userDetailsVersion: '0.3',
+ records: {
+ '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13': function () { return {
+ data: 'dXql3HZJQRpvwOe56SgzbbpMoYWRBjEp+E8uMJT7tprzYJ109H1SnxRWWiXlDOzH2XfoXahP3S59K7rHeJ+/icX+ZrsOvp3YEW7wdoEDosyvrQuxrmHdusZ3BeaFIhQMmK9wqpAzpKCRrz30l/yi81zNpLgTXLLK9fiAyksmsfQL3VHgQg==',
+ version: '0.3',
+ creationDate: 'Tue May 05 01:28:36 PDT 2009',
+ updateDate: 'Tue May 05 01:28:36 PDT 2009',
+ accessDate: 'Tue May 05 01:28:36 PDT 2009',
+ currentVersion: 'a22bad10653a70ec3287917bc23d642fe698042cabbcc1074b60122cf2bb9d4d',
+ versions: {
+ 'a22bad10653a70ec3287917bc23d642fe698042cabbcc1074b60122cf2bb9d4d': {
+ header: '####',
+ data: 'Pc18C1A9NwNlecbOtOOAEymNZD5oq20ZvPqMfiCyNhkcmaN9sEnifF31epZSjpDw4XM4ex3HFhhITttXlCrossDVYB8z00k6XsFruCkdwFRmBjb2PdrdZFAkGQeS/8xTarYWgiflkfGocGqVm6EUq1gh8QLE173Jzo15LOSuzuSS90BTMvcsqzzRrIEe+9jwF9/ehLyQ5yYxNImFGQQ2jkW0KiZsjyEbQAGry7B1/AiSUBaGYHYzcB3bFgXnzC3ecPwL+ENZ+azpTd143WneuVMUJrWNp3S+9ZRzboRzcYV6Ax3nOLPS7LTc+e9j9s4CrPvc1L6pG23AzNByDWst0JrqhN37yp67EVVrFQfUDWcKgZyyA/M82q1TVScx+I4A+g9ASC+PdQ3+M5+EOtEfClkgYJFqzXqwPKYwBv4CBKxikS2Vt8x40271kjmVYyGQOIRTo1UKn6u07TS5hxdEgEI+WdukG52813USiD8bQFbN0r4VhjFSqKMAJoItjqvafBNBl+OXYQ1p1zRCXP7wHS4/F7mvrK98gSuIsBgfL+/q9rExXaxIZJNSbs1HGAXR1TxYSvyKZvLa',
+ version: '0.3',
+ creationDate: 'Tue May 05 01:28:36 PDT 2009',
+ updateDate: 'Tue May 05 01:28:36 PDT 2009',
+ accessDate: 'Tue May 05 01:28:36 PDT 2009'
+ }
+ }
+ };}()
+ }
+ };}()
+ }
+ };}(),
+
+ //-------------------------------------------------------------------------
+
+ 'test_test_offline_copy_data_withExtraVersion': function () { return {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+
+ '9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8': {
+ s: '55a27b18e8fdf1fb5e5bcf859cfa50fcbc69c9a41f04e371606a86411a98f460',
+ v: '983a6c79e7d5d490c3f13645c49760180fca05cc677914bf60fee009ead5a65d',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"75b61c51726a35d1c12ac553947ff9e974d1a29339f87fbeee0d831b59938a53":"0"},"data":"YjlNzXUO9m0EXdi5fUguA6RjR5jc2mwuHkpMsHAheExR2zpoV6OJx8tBTdUGqDBAlbIn6xUx2TT+dzgjic/XubgKNsv6JpTvnfiW6ZMWiebKXVigoZw7L5EvmcHjVLI8aoIhVEj4ADwkh9qHm0Kt1zFGQPwwJfo="},"directLogins":{"index":{},"data":"4W5csD8DxlxeXVRROk7wVbXi"},"preferences":{"data":"/DjOoFcgquxUbW5ye2LrpsKM"},"oneTimePasswords":{"data":"DEqkd74lLAGtG4YKRPniBNBU"},"version":"0.1"}',
+ statistics: 'EkRr9wEXi/WOlZfCXphn9kfx',
+ userDetailsVersion: '0.3',
+ records: {
+ '75b61c51726a35d1c12ac553947ff9e974d1a29339f87fbeee0d831b59938a53': {
+ data: '/gtNfde5l2J9eeg+rlBHZtqO4RDaWNQwaMEluOVowKdUlGAYjo9FU0NwKsA9CM3ST4sTYl0mylP3C/AGybO8/9sTCkEn20wi0slharA61Rk8uB2lNjCICZB4l3ZGvD4AHKucu8YQzxpWop5dTN8f4us5eJ2VjvJPLqUzSKZL4g+6MiKbjQ==',
+ version: '0.3',
+ creationDate: 'Tue May 05 18:47:53 CEST 2009',
+ updateDate: 'Tue May 05 18:48:59 CEST 2009',
+ accessDate: 'Tue May 05 18:48:59 CEST 2009',
+ currentVersion: '2c913151cec0422dfa51c5bccbca6ad09d8e195bff144d2b5f7a2da3bf55c11b',
+ versions: {
+ '0311012a897262b85b60a316f086f0576caa3c11a34779c02ad9e60232c79564': {
+ header: '####',
+ data: 'MZGx+tQAecxJNl6UbWHIM8g416Qa8DfWtGo7f2vLkPBbhsr20xnZ233oPqIGceG5/6WMssQd9c8U81urISK+4Ar8zHGUxTdIYLZaDq33Q0uF5vO7OsaBcjL7m+tX7zB+e/eu0ABbqvt+saMsZKKSdIZv2KNbAg5VTiL7GjWuowM23tWgiUBgX3eO5fnUUQWVkBygk0qy2O45oNfb1XcbsGMCfS4YPF9GB/wGSQKG8keMoy1ZWZh4nG+Pdx2ymIrYKLv8T+i7jtWEbyhvEglb7TadCMBBF0pnkYvG3F29skWooZC92dy5213o+3/uSKi0od5tAbvSYZHjT5hDulUtmjRFGq4ZRERLqvrZs9Sg8G2mjtf8Ta99Hob8WLxyGF9x7s1LcLPERtdsP9qCD+I0WtwrDiodl/sPQ/5s3G2S+M/YejKXBvG3AWwoO1gkdhec3+d3meFNvCr0hKNzotrHmDLC4tGyZIaAcBmPQ8xSD5KmNJJFU+V0QIdiEYKnPjo95oSmKyK1UtIoPrWCahfYSKXh+aW53XnzY4JKHRER9vWwdJzz',
+ version: '0.3',
+ creationDate: 'Tue May 05 18:47:53 CEST 2009',
+ updateDate: 'Tue May 05 18:47:53 CEST 2009',
+ accessDate: 'Tue May 05 18:47:53 CEST 2009'
+ },
+ '214d184d75418af71d18f412bc6bb153fd6435a4a675af6bf2a744ecbd7a53b7': {
+ header: '####',
+ data: 'Y38v4jhKwcsW8LDTigIhtdLJ2zgv+1rSutqyu0AilBQeSTe4D0rnapZZTW/mNnD5IGpWKFoEl8+WGj1zvGzleNdkOa08nWJEYDNe2h0+FjBSHBUAgH5fraezomRWzJ/Z5HHFiZuFfpjt2BHd0Y3Not6AuL3aBgjjkEai90r2o59Xr70maUwo1UqmtVg3gvX067MC3hlqhNIp390J8LFiSj8Z4US9x/WzVR5Xx069+0PFMBwipq9WJPrcfTPwvP6xVa+J8BCJk3HtboRutq1ZhhHpibm+TY3Xl3gFTTCHWDZCSJ4Rm1dWkyqpx51u/AVg2TC+ljFLKv7hq3euVZNMLNMY2BqoCkcb+w6dFLDs3WfPAW0aQN2P++GFa/eVpN90YxAeXufjsXKaArTMjGWKiHqyU1iVVI8N1QEiFYjjBV1GvkJxog5PjtAzJF++qwHDIa+gJ+NnOfenVF0wIRMCEnpGyvbg3SkUoenKFoHO0IcSP2CW2RWV/GAmiEZEuVD393mKi5B6fpjdO9JVPNyz0i0kW++dtzInwPnglhOAY1ywT0ExOBLIEr8=',
+ version: '0.3',
+ previousVersion: '0311012a897262b85b60a316f086f0576caa3c11a34779c02ad9e60232c79564',
+ previousVersionKey: 'f45/Sx3jMC8CgdT8cjfcC4ApA8xMXABFO48jiTh5VjJfTlVqw3NnHRO2KDBIhy0znPvP2AKlpKQHruW8LQno7YLyhEIXh4ChjMUjJsFFwB/LUg==',
+ creationDate: 'Tue May 05 18:48:11 CEST 2009',
+ updateDate: 'Tue May 05 18:48:11 CEST 2009',
+ accessDate: 'Tue May 05 18:48:11 CEST 2009'
+ },
+ '2c913151cec0422dfa51c5bccbca6ad09d8e195bff144d2b5f7a2da3bf55c11b': {
+ header: '####',
+ data: 'tkiW41JHOfbYOt2KHx1HtDJEzxbfVS1Y2HJQqdQZ73zhvxnkWLw/X6FMiBexLeoKXO1H9NIWS884MzEO782vg8QRxTizg66Yye+q1Hox+QsaEoaD4UQ54XV1duTOB/XS5P0P9DFvtIz9msEu8GJrvizAdxu/7FG2b5XfENDkwqIzydI7JMfGC0JzDnfGvYkWqoL8jx3Joxa7TNqN4he4v771Ho1ZoUv3Pp7ZGwBU+btl6Q9mcycSf5KXdTw+6nDjfQh8qyts/u7O5xPFh2Yn8zS48x95I4SA4yFKtERU3pLAxIkcZWVb17xT8xlbPESreZ0RyYSR0CgW0wPMxkLHH1uqWycTa7yIxUhyn+JK9jCl4eDa/KUSGbN1yb6pOyjGuev1vHEZv3bOmO52RVVIdMHTe3LezCKY8xpDqtQKSfAvFg1TmabugXePXB+KvPbDDWI5otDEIwLYhDFcSn2FyqUEATSzeU2o1uXO+ffbU3QBrwr27tsreughWSP7905FQbEEshsRUc2Xt92WhTnVM6W74Y0bMLWjTrXbu+hNsjtFYYN6gtezcltnB58MVw==',
+ version: '0.3',
+ previousVersion: '214d184d75418af71d18f412bc6bb153fd6435a4a675af6bf2a744ecbd7a53b7',
+ previousVersionKey: 'XtJ8Ub99GXIkxErIPr0HaIrRqlAO0Naa/tPwUA51K2D5R6R3CR6QbHd3GpkCnu+y+bcEIRYrQqgabi3LROYT+1SZ9B9FctX6FyaTjYEazFdCvg==',
+ creationDate: 'Tue May 05 18:48:59 CEST 2009',
+ updateDate: 'Tue May 05 18:48:59 CEST 2009',
+ accessDate: 'Tue May 05 18:48:59 CEST 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ };}(),
+
+ //-------------------------------------------------------------------------
+
+ 'test_test_someExtraOldData': function () { return {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+
+ '9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8': {
+ s: '55a27b18e8fdf1fb5e5bcf859cfa50fcbc69c9a41f04e371606a86411a98f460',
+ v: '983a6c79e7d5d490c3f13645c49760180fca05cc677914bf60fee009ead5a65d',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a":"0"}, "data":"3iVejXl+Wnh1P1HeNXhuNswKZezHtSDEnMVPhtFmF+5qimM4vXvQ+8hTO398SktE18V+lTxzQBLrLjMfZBLIaq1rszO6CVi+Zz2+A4jC9jOkjqlHlMIQMxF0jwvTr2fRQSYJIT086H23LVH79Pdik+E/XmQCMyX5oPrm8xI3TnHmb02GDy3uEYTOodIw"}, "directLogins":{"index":{}, "data":"zxt4pdoEyLS2Z7F4GuHsR2Js"}, "preferences":{"data":"/nCI2oM+0mskwEBYj+ghKgvI"}, "oneTimePasswords":{"data":"OxUue8AceRz1qmwkj/c0V91x"}, "version":"0.1"}',
+ statistics: 'rGwA4ZUPNmYKzQCzLpstvcos',
+ userDetailsVersion: '0.3',
+ records: {
+ '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a': {
+ data: '1eab9775e41984618f366a58f3de6cd9d72725da399ade71071f83d3126552d95487437b1a6fc87cdb25b47d35097604ed23f7dd2b54bd71982eda7cac3e19e9fae5b1d8c52806d6a860a35e023d525bf0e43ef459901da8d819789031a80cf8ee4aabc0e8fd0a051a6b9a23e4e7151da900acb710439a5b11477259f464dbf38a6327adcc9dfd7ab7808ba7c6d26a39bc678da394083652bbbdfe382f32ff3a92a31697b72e83f1534e72e7af7b316137d60d597b80649fe11dd506f600315543c39bd447a884218d5ed8746102a95587dbc844f3437a7f057e26a311078a2fe508613894384c6b120e0b74444770dedc636930a5db17e39a55c79da36f44222ef7cc0d3060deccef7cfce9d4454fd3ab4f8e19e949a9cc208e915e29b24a6cd9c0ba01a84ed3c3d29aad374828c4f7174e51d5949799d29474f9d0e0ff421412225492926252c5c28859fd1945fe25',
+ version: '0.1',
+ creationDate: 'Mon Oct 02 10:01:52 CEST 2006',
+ updateDate: 'Mon Oct 02 10:01:52 CEST 2006',
+ accessDate: 'Sun May 24 21:33:48 CEST 2009',
+ currentVersion: '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a',
+ versions: {
+ '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a': {
+ header: '####',
+ data: '1eab9775e41984618f366a58f3de6cd9d72725da399ade71071f83d3126552d95487437b1a6fc87cdb25b47d35097604ed23f7dd2b54bd71982eda7cac3e19e9fae5b1d8c52806d6a860a35e023d525bf0e43ef459901da8d819789031a80cf8ee4aabc0e8fd0a051a6b9a23e4e7151da900acb710439a5b11477259f464dbf38a6327adcc9dfd7ab7808ba7c6d26a39bc678da394083652bbbdfe382f32ff3a92a31697b72e83f1534e72e7af7b316137d60d597b80649fe11dd506f600315543c39bd447a884218d5ed8746102a95587dbc844f3437a7f057e26a311078a2fe508613894384c6b120e0b74444770dedc636930a5db17e39a55c79da36f44222ef7cc0d3060deccef7cfce9d4454fd3ab4f8e19e949a9cc208e915e29b24a6cd9c0ba01a84ed3c3d29aad374828c4f7174e51d5949799d29474f9d0e0ff421412225492926252c5c28859fd1945fe25',
+ version: '0.1',
+ creationDate: 'Mon Oct 02 10:01:52 CEST 2006',
+ updateDate: 'Mon Oct 02 10:01:52 CEST 2006',
+ accessDate: 'Sun May 24 21:33:48 CEST 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ };}(),
+
+ //-------------------------------------------------------------------------
+
+ 'joe_clipperz_offline_copy_with_preferences_and_OTPs_data': function () { return {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ 'f527cdd90d0d47f8524b4e165398ad1455eba515d04abd101d1e93b3c6ae0674': {
+ s: '5f7dca20b7bc610a966ff3611cd8d6bcb5c5782d810123fcadf7155757ea39cd',
+ v: '100000924a0b2bef390c27b2f5f379ab1a557e8b6c2d4ce5ef57e983d5c3ca49b',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"a92c1ab3df0677f63da3cd1fdcec440fe3763e072e1035f8455672a97344a6bd":"0","cdc4624c921b8d99918c3cab5264b5e6de39df30ed167f504bc0a2c612404d5d":"1","6a17bd6b1bd576b99b678dfdac7da04e79402fc542055197017d3e586f6e8f38":"2","9ea260fcadc1ae2bbb8545c32035dc55499f715d005fbec71179600b50aa907a":"3","c0e76e60e08faa3ffa9d859ed869ba3cf3b42becc9478d45ac94cae6c004cc24":"4","5c5fed5764090b8c83435acbc22db01faae889c3154d51d502a3dc532c8709da":"5","97291f9d95cd97d089f940e5a4a674b7c33b06637337d3722010b528ab1fe34a":"6","6b147cfb119d690204cebb33ac047861a74504c87501432d914e07008ff3cc3a":"7","5d2b04a29a8af43562b1e307c416d9590ff55e370d9b542dc1e58c1e30127359":"8","52d2d8c69839e61f07b55c3ef496177e86b9ff35d27ddf4736bbe1907b30227a":"9","de7ce7e545acd2739d5d2d00b04f889fec7acc2229082a7a678ca050e2fdd3a0":"10","44d85d696125c6fa75e791b895359a31fdbdaec3303e286d09a484c0ea4a6558":"11","98af9721614f0d2f03d89ea5eb8930b7f1bee6a55a8e81f0eabe964016a930e3":"12","3c735070f699188a0813489b3fde68e9a7bf25f81d78e98689b81dee364eb013":"13","608adeba618077d125f0b489ef28fc7e3b1ba4fc2baeb01a3a1fc5f568578791":"14","35b30f9e923ce913365815d44cf344ce66cb71b636093b8ec55b8245d13df82b":"15","c742849667f8001483c1e6d3d388ae9d02a2e3561a1be7b1866b62a356b72b91":"16","2b58e7cdf7c90594d330ca9636565dfd1ef2e28bb49d16dae94335450c496b2b":"19","aa5a54aeeb4f7926e4d0b469207812e5384a4e00acfe9248dee45e939dc58b42":"10"},"data":"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"},"directLogins":{"index":{"03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c":"0","a48e38845713462ecc9f827149eeaae87da882031f98ef8ebbf9ee9537b63468":"1","9b7a30e667afc9f76ba77600658b2c13bff52432d444261d39bf3d069a160afe":"2","ddbc8d01300a4f10631cbde09e1246332eade3a877a2205209f9eb9e5bc9da0b":"3","24404059cabc63b2dbff0f42ba57183108b8189ef53ab62fa25141a1caea824b":"4","f22dc41ffabef4b3bc8f7af804fec975bd50718098322a673cbe4aaff9464ae1":"5","2df54059e78f5771f23bd285cce19595b38331b73d67020424d9a1b2257db09c":"6","065cd0c270e5e8ce50e4ea8e3828dccdae18c01ab030813d756a87d03fe68784":"7","f695fc36ac56bead80c0d20a88e01e382819c18dc268f1679551b7c83db7cb14":"8","7e1d069b7fa57c03bd7bf48807520feb953157834503aaff8c9d493f37dea69d":"9","cb9ae0bba1957075ccdbfd3b3481704d62087687a2ac7c411a4f07d444bde0f7":"10","61e87fdc4f1d9112e3b30c1f6812d095dcdb24f014c83319091eb6c9899ec348":"11","1f9bfd677b531a03168d3f8bd8afabb5357244a7bc355dff50bd6c0a072114a6":"12","9f7979368fa29f66c44bd97ecaf6c545abc800b1c7bb21b7655a68e1514c3906":"13","989593d4c48929f0c8f1581aa96969c622807e99619ed4732026e967530a68ad":"14","33cf9758477460a8056deef0295a1ebe65b39b392c361ceb920a83edacfe5d78":"15","e9a16316f330e3d150f6ffd194f6fd8acd1426757b097de4b88ca0db875202e4":"16","9fd2929cde3d32d9cbc5f1d787f2f64729a5e12a14410556b31c0c099762c46a":"17","dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496":"18","aa18149164302d5dbe7e2d3724565b9550e00887b49978559783b2e38c625584":"19","6f7bbc4e42ea462b5246e6f51c3f86056bec50601ce2de6067c8c1d26f21c07f":"20","a7b32e72502804bf2946a2a8856139cbbb759c5777e6b3e673db1fdf7e3bd06e":"21"},"data":"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"},"preferences":{"data":"pcQa/VkZWvrLv88k/npaOssWdQafXF9zJS+/DjM6MZwsUimSlhedy2pWLvrXp/TJ0ws7Pef1CbVmoxHJYyT1x7Eon7y0qy/cf483h4M="},"oneTimePasswords":{"data":"lyRIfuaIli6Zs4awYtZWI9JgUxQluHa+hxopJ4ADzlXfY7vTv5Iuxtmy1JviMKcGT+xge69tkrDBccydict+biWRPoZFEuR/V7tLMNndQBSdR54usAJ0e+obc6jDM0u38TpyMit0W3f3CL58lV7VkNUQgt6jEclKPxnKLMCqLOTNqoPTDNDMFJdlWVXFVeh+TDG02rarglHzIKd1lox9h/j+Ty4s04vjhISdlE1dNiQ2LqTZ3M2xv2Lg/kH9LBWMryCKmWpMI7IiD+S+eBnyq57EdwrqQi/3p6E34NcuJVJRnLBjnVAMoGkhU/vMg47iLcZXF9obP+oHYUg9mIKO2NNr/OYA7UIQ9lEHXWqs1XZmvnW4ORrzqQNnrXaO5/nWjYO93oG/PLGlJ9G/Tf/zsc2BAp3KJSwILoNS+xWckUydT7gickZqN+JSBXj5W1LZxJ60EY3PBIyE3i37yzho7nP4n30G8kGv5PgSA5BzpKj8/EiPFF3JFJVB5oDcwdeDgvDRsCOGUSMVWcWP1MfDsKHsRkMdGwW8kjFB65/jj3VTGaS5tYtyYVIhr49Mq3I/hUVBk7fcDQQM8DMYqj2EVfDoYAnA0BT+BAFRJ2bfez8Zj/vgW8GOwmsvfaha5YnneYVFg6w8Elw0cwJh3uKGHKCuXwXpe3h9LHSpA8RB95m/dvdoRQg9pg5l2y6oqFlMjBd+3qrpDWG68VZoz7pes0WHMVsNSmJQs+yJ8XfiVnRl27O8/8v4DmhRUb/GhuBSu3pew2YIPVWXEGq9C4nJlZhWAeT1pF49Gv+2bDzRI2R8fJykNXbStn1DO1I6bF01yECRgfzc830T6VBdSbUjpmmMMq67ZS0XVPvO8ZErmQcM6ua0RlttgMdXwNrO0pQ11TKNtGD6k72ud5MYDOYOtgMq5OFdpPc6A/b44mJ1Dim/8j4ETnRM53gl+FU43kbDGBkFu2Q5UGTmza/FctczfHqGEhthyBEE834FDFJeRZSNpGPAvGALGfReifNuc8GtrNyr4X5YxQdcNLHTa8wPAU04M+2gi/tXMsh7AlKbZ6FOEXmHe68A+twG0gcmPG5hEJo2n5L8pAd1eeW+EiYW/26g/oxKgl7p1x6I+fen3rlhcdNkGpUJeGnf1B/Su9wTKeQjobCcQax6RBbdjewLhbCFvSjRjH/9IbWNDgD1sI1xHEh1hKIgSebB1Wqi9pNc4Z8zRsko3/ENscVC7onTyZDu40QRNApD6c6sOLrAgQgUXdIC7Iinwv9MHFLARRmX/f4N+GfFqz5xvfuZtMeQI/H2MNtC1xVT5p+MhBxo02LM03wW9BuXCVDzquX+X5Zvo8hECl2zed/Bnpze7cuyaMFpQLqLnpgOrIzLUWix0ri50+k6SODYj6Fkzjz92COdx1DJCgrGNV/LyalPs+bsmwQQ2SgfxcE9+pWaayRlXB9zSxoZWv9wMX81xpd0fDLpxfLmINKx8G7hSK8YNU6Ldl9fQWM5Num7/NHkiROA57Bnwa8jEoJSejKLxWLzxoyVm6AwJUVFHpBhm/VOoM3lUW7IVyyCQeZP9zeCfmTtHtMDu4FkxNEUr2YppNmaT3CRtOJsLjcbpDqq+b5ls62U62uJ4HXz1ZBwgxfZcHUzU9t/dEr9dCvAiTSfnDhXnqPP4g5G+TGvcfOw+UdkxAOMvvsoYXKO3A6VqJOwrynUJKxSd7I="},"version":"0.1"}',
+ statistics: 'I0/F4RIPSdiZYXN7dF5ceIel',
+ userDetailsVersion: '0.3',
+ records: {
+ '2b58e7cdf7c90594d330ca9636565dfd1ef2e28bb49d16dae94335450c496b2b': {
+ data: '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',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf',
+ versions: {
+ 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf': {
+ header: '####',
+ data: '4VJOhqSOjhTFz/k+JEODmNhY7cCD25PLK7aoD34G4wGzeoVjBxzAJ2NKXG6X3eL8cXG7DjhzI3LV/PiPkYhFf2sVkHbcvAlXBcuQFOZkZcf6PvedC1ZfNh0/QKVWaCmTGrMUP+MEk448fqKfKxJZMi1lUzvMx6VX3bSG5ZQpjt9DtpsPXsbqiz1ujkgwR1a5f1oXgwoWVVcI95yOb3cS9/RPBy9rP95L7reRkzBG8hbyUkZx88yZNC/RgnF68PfgAKlIxAuyMX7V7OuXzHntSxw3FWBGIg2EiWpvAJAUi/mEpZcp+0es29rbHJ0FyuWcW0gbeUsCS0gAyQOj7/VoiWKhG1Zc6qe5cE0F+EA9bLuewGynwX0CV9IDYtoC2IAJXO/HmPF+yeXf1TI84h8l',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ '35b30f9e923ce913365815d44cf344ce66cb71b636093b8ec55b8245d13df82b': {
+ data: '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',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a',
+ versions: {
+ '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a': {
+ header: '####',
+ data: 'AA3YiiY3wEYTTnaKKxYsmKqTZDkmG4FoICNWtkJXiEhHzElR5vi1OgMNhm41aRVszrCemeM9kK0we+rMCyFItJ2mLcbsYQRmuuhOqzmp1fCGSoR1x09KpDNug/FndY/UjtAbs9T948zl3TWvdwR9VWOzw8XXxmJg9YTsw5uwhqQXcxdVnQI5akKClcoqz0q2NVp+OdgQnjc+FUE9WeqKY/Bl0MV0l38L07DLcoHZ8OVKPSERnMbcAbN+1C50hp9QfmniBUIoVdAIsNQ4Zuvh+6uo4cRMeWQfKw+DOVAWiIvrpUBSk7pVZWeOoKF/IcUR5Ftem63GIxwZolnhJ+HcTFcNDWkZtb+E3QRZ4A5kxtPZqI1KQwiTkS+mGI/u5zumFtJunrpbe8JgikhV3mA/WD08nZdSxmfg41BmMC8t+0zQ3Jwiirmn/F9a+TIntcwyI/4goY6T4Z/t+vKHVdv7XU+Ma0Oy6swrXB9JLfPF8S8PcM/IlyqnCKkjq1G1eBymMw==',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ '3c735070f699188a0813489b3fde68e9a7bf25f81d78e98689b81dee364eb013': {
+ data: 'PPAaxPg4YBKa+02+PpnXDHCEEtAbyyPGrpVdLS4DBky0KrUV1J8C3lsCudQLrVNcRdgtXetkLipukMuZ7lOS+qlr1vsF0JyaU33GpMszeCNtOUlWMidZk0SnjHPPGHBXEzmZm6yVfprH79bv8YsoWASyRamubk8kZ2lYefQvl7QYNBQVb01cyprJUVTtm2MttYnfKSKmlN0n80nSpNFZuTyMov1XAlot3iicojBvSvicsYwkKDmJ5bnpuq4kzqonL2UUQ0TDTJ7erf2MkT1/UPdnE3ZRjfsoIEm07+0ORTqrVZJXjmBjSLlxvBRitAcwVs5IWTUEnMF6/bYhCMdWnF9w2oayHjEnKh2L+fA6RQjkjlfYscmv/HfxErYvFvfSRCiu66AotlL9qwBzEooaXENZfPqZVrYKRm92oZDoz8KOm2EHlttnBgjE5w7kRtdDDBIgGsU94bLObSu0UNHERADv9VitYYK5dEU9Myugf9V8aAJbwkxhzZHvYj6KsKhiQtMnaU0FVO1qib0g2tyH4+TlaUUlY3Zo7wjIn3GMVIomgN04Lt/gBp2vq88R8/erqERKdZu4XXl5nATF8w686gedHHIjpObeVyBN6PTNp9enS/rM+sQti5AOKQLx9DgVaoT46iLcg2/UOgIwt2zDdXOccXqBq7PzS+aSzya5Pgpp2H2VH527/PGfR8D4EA/tiNGhUdwPqz1AJz0td2qCWMllJ8GDgme7Bzs8UG/Gd+fWUkngTwRA/CcNAv/1f/SmS9V6RjidkAiNF1D/CGO9rWMOLMr77W3kAOEdQZzxo5tzymx7FgG0Q1xa0fUY8z57UxViBILddU0gArWyppOjAKtP0vw4eDzPFlH77a0TdXKnfB/41arRi5kWl/fX0VZmcjRQuFRS3t3m8Ta9GINaZHo/QAKK0Wjjads4THGjNBOFq/pVfqE3P8EPJZimE9A79dz5crZCiqdflTgAGUdW4razA2jqxcLbbxvXuSaJM2kecddVvayOWO6gVu/xbwbqgk3eETpO6HBbYZq5TzmAOJEZ+XBt+F+wx4EwYTVxNtzV7NDKvooBH5CDtTxfmDIE3b/FXfqIluPLXuzjUaziotJ+IARbY77w61VjjK1xPYPCF52Ovb3d1A0L1SUwfACzMYtG2Vp7rwAa4kUETedwjrZ1rw==',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b',
+ versions: {
+ '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b': {
+ header: '####',
+ data: 'HI2+42Qv/BK066PQvkV3a+njq1IJeWZS3XmFYL5Q0G8ZChyeMUz9oCSfLW2fZrDcwTQNKk5Q1YIbK2X9PunUX5+s2eKyta7ZejiAs4A6T+AL9GEIPYnX/OjQx5bHFL1lVWCOhg8dGU73A1ryMEUZnflO17KzhktJENZvh+luEHjN0GIqCBypenDE3gs/A8aPoqba2EcJ5nfazVxwIpiPWhyF4HoJ66pjBdj9gUoIqq079MPVcs8xVdO3LfVOc0rT+pCi9+ei47s2q3rwjhC+osWCYgXdkdcf3TJvOwQPDq5JEtv4vofeHsLV3f0DrBRNb1Rl+Q5VNVJETVv5CGOgT9doysj1ktLA61LVBPKIJnmtVaa3IoNMHvTeEze6kgIsgWaH3t48uynqowx6QeveCQBH',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ '44d85d696125c6fa75e791b895359a31fdbdaec3303e286d09a484c0ea4a6558': {
+ data: '5DKtDM4rsjjlFeJ2jznb2yT85d4lhBouKjDGFQ0qkHB1hUaMf+8j7eY0LX4n+IlFYaaol3EfWCbIMrpTDtfCUV5+VWgyA9FunbRHYDyCRZwy28+cJVtWAt7aBUninuQ87LCXDEYqwATDo3+wSW69OOIzqs4dq5bL+SAbX53biquKtb4kDlSgHGHImlpBG+tPYFLVL+fbm7MC3khgVtM7X6fBUhm+g41mAkU+0WUxft9hQJUZl3JH8tSBxhkHxexfekuaoJkFlpxAKR1Mtb16Lo2w+8/3mJ/cDxacjjui0IH2jaZG61JrqJutx2+e+M3xuDpcLeGm9VNEiEDNzeNWhiRP2gojk5liQN7Hhxdl9DpKpRY2s7uMRXeU909vvEWaAcEbF84xf9Y+hgwCGBT0n80VKkHPvGyC9Dnva4HfqIvu4wg0xF2ISEun058kaTy/+BnZu8rRPsc8Y55Q6wbNQvy0npzk82wqsHomrXNNMnoufM3wQjCFt0jIR/UowSBBvtLxIq6fF5PvnqQgwZOliLIM7GAvMvn+Pu/k8Kax73QgIRkbTRW/pOoKIAbvnk216oe1u1+AGqBqWzISgMfux9aWvx2rmk+MZG+S5xdVQzRhhgecpgYzDXCm66FbzKVZCNnCSBtge5VwChrfAGod92RiqgZBpqTe29MwW1vlVils9XBfvDCL9BxMpBYSOOHFilnSwdp8VFPFejFiEg0nJBK63IuUS8wyKtkzsumYJ8WKlLKH/xDtLBPkOnzMzj8s5GowhBfwxatbi5BZII5oEVlSgMlrPUUNf1zExDxIvrDflTMoZQuYTG9SArJ5VIbJrznaBk9LGphrQNH1t/90eQhkCFNdSbLraxxDN9+8qAv4cbbEUUVLXiXO3GN5VZuVZxsvkJ+3RjcsQgg2CldV1B1Cy3iY+sFqtnPChXDItMdZU08BkItB+pStsjaLhja75cw1Qs/I8vdJdo0czWgb6SQPU/UllTxo3CS3t94PgR3nNgXcUYafc5QzjJJ2H59PKiQGdXju7gjLVfe6R3ALysiGJRD4VRQx4fVZKhtnrFBfy+o+4+dMwu1HeW2Kdm+jwXrGWCc0j1qan2d+6G9bj8fLT0hOykuixkFOp8lvublO4JKvrSpSrCcXnE3dxQoFeHIqwI14euka1Waf7D75tXI/leiszCY1WGPyGIV1ezIzgIyRAfLH4RcxWfw+2iaLJANOOhKro4cb/9M6wsNJ91LxpZF+YpsQmUkciDLMafoCvYnmWKq5',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28',
+ versions: {
+ '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28': {
+ header: '####',
+ data: 'UukuFiQRHdw4Yp8YoQ5gsdE9ZMOG9T7TwNbEAKMgqTiCmbQlWr7PWnD4myvH1RVFE8D/L8vUXcvfGoUkENRu/amIAPZv4vj/v41COpuahE6Ge7gOeFDr36bxncCAC9QQZYX/PiDX0OmsdrfsCHk0xIDln4yF/QTzOlygOn/G2dtfOaDB6qLs/Qn+dGuQuCIo6H2ACRT+yW684lHziFwch+4USry8IrI6L4OJDOgjHOdPNuv8SKEPYWeeMiIdvPfpWvLR+hgYVCJS8jiBHWDO7F9VbT+ed6w3b27ORcXfYUXlScedXhfxmxZ9sBkEXYVUhlgVpMOUBw24jVNrpkq5wxt4NGEhlfX6L2jdc2nj33hP7mp4Slr/6gGm7No5woXr+abCWZxgdsbj6Yybbhw=',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ '52d2d8c69839e61f07b55c3ef496177e86b9ff35d27ddf4736bbe1907b30227a': {
+ data: 'XR0Do3w0K649LRGUi/FZZqF3s/cTvWRH/ke8qNXqOUh7xFZWd9cWnboAjFu2dRAwtBDIkdgJU5cfPJZIQdbGw8FnyvilokLgZdNqRqov5p7fQy1Fi27pQSvK5QJAiB3dYTmb6SldpuAqdBHcGp9UGecBzzOycqS9GjsXrrrBF0jKRuHJrs4nR8qkrwlQsa5JVFKbj+kgH3gttd2y4cYaOgj+c0/93co0/ao5hzgPovP5IWRf16dxWCV0p80e9ufvP4b7rpdXABR/tkQ6AgoeHF1asE+a1PPG5MS4dkn4o/+HXLBBzLVY+mMc5vsHCfuP7U74DoIVOjqWmoAmKDEBPGSj2bZELTG4guhAX9hdk1cfNRE2g7fhUXkiAdZASc46ny8Y57qc/duR0p51g0b2lStu+OLkzaGhAl2m+k6rxHGyhZE9o/bkGWEUisR9W558M0mKoAzWBoqRzcau/Z2fOGaAD/qMc7czoOMzvX76gyo6NQx9Go7l8BMXPgGedQMAOOVA1uWco1Es/WBzk+Gp9AsDIGPss1HzXZt/XjC3pvcV/Sfv5M7eyu0puNC3XiwFfZWJgoChd/QkIHicJnZlYTyrpO2nEoHPTbm2AY6UDl58K9+x58voKQnrbrdHF04GVBdtZvHiNEzzSd+4SfQaWql3KdhaAa2LzPM6cIVqREXI3UwPVpDu1XHsiC2I45mQ7/eIT0kSQm7wPlZsT5Fu6EFaHh0lHBa5MML5/EQzYqfosFvwLqxuI9coF3JyQszo5x2sdVfSkm3ChJ5iG5T41k7fa6zQbZeUHM9dLLwx+tCxF+XwoxkBJ3fYSYmmF/7xdr15brIB5Pc7dbBZMPiktn1nc11bE4bgyQOpqr8a7m1tAOT4xK6Relo9FkKubLg+hbUr8+6KPzztiamD9eAGQRopf7e7bVNt43UZIfSmCOGopkfZ0s1AVi396ZUexYJm/OgKWNR0BE8P1kXsSj7Q+swYXZM4QacF3u4sQwhKGu/Dxfj8hBecfnCQoe0oDBQwT6Ep',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8',
+ versions: {
+ 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8': {
+ header: '####',
+ data: 'mewISOORFbu2QbxavMOFNOKpVRZTFZ5l9SG1T9Es0eDksCgUj9g1cNqRHC4lrRcp1F1DbXLrANM8Q6fK7m3Aw3yOVKog3+l3n0IeEeOacY2iPy7t4XgUqs1LoenPfqgKwvtG4BK0jnyefbPKEsT6oeh2TkfDtK5n+ofVUieCPqgyc/giAapjhxtKE3nkWVuKfcpUsaeHD8kGPY/rW3TlD+53pQFTdRfRgMGV6GveNo4WND54w+7y0WhwAqow/5vIrsZamUYOGogToklldP06raxY581IhwdogLmobs336YJ1NA4cpwLdkb/GlG1Tjj7Id1DY4mxuD9h4pxwrQJ8ogeexBlLGlHxmxCuX/AtiGeG4a1i8QC/CZKuFtQ+URRbCqtKiGmTEvNWVhlbw1MSZsbU=',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ '5c5fed5764090b8c83435acbc22db01faae889c3154d51d502a3dc532c8709da': {
+ data: 'uRB9zloy8YqSNEu2S6QgUEznfxgCvfLxQIm7dIxQL8cRRz15WdN1bLjdJkNNr2X0LZn6J59u45pn4MKJo4Lr6p6HB4Sx9f3IjWHjSD5O04PTnddX2rjpQPM0ONFTuOTUf1ETaG3NaOY8AM0nvBBFBQ9hxupGeEVKOY4jkxKqPo4UFD6AEi4e74CMMBnGZbKNPjOLJoMn6c5Lyf2YXMc7stXC6HswINHcMq8zYOuN0qlhj6wllgW7zSQSbeQgz8Xu0RY20K1IxAyzNYq8OdVsNadcOvNFCMFE5BNvoZvKOa5nDGmYqyytXkWVsPHULamBhOUAnrU3tKDAjNWIeUNcI1hCEiVSP7ggsHGZ1PJdHPpSQZH+5/xIPtKtZRZ3J7D91abZHN8XNk0WUC37WhOnIVI+79CIS+t7t9muRH2mBL+v/VIRUWjKdBYS7tTdXPUJOEIregvGc6qX90GC5jt5aYNTj12yJ/AxQdKVP/fmE8klf0ZgRqdp8fNP9IwT8S7/8c7S8TMQPQzfuQ39m3aJiOJrHkQQBbRr+es87P2aMu1is/BTzzbIEGq74sc0GWl7aC2ocjJRogHRQ15NtzGGFuSvP7gbwEp502mJ/2DkKKbY6g0DyTJ+FDe3aTejcW4md/gTYsSTqN1FHO5lg/A2tVrmaAnFFrPvFe7OEIwMbN5Ft22GlGG4GL9L/xXtKTFURdd4uxaAr1xJ6u4m0LnXc1iNs3EQjyVCJxzpW4aubavv1mzGus7fWOB5qMgDH6Oy+BqmrLoQgidy5+6NYvvejrqE2nJgNIEeg2iSrAIly9Md1m0FL93ZlFYIqLdPNn47vvhz8pZAQsLaGyrEvNZzt+67IZ6XUhkbO4NBOt9toJkHW8eMy/go3EBWkE0ZdleXfi75pJjT5gRMPOknSsgpAtB8Y2AcjHvdP9SfrZoOtxtRHJnOyQgwfWcnx+fCxCFPdo7mR2aDRQR5vQFU3+LTwgB7QpCUMZ7EGg4fGexfCKyTfkDzNFRWdBgRV16CV4q7HIIKNYB9dn8mgTldkMjaBIsVFGd8hyvhArWqQdDbDheghNz+uQax3go94gkQ32q5uHC3Wq4uCYkZSMGtGS4xZ1gL+yqjbV3e4Mt0uDbtCucMu9Og/ftPWmw/xWPY2z6L8juU0WsClz1rulvO1zsqJQF7PF2hlvixFrXOzxcDmSRGig4yWszcesgDnu/+bG7X1yVnRjWA6PyfnHW6',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac',
+ versions: {
+ '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac': {
+ header: '####',
+ data: 't8y1iJOn18POJGNiM7JOX59XRrvZDoiDY8SxTnmIRhuqgE6T1FZ56s1ObEMsiyzPoR5OrkQgp1GcT5zDpC1uAtwNRnKUqfe8xmbsoHreq614Nn95vDSpIBCLPqWZYLs5PxAD/M/HIpkdLYBtluFqS8jTPTGGl4Mo7BYJHVEonHN6qgPxzAB5rYZQxGwuGK7m84Hdu05wKnGfwLT49nnR7pzBoSfKgGzYU2PShki6qd36x1T8bFxZCG38lX219pNZ/Ogqu0okqxdNVH9Cib2RWwRdW3a1Z/7PyUoqDCjddEjIi5eS0zqk9JYFFdJQ+VnWlAEkOu/MR2C/Mcf7ESmSlyIfTWkTJAE8T/LY52aPcdJR4CyoIt5LUVchn750UQV26voTKoORkke8uW/aZo/LVoH34CmmNQdH6YVw8IUvqAs16OSUikgk2RFFfI7ca7OGftLJCSwjJT+0bkvLo4jvi6DrLj/OReUbIWEQUmP7cRMURw6tkEP/rpHbkYD8Q7pQR/z4I8nsh14f7/AHU+fHDXZGAczT0ge8FFFinyTVkg/2yBk7jU/zcNwnciSq7Q985bAbmQTP7ZyIErAYvPjk+Sa5VHoGq5kEGYDPTMJ0x1vZ3ev325k0+eEPzX4Pez7LewnNhkDzxx9o1lpHo0wwB8QfkGo0xdVcD5UUFmXVGwRy5Qnr8gb6E4lXKhll6dFx99n4OrMipyNd8it2LzbWVZr/UCoizEhy+3+nI9bg4QBGfULH7uWSM81jyHADRBKWbzAXdxoF+F/lJngLpLrqUliXSIHi5d2GxuJwHd4LeBIjETJ6c4oEEqvSoM+ZNKalTybpVgttN6kZgu5CLI2678nfKYqIro18VqoW507B9Dhzm+34UA/RdMd8PmIlYVgcadi+KknKZiFVlITDidO1vcCh2OVCLQuJshFCyWFZQtthWPupQu6VXOScahFiAA66fA==',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ '5d2b04a29a8af43562b1e307c416d9590ff55e370d9b542dc1e58c1e30127359': {
+ data: 'a9CEtLuWMZGaIsOUVOpZ8I5u1X1BUdsCkAMDqZpa/xwgIlvFZop/tTGZ7xXqfLuGw8oBgME3odWfSwysYqFlLyLxvvHHFdc5eWEi4ZUUDRMsfl840zFZjXO+GgrLVpQDph7Uvrnsd4X0BUq5WyKDuLwLujZOS00DZRrrEaim5fHUMJFceA==',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7',
+ versions: {
+ '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7': {
+ header: '####',
+ data: 'CGP/3gax94oP9EMpcFw7ZhWUzIp2DcqDW7CVRblVwQg2UpsWe1K1fvsrzyGC0DTM6yAUXLhSP4T3qyHjb8rrsQCNPr87R1a91xQgWVB+zluCbXH/ZfmQrYd5tY/OEo2e8UosOQL9qieRsDuGbRd/76iIysR/Ce4vGyfYohjKzYepZvq4x+uIwe4uKbzn5YedPqsJ92WTGK5rYIN9fGzPOQMfm8nOkhMLXocEm53Nh5cbBYCw8SGxxDBKRPn3g5z1jLCiOJ5i2KrVQUwIa8LdLPfEBN0FFJEj6Ri8NT9AWzpITZ4xovTomdIdSEvypXYHnkfBw9OWn4KPZIQ8liLtYd6oo3rkkWBZppjaLk5oBkKsxBNSy2gGnh5Eig9HPQYjvwPF7gvG/nunSm0nwkreCMQUzGUd4lLNVdp4dhYErGhsOLb8Rif6BVgxlDccXaIr4Ui5MLrS2vBiO/UmyuYFEduU+7eXuXR0uT6oib5f3cRKFaJNT8IyBiPlvVkEmG3gHZJBXW8yk8fuL2paGC6J5Qp34bkOqDW8BbM0Jf7+CcZURZcW2RpjU1UW9KWX/ga8Z5uNL2282K9C6cZWdw0yeFHsAOitp24xOIJkeyuRnhkpkbGz525htXrzXdwulVSqT4KiZDCVbgMh06k14f67HfYBoJAvLW7thG997HSWQlaxBz40vyjKD83rS1JvJZDLCKTR2VSb5skaAP1ye6CMbsYojZ3Q9/xVdVfW7jQ6nzjT7O2hqhIuIBezJCCvYdZcK2oWY3jW7S497wh/OveqniATyIk5YzIKGteIIhP2lPQ9utTInFzSwQN7LY+pDhCjNT3H8jGZuJFLq08NWTL5AnIS7DEXUITQ10+b9F/DXrM9zt0A2ELKReie/eVeHGGkgrO4ftR3S1RA/X9w4caDjG1vFxGwzFVU+a4TgxnMWwQlaKiCNhm2phgLH9Lxrv8KL6X6Pi/scV3hz+AXvLbiVGMbs1jk0VS5VHV/+Xh58kVcJFhUFl9n+ELDh5byUiOSBfYBaCvUvawkP/OGi+NZeoWckAY9dvvo+Joz8YpA0sQsUDYNNjw9PO++h55HdKOEQYHW0cBR+0PQWgtuARDEcHH8nGHdZd1+0quNJAeUWTKopX+C5cgJ4ST1iPHtnMVYPFQsnZkS7UGS8LVUJbeIYR+b/2rB7H5fzew=',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ '608adeba618077d125f0b489ef28fc7e3b1ba4fc2baeb01a3a1fc5f568578791': {
+ data: 'Mb51dELDLMqkQbUrpOZOTFvi90inlkadvljkbKY2flQCxQzyb1OwdZhj+quCah8RjXNKUGR2UMieW0whcLLqDM4KcICsPutmHnXgw9oGuFboPKqtznujC3pvZED8+W2sBXpyq/lGWdSM8TAjoMmY3r+VR0W6tYvtpOBYiwBsz8MJfpC6zJLEwzd0ElqnpGUCIZOBMCAUZ5KO1DpHhm/o49mKmSXks9Ilh6drS1E8IWpTrGknqiV48wQjdL+o1H4/40wq93D8rgvEIQczlHz6klMSyk6yWHLMhAuTd4k2ZYFsbCOtW7ixzFN/QNo9faJZ051C5RP6srlPgXSQA4lRwm5qWBSth5GmGmelBYt93d2aYF86z/fkjE4hNTRH1wJdh233dBJfh+3nCf9bdtdBs2b5DjkRTLZ/6kAgfdngti4+e6DiHX3NMA+FK/hbK9VnVr1YQOZSDH8NExthg8oWDK2WhiXUX//I8a+Oc3pR16kZHPJwJVJmhRSnE8DRH/mYO2VqV0rSnM3I+i/4DYiftAl/inLBVTIx4DE87skkywXSmBIgwKoU5ekZNgPwU83VADTVXO2vlwgNlA31mmB9f++z6zNdC4gdPEiPn7imwKRGKl/ofmqY87/nWQGqw13hts0sUmyQW70CCnNTL4aOXVay8LjrCHEbelz4Nx9Fy6Ba3pMEelpsM2wMQzuOkjN3JlmTTVV2yydZ19xDMDf9c8lNq7PsiRepEf8xXcGJtpeWXLVkw9h59G6e1RVmAxid5tS86uwnEs6c8z4idycMpvTpMCUPG/KEqYYQnD59wZEq2Ctr6cOocdPSUQ/HE4/+qY/9/949z59B+mDPVxcRAED/v65ohop1QIekq1BtDbrolf8rhXLFMv3JWZl27mwUr8+DgSLrrI+xk3v8mbASUKrSjp4RqFRB11kLdVC71JJz1RBKBvfKjsfG5cO5nDIS5hVkBJX1hXP9pvHYjyDEgSI2h9DgtZh9xXEDwMKITqI9jpTuGWNJMas1J3Ip46u0PG2aoLU1O6DLRgfutVDTyJBfNHdlkgBxydqsl5Sxhmjy7SPwk3xmxI1D6CLbCJ5ODf6x4CekWrFmF21IWfF/73oWr8+KAa6R14L9iTwnl0ynmo5MVa5IJBdn+Q==',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926',
+ versions: {
+ '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926': {
+ header: '####',
+ data: 'nrV954wGGDHVx7+ovlm+4b2zB7TcjxIfXBsMCBUr0LgE8G+zEd5oj3Zc2MvOz9mLaYH/Bu9d0ecN+E5qFeDyRYbVgCH/EVijYemXpXnQH8bCcx4Ek2OeguqkhFNjLubQKRC38rOcWgKDXL3fa8YEyXQpdfWE8g9X1vCshxVOXN4LR0L5bYX2QP0mmoiFOY1Bqr6cYtCAGZNDtfe43Gi53q3FVOnOUhIYy8qrPet1gcdgVbmLs5DufjMdylXd9Q9rUVZCEwzsORAGLAkk7nWNqL9BtYquz6fK5/z4BwRkEztlkIDrhjEwWGjRujbmDD1/5RgKG9Ztbw3LBMkyhabPlYpO6io5545qndV+x+N0YvhECiZdaBr77KUAWVIH3O8EIeAwyvNGKKmTbHox2h5k8nWC',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ '6a17bd6b1bd576b99b678dfdac7da04e79402fc542055197017d3e586f6e8f38': {
+ data: 'BNaqOx4gozG6ehd386VaVAqr4Gon3oCztTSRSMdZ/HskNFQfRme+BKhMHljLFq732lVDYW13jEcx2Z3h2PQT3Bm5+v2Ke3aSSlvyIfvIiPUl7PbaaImKg19wnAaZqhxheSwVUHmBIbfhCt7UbTP3imEKl35fXcbYIOrWiea/uOy+xwcIbC9YkkRyrrk4ttFExRuZfnk8L6xfglyY9xlZak2OClqLK91l0xUfz/Ol4ylpQxWhmwiJVMkyL+S3Ild0A+CyuxmekcsgzSyx4OS7X7uc9u1SeWjB/mSAzQh+YsZis2J+hFLavUTzWUYWaKUbHcQjFQLHD3ZEoZEoB8iqY6ogeNIkrV22VVHlcBm4QDEhijApnte7OaE1kXLesCABKiS3tWwymSpLy6TMXx/Md4XSY9A+EvLLgUjkgpHq3ftMQRflNvLYlEfYJYXCoAzo36pHymVp+uIN5BR54BdNr2DbfBHKZtGUGQ5+EcnEhPpvoMnLcf59IK7C99kNJ0fLzEfBO6lvGKfG4WfO8AaVDo8sonaJCCMEdMUDKmNXlBsbZegXWotZLdIbZqN1m9OtEt6ey5PAVqR9nvHL0wHX006P2b1092Rv5fTfaltztpXDsJZNttqWP8U2vkZqYPvSBu3jdCdY4Gkjnea47TzTnPX10EdFcE2r0h1G4ap8mSgiC46j6Wuzj5IhylgL4fbmsPfNvtRQB8jlW5Btf+i13Ed79W8YnzyYbgcF02GR5AFlXBMfvZ1Ve9QETFnSDJNRLcPNNpslNVyQITBlPjfDn3NSgIVdUs0EMDsDIQrMvKHpsWuiXnt0sKrRBJ+MthJh2bD6jSSYB/f71OOWT1t+i/wDZ3gJisRR+KxZiCTt+y4zygjOiUH65BcljjTnEv+XzVci5N/C9SFyT9O0Lxb3/dNSVJLKcpQGCOz4pgM06NFQFePJ2dr8az9pjCWRwuGzhpRsBsqyOufX3QFveABvRDeaEyNWOWuCpnUMaNXy9YdfODWFQa0Snff7tDD/fG0ipAY4s0/fy7IZWd+pvgayBouKlt57JcVU6K3TMvE=',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a',
+ versions: {
+ '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a': {
+ header: '####',
+ data: 'ihfKoU9bJ1HxBWuZ+wyKaK9n8PPx1MJMB6dppZniB5tnfUvnUf9PPA78x3moJRcJ7fVXl/rNHWv9Sqnf3wggFD1iuDFCbxXAY49qrWEdXWFyGM4cihTlWQBYZu+cMWQrdi7dZPUY/lLltKTSRKplyVUmqfG04yd1qCzmiSJtzKUaIySXkQGX6oxoeOMpw3eVaKJjrIgikmjfxE8f43HNpCPG0TYq4CNmvZENZ1z2itRtgIUSdwEaH/xK49ztqxJPrbeXxTBUKIZ/toE79okotm0AysfZdlG35PT9eC/hzttdfBPwqb7auj6J3ttc7DWkFrKWEemw0dHZYL0ut+pdodcvWLLrP1Gyo9aJwfE5heImchRbGal2BTUiyZO9zALdsqjRvMYSyHfxtBUDAggWL6OA',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ '6b147cfb119d690204cebb33ac047861a74504c87501432d914e07008ff3cc3a': {
+ data: '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',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec',
+ versions: {
+ 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec': {
+ header: '####',
+ data: 'dn15LeaR9HinK07oo1yVaKS5SgM9SN4jjB5psuvJWV77JPSXYngldFuC16IsKzrkMuRg7MUhdjRuxYxRnTla3FIzWyuwfF5XYHM/AlHMbp/K30yDk12+UtSAEe1r8bUg5ra2KOhZ2pGTxQi57qWKkVkKvnmxeQa/LuggfC8PmlYQpC/8acTPxoy5hiVmHsxO7yoTl5PHrIee88kgLiavSsKRMMHt/zIWoI7liVcPV3xqVBrlAoOgtATNdqfk3YF4N7Wokyx5sDDOlxCXYSoQkHfTNVxL6la+tHcE6pC6OezbwSagB67ysJ7P8ek2kTNfzG+/smdxq+iolTlAbJ//MtdBEDOAlfsc6nXXo8N3OjGNaOActaMP/EiQUD2NT5L/JOQw3zM5lJidNcP3urT3PxQ=',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ '97291f9d95cd97d089f940e5a4a674b7c33b06637337d3722010b528ab1fe34a': {
+ data: 'JY35iFwT0aSVy9r/b2tHFmaOC/AaNieghwPqz+PzMgu82k1WdeKZzpIZWBf7ku0VXUf1pOYRwUVM7AblkFxlnNT2LZeLZojwIAneSZIBRExaLaRpZqQEdqNYUr6tVayAdgB52ObXBArwrNRMSFkZHicGjjvoOI9WS9G+dhlPaY81yW5yQhmJmu64JebF/c2HljkBj+3hXI4utRggddaDKpOerSw3PHpbJ0dPSeH+EIWG+3cWCO5Z4BVkmm/wQZG8wu7ymWdxE1Njm83XiTSLGxc2YB4Tl72WRe7ekmobFGM1BRzf6VzmBKOFzJb5SBXCi5XdGumv1GgtJEIr2N4zRJMoVDTu9qSzF41mFKbuGaldMuVI1pTsDTWAOFYq9ntuFoNWEGucWOeFZZQQTvwzdAq0LLp8/A3qEc5Xkf6Kge9kkG34kCkVcxAKhuGWjxUVWdmLSAHKNR8hgipKGhLRoUVxJ5kLFvm/7BNXFqsKdZckFzHXfQcemFoPKDcqhuGVrRhPQ2VG4oUJTJ1ZjtQsUwJPHr8LNBvD93gHJetF4DtKwercWBmlPTAx60esw8oilgJJoU/u3SnoRa/zQdJskPjRvn55C6Kbp93GGszhiUNTL+SbyxeZOyfISLj5xyVEXCJwWOynzITQfrU4ReoWUAlhk+LwnAbnJ9rEqVPkjbA9cB+gXj2iM5EDLT9yaiMlNmiPtrq/sh0w/VV70Czgzw+JMZ7efvcTP6Q7jKEEDDF+oaj/x456gjeb1ckkK5dkTVk7AXMFAwfjfIrrPMpC1CEa5h5bwJhpqVe16IU8f7Nb1pnGvd0l8VGUAAavrHXJEePqTkR+vY6I0hriFuXTaMbnCoJW70lW/FQao7SzxOdybymL1pWPs5bVoUaX+zrvBKQr763+dm9gSBhGtpngZ2lQxmO5AjfRuv2rG/SPZsFYhTE4JKJIKEdYT96FOKqgQUQrs1MLppYH4BTqgKwjMUGoTWGJkfF7LfEgbOwly/ZGLIgCD+fk0u9a9DfRB4dIy7wstU6MN48nd5zz6GqLFCrf8wtrN1yEpI1QqjVvNv5bzuugJlnT8WfU6m2ppKBmNlgZVhYc0Va/90ybcvQDLPVVBTnjYydlgE5z86VfMREn3/5+DgsXVXS3QwXuWxjYktYsg2ts0QvzCIMCk62pAx9LVM5tn93lm+RNg1y4EUiDTbF+NqYDCLu5Ea/0GXmaHLYqu9X6z5/jPUq+EgMn52L4WsRyZabiPgxCvXjpntPJdP5XeQ5i4ACOFhUwFFRAxWPWVWv6ecL29f5WoyfXBsPM5HOSa5eXVz89Uk0v58msbf1sxkOjjzSXQOB/hUrkSt5ZlMpVfWye+6uBelHCWWfivMi+S4tveDJgDbssnagE8EDDZxIYuYhYUGfbUjhnvKuChAWw0K91ZtRDESFMpRlgBAFCwxgI2KoDz5yFWNckPA2ki1+VR6Rxd2z2+ihu4uI1qtZdzSC58PHlBFjeZKFzZPABfttlZ6t+qijg88Vo8fLLxakwhb2kJ9Fs3I3zqqnLYfkvfCw0/ZbwC5fH/5Ey9WiIaPJBjW6e6to4NJcy7pEAJVKRsCpfP80D3+LBzoCFGrdMmhwymWvi7xlG8oZPYkJrvhvW46D2apRdqAKJrfLn+oX1fCtkfagH1bJ2o0a9J+ckG4yTtoxBfkxSJ0cCErkQE1xU6ADCd8+p+2Mm1Ls3p31+Ynr8CSGR7+ITZMjMysnIc9J97DrI93Trab1mOp/T9zOM09woCbopg7IYNQxRlcmpH/vZozmGWHBWGHAvl/+ey9FDwG1t9BXf8kYGlwg=',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74',
+ versions: {
+ '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74': {
+ header: '####',
+ data: 'a4+XW+nJaw10sl9INOIl+MBO6mRdwmGZUW/BRTvcj/PlpVA0vCE7pT4JgdX3IwrF1JTk2KaGHKqzKGf8ydUiDL0p60R70BiVmQlony3kmi5XNCZ6+Efh+EGtM+4LNQ+2jojnUuF4xKRk729VMV1z7b17SiuQzcHwkecBgYxZ2Swm1SJaia4c0tk46pzsAKVrWVOuadtemhcJvHnYaQ0I2bnUEtct1wYldSI0DPkIuaI/0+xDn9jx1nk/HEu3p6cgMnS2vSN1/9jXYf1cDsrI1+yuO8lFClx34kU2mXCjDgFZGhljkgU1HJfeMufqyJ4bYPQfTL8/5NwFNNhw3HVFsrcWKcbct6bM0Puc5bFA0cSMCVx+61ONXqtkKHy9NPdvl4po3+TOmtXjooSOgQU2hg==',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ '98af9721614f0d2f03d89ea5eb8930b7f1bee6a55a8e81f0eabe964016a930e3': {
+ data: '0ZJHKdh904kbB848o2+gi5KMfQ5p5c1FeE4PZrZHhIyDl13DnxFFu1vm1t1OI3g89YGQejU0vzT3+d80MoO46ItdAX63V7exVFkZDnkozjL3Pjo0iksDuz1nAHxHGMSoixIKK4WcnvqMWaMdMk8LTCl6EZES3aHaqjZ2ywROgNBj2exGBw==',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3',
+ versions: {
+ '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3': {
+ header: '####',
+ data: 'iumHWw8KQNnhFThhMLBzHEJFZ7y53CqAwEn4DVn1PYVKpaMxjtBHa46XDDA3qliCbqLzPzDKllL/7HHJZcxxjyFMY/vV9p6YsZ7F9tVaF1cCQrCWdM52LDnKrmNEH4iT7VzJ96qsro1osgGwKwIucSSi1FkhWOFtOQhESWIS9TVrFo/yQj54z3x6k4juXyeLN5yDrgieypbvN3nsTOCyjIfjpaAw6ztcEOo/8R6/+mKEAej/eVs=',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ '9ea260fcadc1ae2bbb8545c32035dc55499f715d005fbec71179600b50aa907a': {
+ data: 'WQE2bjUwhJOc4e1OTFI4xKTDRNIaJ/QS+OGszIo2GxP48UVsjMts3M5TtglFfgUmXPt2B0S4Fw5zALIs1r4o1xfqTuhvlZ62VpzgkMsE9Vl0fQsZawK6a8oKErwAoacZqkdALXGjaOYSP410tAcFIhUvsBmRWZIs02EOV0DMqCe1fYSkNg==',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc',
+ versions: {
+ 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc': {
+ header: '####',
+ data: 'VsZfs03f+Lm4zyHzyLstuhqWX2f3fDjw56HA1EvhFAPrTK6uM7pvXvseuNGT7oL40wJQWjLuJgDZ56NrXNDfoz4BUNpcrSaJ2bUQS0ZDjmoOODrLM1hFmd/gzsdpx70M/b68BEqVbHCf0Z53TOsLXaFZmAebMvbrLMXkAIYP4wrhbLa7qNaEnj7qUaV/+q9CysfaOKpRomaj3i3F3/kohJL4NdNsZ/N7qzY9/pQHFaZT/GEPvZbiRr5tGb0oJLMG3zsHKrmsZHh3kpHScyfxqWFzm85ZRAEx6eOjXlfAZey8QgZyLVmRsVsDyIRhIePHCuMukRokohDjKwlQi2k6eVXHSaEEAo6jbK2a6LgbbQ1uPNf7ay9WtxaCcGCh9qBZJ7Ndq5g746AN5VzqyUc0swstRFOn9FjB99sAenhpqzo1z0Ddfb3reiUmNuXoETlHlA8SYfb5TCVoHfw7lgV8ikv4nXW7eEAxYeB03VWBuZPFKzlI4k3tWLHGytNThQ3ZGhcH5/Fi4dKRJgtzgWAJdwX1qgP6+Gcu3DDcrzcrIXFWVtsZtFgwvS5acy6hBha1gN/EapZoidoiIIkh',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ 'a92c1ab3df0677f63da3cd1fdcec440fe3763e072e1035f8455672a97344a6bd': {
+ data: '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',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 12:59:02 CEST 2009',
+ currentVersion: '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854',
+ versions: {
+ '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854': {
+ header: '####',
+ data: 'EkK8xSZRZAvE63intN3FTaRKNhNqZbu/5L94kE50wy/OdmBmYk+TVYe5WmrHxrJC+9c8g9Da7vQdH7vbBWwlLpbuPtMUDUxZgBQHdADAxN3OKrTbf0ZXLVgWtm1D/OBgVQCCKiLKPjujFSs5Kp2Azjnm5W9gLnYmktVhRYY8Y7hklX6AMyF/cTw1k2HdmNZ87+YGKZCUcDhDr77a6m5hhknxUXOEXaeKlL/Yn4QudgCJdhtbkxifB2GPl9qal9DOsiFJwg169weucHUy7q64vMFEc9RZbbJTpH7g9qGXELb7VtjaKv7A2N72FOt8WdJux3nsgBrAkZd3oIPAGr2KWSg2bxbJ5MU9Wb/LyTXIJQb5z/0UtF4dlavW2MFKBGg9vIU2fMukOq1YWKwZ1TjG6GmO',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 12:59:02 CEST 2009'
+ }
+ }
+ },
+ 'aa5a54aeeb4f7926e4d0b469207812e5384a4e00acfe9248dee45e939dc58b42': {
+ data: 'cGK0775KN6QUhzU2QD7wFYwTffs1nZ0wd2otvljnUs8q7pzmnA9XFQNkvuqjh0WseVZdqGLfUYrrh2UUhMSpKec0tKEmrNqijP/7LYiSBte0Tlg9OXzIqvdhFEtDO/WC3do4rYnfpc0pJolE+I9J249MrCbSXyQV8hDeD7IRFJ53',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:27:25 CEST 2009',
+ updateDate: 'Thu Jun 04 11:27:25 CEST 2009',
+ accessDate: 'Thu Jun 04 12:55:14 CEST 2009',
+ currentVersion: '64182e6e8c2c3410ee0e30050d0423af5c88c5c53600aac101fafba9debec99f',
+ versions: {
+ '64182e6e8c2c3410ee0e30050d0423af5c88c5c53600aac101fafba9debec99f': {
+ header: '####',
+ data: 'UzVgxfbPpCV4VW8nfK5AtzyKlFUQs1MXW928M0cWqPzQeA9t0+oRS60ZTvDdMjqWzM1Qs0mOhi7wdLdOoZbbT0wUgeU28IMpICZy0Jy+ezjjQxRnC8O5yPQJgg+fNrUbtn5BWMonPVWC2hb1wyEsIJyTBt7i3JsxVsPzQ18M1lyRZBwa2z0QWRZiUF6aacNf2GFXhCkycacNztQVnMlq2f7AXPAF25l9ZQIO5VViBZnbXwIyFbrmP2xJX0Xpp7Sspt3sPwWzg1BpTyjl/P8tDHA0+fe/iPhLGNk2omBko+rPlUwBymvh/t9G4PBNhuHTpEfHW1bGQ5RHGLGLJsBfpNuWALeAfioRakynNpGaCaUhxKOysTyH7BcGyDbh+QxyBkX7ITNRQg0lfNkA1PMRGnREph2g+Tclizgr0eawTstTl1qma4qYKEb2egtyABuvhi/q7ltK55VQOLO51VOY4cJQiwSXnk56FXFEaLS7Kra6zc85xJY1ZP+T9CZmmd1E/W2TMQ==',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:27:25 CEST 2009',
+ updateDate: 'Thu Jun 04 11:27:25 CEST 2009',
+ accessDate: 'Thu Jun 04 12:55:14 CEST 2009'
+ }
+ }
+ },
+ 'c0e76e60e08faa3ffa9d859ed869ba3cf3b42becc9478d45ac94cae6c004cc24': {
+ data: 'yEGo5WUC1jnPQRqAmksQH5Ph0ChNdS58uolzBds2+KFBNZinqbzr8OQgBax4/zN+lqLJkvHbsV9/dhPzCfGHV0Q3q6VwZt6R7n8b4V0F+IYvq1sbv3THahwk7icZcrJi9TjaAKp2w9IBJ/uf+rWoZKegmZXnF8cjq10btOk5JVkVVSaKb2c/v3CLYYz74PEb4ImMVSzNxWTy44w+YOIWpL4IMaq2nWpULIkulV0UAZLOudf38cEu9Zb6T9yGZPrACSjlANW1UhtfH5KosUMhMRlbyAWDD/CTF58Smkf/u7kzyCH8E/W7BE1C89GhWjaMwQq2VAubJ9VAE2CAJG1ax23/ZXoUgk4oK7ReY+J0QbyuHnJDIN2FhRLZt08MD0TujA4xyg/Hp9S6F8cd2hV+BFVIAb2/jXCH2OqvQ4pq93DWF375P63uC7/uz3j7+jYXOmggtfd0IX+d7uSG9V7FX064dl7xJzggSwnkBXAsuSwiQjFDB+jPpTY2k/F5+UgIVEzdR4CPMmaEc+Ied16XVTr6nXzqK1zLRwmCbeCL1ZrahmZqhqJQsV0Z66wQS6pBr6dA9YSkTCzH3lgBg/YSmNeKaaPmwD1oSoqVwkzHigdUO8lwzyvuMqZZdk42KVO/QPC8ex92dvzwvSoeW7EVNzP5fSymd6pmO3d7sdWCnzEQCWP5ADfZBrH3YH1oLY9UzaBGiLLemM3TBZfBZ3u7k68y5QnCfuHtL4Y+IEcgtOUtAe/XErIaSZjjwfw8mfrPjQ95XA3841UYNCtoLMPTGR3rRSj/Jluh6MHJc7CpTOgcgbi5VKqOIrHL88Qs1tNK3wBA8u6RhIG6B0I4lfPTE7Jq+FYDyoeNf2qGqd10XnwHi0GSoCisi4NFawaric7GmVMuQOJsJK2HVFJ5W6e+IhShN4uWQmlFpyifOd+91tMrJ7uovviHkJwcg5ROVTk5yiihGByRUmFVU0W1Azb/CWiQp3QiFKSyHq+uQKUR9gPN1WpaYupSnp4+1tJclgdeMwsQeE40qFxQbBDZynqWeSFovPHXxhiu7xjkLGHlF0QJGMXaMca0RIr9XiQKSlQ6FrzpKnFzmOPh0LnUDhd8FGuMPgHhZ8L79Utablh9GtrJd1kWzSiUKpIQoZm78Sbls9wyc1LHK6eUAYwB6A==',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463',
+ versions: {
+ 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463': {
+ header: '####',
+ data: 'k7I09dmz+LypgSeYrYH3JQGD5Mikr1YV58akOGEn2Kmi3t3n2ngvDB1+cv9hjREPUiGIi50ZQJQw5pt6eY6jOD4aCgGjBqHYNS5gfbaW9dHhjXRPu2e3yhMm+YIlAaF005zecnB67RD7POLfhRx6qjLtqktUt4mAotz3ts/nUmHW45psLPLVBlpmeTNAaSz3nXubkoyfpGrotGGEQCndB57L5Z2popMAdEhT2mVQqzzpasOQnp4PJVf+1vfrQ/9AP6ublijutHn1Oj/HsBmrwE2YQpj2wpZlGAFdghKBgtrvLMk7dsIdDuK0MIQoDmgNPwgiF5NNmG3hoNhS/WNls7uozBNMYFa+W8IzP3e442zJINdGs9zDpEVWZfC35OX4F6QKGSeoHDBkpB7aWAXfnkKz9owt+8OEVEQ=',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ 'c742849667f8001483c1e6d3d388ae9d02a2e3561a1be7b1866b62a356b72b91': {
+ data: 'sk0Rq438xMuzxfEwjPhlg1WxN7Hyrs6VW0wFLQBB3m/tNK9DsHpswq2eMRqKv1S1q/MFTyx7/Q8YVxRMkqKWIgUQRe0g/arWR3iHP09t5JMFIEqxIbCSotukZBgy5aXlG1WMnEsT+tIqrmJZzpOUy768JpkJjJxdr2dlGeCUJbO4bitAySOvpUoRlCb2/a6D5Cib4NU3fjzrW+TZyQB7WpspAfxxyg2zTU43D74OAJR/wy7K3Tp7hOl9cXmUoHvM3vp52ENvPdZmy6wAbz5d5Iu8KL1mxwGbl0pxx7dDecbMJOO/OjHwH2/me+DhyVTmv5smb37X90fwZRt61mn3A66ECsp3nq6pRZaaS+U9WRC1UAVifc6T4DWqrrma8D1BGnLeR9lQxJj7Jm4foKvnWqSeurdRNOyZ38XK5SBSZd/FEalS0UwawX/5qJhwdK2pQRvrTyDDrXRSNj3ssuB+3YX6l0lxacUO29wFjmkh2WljCkDBYPNKOVRLBLUtgQ1pWKciy8BlH4GsqdjvkcQorRgfgS5L0Ce2bHWbBsy5X2LReW6Ugst2wt7Q4xS75P1qF7202s89jQVQritexaUwbCibrZ0GFZFfwnDT+JjKiNiB0WvDBO9tdbqzCA7T62+wUOtCX40tQc6+4mBQkkU+mi6PfsInGiafKctrp1d7GMQHJWQHIJhx2LUvyqPxOa0hE2vqCSJUZmNVD1KzMYGguPtHbuHHaWXc1cNTjQuuTyXDuewBl4NnTgTki43J/lVt0VLuoLIEQx58y1rMTVDTiEufA62mmLxokLYyt6VLb+OeprhuYiU0PhkgkDjRstSnRE4B5JsvFcPdYENYJwRYbC8Ho/rnAvfBdGlYw0TGS0MFcd54JoXiE+oVVRDuYTVfm9ytGYkG45Z5uX0D3Qm+KZhGAd2gQ+NX6umxy0v7RHwqtUjSqI4U0SOiVRNdwFesQRFAzZDtr1tKNf56ACLt/yXl1GywrHljtr4BlQ0Nym3upNweQZyO19O3kaQmtbTbp1Tg+xewXr2MZ2U2QQRNrCzVeqe29eHU9133xo+97NxGi/HDZ5tr5aUTB+OXqnoIzSeqyHLIv4t6r8D29+MTfZsf4sNC7vNlpO8+GLYr/0S5md9Z/zlx/2iPeAPnNkf95gkav+6U8F3nL1Ok8MUG6drGrduKyv30CGDEwWJqcDFJqOZjs8reCst6S1ijRhwm93fqkg+nzqw8mZYeltSbTXFmpypD20Ravw2JdJUyo3umyZiyPaL9UsCFSf/ssO47C1HTN+OkRtMcTAyKEqhzvUei/JHaOvRhmMCam65+gKuoCwy/x7Si/oRrQ8lZkF8=',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5',
+ versions: {
+ 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5': {
+ header: '####',
+ data: 'bGK0B/s932NBepXEWJJC9i15cPn1iy44m2xFxohFQ1r2Wz4dKsy1JowXHssezfU29ge34tx7PqbJM+o6ExNVkgufb0tynMeQAyPcoV7jSnxCqBUfupTWndRq6YHkG9xdsLLrrbmmRwV7fIr8Xu6PGUbCs23sDFW25tiLDtps9VqFNb8jBQ4ms56rjtDVsL/VqBBI0koojN/e9JZr0/3Wv90a1qn3Uz0hRJnryCPuoDBmcLFdlNcd0W8I/8SGJa/94V2S4QOJD0KqP1+/jYA6p054V/tRnDlFdkV5G8vm0XqI1t5cehSV/2Prq3fGj2UaAs25C2WU0xAHPKJErzy214WztzCd9vqINx+DtPEewS0QcVvnqnC4kBMhGWKUqkJBySSQ0nHvkJrBOjeratc=',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ 'cdc4624c921b8d99918c3cab5264b5e6de39df30ed167f504bc0a2c612404d5d': {
+ data: 'MVUf8enllOr1nuCWegNFBnC0YrydNpddm5VZzlT/xJY1YvqIcYnr9HKk4i55TIdA5zjcf5TqUdwBUJ+LbsaGA3CH9YBz6AqAxt0mQeTaS8ufyXDzxHthmTKcsKjPEuJ+1R288jz2D7Lc24+YDNrAySXWg2i3+mJNIFU/Sg7+rLiGpcvB1go4zlh0rsZbM7AnIcCRM5GQLVxtVn15xC4fDZ3rQDu2A3GNB0+RFB4xZlGFIidr5ZmUc+3/0eSdMWb57xRdCaxESjWQbGkDF6OpsozPVuXEqd7K/6RnHAjVsTWvLGtCGttznrCcaXquy1xwUr2LGnqLSu/+Jp7hnZhkGGrFxMFui8WyiVhpTxr1YkB8X/S8lTvsgsUg96PGgVlWK0XeW0GvWgo+v+6RyX4mChoTO5lzIUQuTivve8OH9RHY8YwUJeiY+Pg5ih4TpsGULQRZBIXrmWGdBA8euFSu/mPYuBZ6j0+wD5monR7pvrIf3kEQx2g0N8tdKmN0W8iYV80ONMWqwP2rnbBYHbHE8cljP624xO4fXWoMYlufyCmQp5Y7f7ugw7kWO1gYsMgY0e1pZ28U2RQsTFNLXuLgbeOPz8bpsm0lTFec+WwZ/yMTXFfaz+hFKc60sUADKO6ax24pnUId9+ih4J1DBT9IfUadXcqKN76nVWl7/iApOu/F9kMLK8AtxpSpTDVEZTcS2RhdyvVisx2vqDR34JSP4Ju7qaLIxOlMrc9DVTrz/yMzqwjjefS+w9IJvuwz2ikCW/m6PesRwTao4K0TONJE0aX0xQ19NfYJbNU9Xfs4IFyr8c755UeUA8dK15P7hgf3E6A+pBTj79a3B2SfKh16jOukNsdAVbZkJcc8m0ABR1azzNY/zr8MnHjpZuhhFFnqtxoQYi2si4Gln6Qh0uLwTN4557Igh2W0WcZKSAo2wqfgTx7iRkXz2J1BAbdaN1wmgLZKfljq14H+YGOiqhHndM3UV5VCez1tpA5eHDZyEtMIyalMbTvGRoQ2b0dC4idO4Ec9CoeYwjRZLS6wGG63N8RBdOK1RQeW6hbOrgJIQiGyZ7e34OAi7kSwC65f0Q7SOdg1JJVLgUPh9vfCkFyGEF5OFUNDR+C7Whosvvuijl4hKurZj1KzxoZIAl1IY7C+GiAL0FmaTqEiQVjjz0xf4UHqKw0qEwCqXosbhuwzhmV0EtfNRbWEj5yOt9MyXnIdEAgmer+uEP6OYJTtPx1M16KFl4r9BZ+2h7NdAkrBbkuhiq0VZvBifkinOwe/P6zo6mI0NVmLAWrAO8ZaldY2Ih/Px75C6g2u/zA+2U8k6283cQFt+E0b2qNdUcqR6sxz7gu5Ym6Ssf3+8x7KHrlsXoClcuuv2MO6De7GhRbf7+fC4IlMuw4YwRS0MIFg+nVMV4xyCAVn8z5jl0yngSt2wjdrLooDa2IRKIpxhSreVdsttCtiN0pq4ws+QTsg7PTUf3zAgVoIfuC7CuTr0fCEtYpZxhey7cuvhwtbdcANAc23OoedjS3o2z0vy9/dnEA93vbVmJ7cTztPOZA6kKKfhaWBMZDzoNbkLU7ebzqv5bpgY1/aKYLVJxUST34ZiWigna8nfBS8nnR6N0nKpslE4uPv1oQgSGTtl3A7e+xX8htlIzDxLIblQjZcZgdtZVRSmUW5/NLraF6Fceo+FZcgxiO7+0h5ychXL+HkT81DCbRMchmTOA==',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ currentVersion: '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130',
+ versions: {
+ '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130': {
+ header: '####',
+ data: 'wRPWbH+Dw3y0DuWz0YDL/e5zTQukx6++cLlCY/0Fp1J2qZS6i6/CLhQrZdOLtXfEhgzkxQygcYGMCyz8wDILafKNIAoS2BcuNi9RbbA9tKXDeqINcnYdzA2NDWj1tQDoNU+/KssWdkI0VFSr+A/EpLMfa+Kqw4SMqNVbeEAUT2Nkyas+eyRVu2iLNV0bFzxzbXvHu0XK7rqL1Tj1OxY25vvA/tVRI4jlzI/rcQZrfVB/BTqzEymFel4hDLu9d4UmZn6H8gubyAU5IiK1Jf6B8nZnNhs0JKUPEYwSXPk9tAupRjQxsac2XPyUQXkemT7TgZdFuzLYQxOAtUmYHhXyigzJRDRY4KPDJwcHq5bCw4OwBNzjhCm0uCQLmRpDIauPVf6EGNs0vorkdOW758bmUjMM4fwlULIocKfhreJrGiGbXTNW80h6SljKzXdlFZAYTSdsjmACL37xkgMJI93faHuGMQ3HuVqXuuebIV8Yg7dSZdWsEus/cQPnOXvVok9qwJ1L+wJs0darskaEN9CGOEAjky9iVoRLuKepjPWrSorvEitedjErBntX0ErI9JDTCdke2jO/2e97fGlrU9++k7T8RRScpxBKmXVHnYpqiesX4KtORnGQFrV0tHgoSiD+Q9YwBj3KSRdFh2eZ0t72ejqehhuR69AZqC9KvY2b7O4PDG//emeXLXMXuVcBawZGgwpOCeu0YunjdgcASADRPVTh0x6IGP6GQ50LoiG5hhiA4z8PRqJ+twcvZ8yJr7AOOTjyMyi00nXPG0OAG5Xg1sTzXtqTwj/xVWbzUEMFt0nxMSp+EVD/Zo7+bdDY20FKz82y2DabKFGAcmjuLTmmS1RaLExvtsZcB5QihhTEwEUSI6a094udE2n1dCz5ZA408BCMi78aHFna+pg8xLEJHLcLZ2XJigkF8r98XeA4fFjWUhfYEhIjclG2pIaSBaXqRT5QA/ziMe4OBTLKTHIp7K0=',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:22:56 CEST 2009'
+ }
+ }
+ },
+ 'de7ce7e545acd2739d5d2d00b04f889fec7acc2229082a7a678ca050e2fdd3a0': {
+ data: 'l5j1yk5VXiXb+81T15uzjSwhxBdsAQ/JG73GNCGulKTA64NmN5SMxDL5gNV5AApu+p9AKKOThZNER9wQgDt05svLWN248YROu7PTsBJpHZYLt2JKlRDO/SOWHAhWkmHrufDs6omk8TpxVbIibsE9Whp4CjkAneGFpvzIJcdZDyWfsaFXKs/gC6O6mxYgU6dBtvMemorXCgSEwL/B3NF6OkudADJUZTIha7mjxa2eWQo901kwD2EKSvVyokcMdok7FyR4cXfs9K0TSOOYK4eQWrqE6wnt3Ab8OSO9oAdCFIUB/WUES3dF7zshLNFG4uh3G5NbTHYBoOrUY4rYOzx6gXWKgv+AiqsUYQGIphPm7GSs85s0eb9IiLNb0rQnrkX/Qeqorg3EIe0aRnWmAWtRWb61vClo1lLIJFWXbK/6DSecAfWrQmD0ExbJZbNQ6WjtVg7fSOul/VGOrbiG0QysCJI/D6Pt5nQcKf7Ooze67CsrYOnmF5oU6BPZHuyNPsaAFZR5TOZMlB1JASkk/dS5W9vgX02+xEYzT14ZLqTlMsgX5ibw69xxdrTcqsbHcfbGVn98FZMNHPhP+XP+ED8XllDomt1oUZEXU2cZg/s5QLFTYKbQIu2j8xgaDMmpAyzIKQtenpf4G0VMVa1T9lVApqmw+ILC31kOWwlEknQhey1ZMowCbfLMw9ipozGyNvG8QOoDQCyJ0nQJ7OBI0m4BDXJXIj3kz6LDrH2KJYu63JFaxGNFhbNDoMNhTdLyD7cBUps1++CgKNxcSezY2sWR6YS7OBW2wvy/X5yKIOtWg57I4vvcFQCs04EanIuViPik2CRbTSAUIiRvi8sbnqXYNT1PpBIPiQJvIbi8NSjrpTjPlEL5MJnIdjX6mjXbiwp4qWh129MvMZzF+Bann4BlJQwwGhba/X9d0K7pyOIQ605W1PeOjgzSPXE02wcemgF/tvFXSDtO4LOfiSCC04OkMtGTwcG5yMOzU3rhu64LdDknruYjTZ3W3AJitWixDj/ZEeseUCQbaJjMX8wsBFrPqbTWaC9MsztY0qM0w4o3lD35k0D3whK7zdfb0i1rgw4TRG+UaAy4iv/jxB9orqjS4CULzPDXZygYopwxRJowF4Sm2u8uk9/NEsuJcDmfHOh25UTnMO1HGSNRZt8lnA==',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:31:01 CEST 2009',
+ currentVersion: '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3',
+ versions: {
+ '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3': {
+ header: '####',
+ data: 'zC2F75+cfQZXWJ5EquBKnCHqS1TekPWp4Z1KXd4166/CY7tcxfEzPtI/6QqkSdfPYesPgea8G5vOhTzd8yL6nIL0ksE7dTGLXx38wZTXrOftuiHKuxW2HLGE02WRtwWgvgc0v4nkG4mm7LIwX5XFSygGmG3fKfPwfLaRhayD4Jsf15r/zWmU6meVCvR3VAYvHgNqIeEOhzhVN/ZMZSZ3fb64CyDa8wc9KZpmbjg6s+x+80sriotYwYTq3CwiHqQyZOZDm3P7rhhbqy3EhyH5aTfroSBWgra3HuCzXAGFFog3S1zl+a1Mr2ZlmC/RxCiMVcHVQ9CluNU4fITebcxE3VdbcgcOzdY3O7U7cWFaCahk5y/momzFVstPsPQBhXfX6p3ofUTuHh1jj2OIRcvrWgYb',
+ version: '0.3',
+ creationDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ updateDate: 'Thu Jun 04 11:22:56 CEST 2009',
+ accessDate: 'Thu Jun 04 11:31:01 CEST 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ };}(),
+
+ //-------------------------------------------------------------------------
+
+ 'joe_clipperz_offline_copy_with_multipleRecordVersions_data': function () { return {
+ users:{
+ 'catchAllUser': function () { return {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ }; }(),
+ 'f527cdd90d0d47f8524b4e165398ad1455eba515d04abd101d1e93b3c6ae0674': function () { return {
+ s: '95ae437caee9bfc2a2d716291c2d4bc7b6412072df45a1403182d65ab62818ad',
+ v: '30cb1d4c26a4b93f9303685f2f08d32a109411044a1251ae3cf82e6032d18c0f',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"2977aa5f99a9f6e5596c1bd7871e82d7328c3716c9ef8ba349ae65f10d97924e":"0","5931d708fcdd39af284d4809135393c81210a10b0e9d56b49b2f2a3b8adc9394":"1","0bfcbd6662f3771f114295df779a4e4535e8e666842c2336da1b095ca1def657":"2","2eff872ebb19c0f8430518847dafc819c0bf7e0cb714b456d74603c250f2efbf":"3","983f262760a45171a8dbaad13a7c87b8a3dd267d1cdba7850b07e58af0460378":"4","f8141d3cd5cf93f3ade420838f98e4bd0e5206d202b45a24822afc9099827c17":"5","25bc43a5f1aa780304bec9cf0cd61502f82243053b5f72a55712525b0b8290e3":"6","5ea084cfa5ce8198528f466e160862b4f17d0a4f63d3af45518c96413d16fe69":"7","b81f9a1d9267daf4afb786e8d477c15aa3e1babc59b8ba09bceddc700116ab0e":"8","d8568a483a8f443190ba723b391960554962760cd886b2484f2698816beec530":"9","42c7a17479baf21938c87af38ccc3ceb3aec21535c644f6c90496f89008f7828":"10","63e20b19028b7dd1465cdeeed60ca75b5f5508cd01601937ae8b0d1f981057fc":"11","7cda06249cfb102884a133952770b85d5442f8049db132d66f761deb765156bf":"12","166d907e97005cbb29efd1841757f7d1a57210ddb32605ccb6841f35f72399a6":"13","350a8d666e033ec01e203e0b6df730bec53124f9ab25f7942bd9378e4b5c01f6":"14","a0d5d8796793035d1b109654c68d34b94e2aa64b5f76d50f01d9a18ab1cdfd5a":"15","91dee4945d6660e7c0db77b72fd2eed3372a46545da1c1e5600a80efd554977d":"16"},"data":"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"},"directLogins":{"index":{"03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c":"0","a48e38845713462ecc9f827149eeaae87da882031f98ef8ebbf9ee9537b63468":"1","9b7a30e667afc9f76ba77600658b2c13bff52432d444261d39bf3d069a160afe":"2","ddbc8d01300a4f10631cbde09e1246332eade3a877a2205209f9eb9e5bc9da0b":"3","f22dc41ffabef4b3bc8f7af804fec975bd50718098322a673cbe4aaff9464ae1":"4","2df54059e78f5771f23bd285cce19595b38331b73d67020424d9a1b2257db09c":"5","065cd0c270e5e8ce50e4ea8e3828dccdae18c01ab030813d756a87d03fe68784":"6","f695fc36ac56bead80c0d20a88e01e382819c18dc268f1679551b7c83db7cb14":"7","7e1d069b7fa57c03bd7bf48807520feb953157834503aaff8c9d493f37dea69d":"8","cb9ae0bba1957075ccdbfd3b3481704d62087687a2ac7c411a4f07d444bde0f7":"9","61e87fdc4f1d9112e3b30c1f6812d095dcdb24f014c83319091eb6c9899ec348":"10","1f9bfd677b531a03168d3f8bd8afabb5357244a7bc355dff50bd6c0a072114a6":"11","9f7979368fa29f66c44bd97ecaf6c545abc800b1c7bb21b7655a68e1514c3906":"12","989593d4c48929f0c8f1581aa96969c622807e99619ed4732026e967530a68ad":"13","33cf9758477460a8056deef0295a1ebe65b39b392c361ceb920a83edacfe5d78":"14","e9a16316f330e3d150f6ffd194f6fd8acd1426757b097de4b88ca0db875202e4":"15","9fd2929cde3d32d9cbc5f1d787f2f64729a5e12a14410556b31c0c099762c46a":"16","dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496":"17","aa18149164302d5dbe7e2d3724565b9550e00887b49978559783b2e38c625584":"18","6f7bbc4e42ea462b5246e6f51c3f86056bec50601ce2de6067c8c1d26f21c07f":"19","a7b32e72502804bf2946a2a8856139cbbb759c5777e6b3e673db1fdf7e3bd06e":"20"},"data":"YGg2pl2/vdBJFj01O+Hi9yZpocySwMYbU3Ccw7S3ZUrrKu35reK5YAxg0U0z2qFA/IT1U7V0AQH0zwgz1Npq21QGBzw8SkIPkluR7yyBRRhGYLselYQTN1tDg101LPeBMElhLxKjrNExZxLtxq94DSjkk+eSYhnRkdvS94JtRw7BjoP/U33nL9AKZYfL3gqjsksBQNUMrKzxoWQJFAo9UOZko3myqOKjNhFnIHhW5gk5Leetukx2irjFCTz9tVZb6RexNbJIWH+PgmhnIl3/wDFVyaWhbSdFIZEx8trXJyzzuj1xLqO46yZ4ytNHcOhz0neeRWSfEzY//ANjRhzwGquQ1xyacIh6CRq8AWegT6FzvLexpMOqV2wToaFbkCJBZL4gGZFliCtvDWX0U0qVWUwJfkpa2xWYp+NNktMl83XJFvoAbBrDKLeNjYclJ2r2MdgiK0u6kOCAq4a3ABXRbmycfMGW21ltzq+IOBkeUwpywLLR+aywINT3urYk3ngMLS9WzwGwDzF6FIrBUhzlbhCXLX5R8GpwVjmKcX7smngys+PmeRT0dvKlSgo51iZ0whF5GNKINv7BFHEfPCZiXJtKDrW6Nvr5+Cu4BI0ZrrtHi/Wphi270FymoZsVB2Ecy1rptqvF4E6OB2vhyrUPMNteuU72lZGhJNW9HL4BNcYKfrtGLz6WLUAVXCtNfSmCLlNoMhPQsRF7M9ypVfWf+zOq71V7Exry1hbPtrfCzvqXhWcrRQphKWXLZKpUVEE0rGYmuxbRRQfkk787R2gbCo/M/HsSHt6DDlxbrz7oR7B2d0Xp+1SOnlS0RA1LF3ct7aLpKmMWWXP+1+bmYpOR+JV0Fn5glsEJ/Ql6eghMe7ZDM7kcv8//VyBVC7pUP/YzurAI1RuWmKnwCQZw45RiNjypkIKvISB2JcDmum+2isULdVAY3J7FyScaLGOglmaGWpzE/+MbL6CoVDZrCdyqRsDhhW9BsPWQl//XKWOGEDg+llgxuRuLFMVHuYqyOfDQtYTwe6wQ0Fk2PJ9/i/5hRX/79altWINBhgl1AMvsj+6+JCpbv01jO3VV0UT7nKunHjBA1uVIaZR3S4DKEA326pL0t6HBZMEiPBeLjhc2vOOrX4/UcoEET6dhIYk0R58Nae57AIMT49SfwdV7i2k85HZ6IAm7y1INe5rEaRqoYy71D5JBwxUVrStaMDN6vu1cCCzChEvu4W9tm3ariCN7Zc3t3NDss4KfRzPC+ACUpYRKZr16vz9e90nyX31F18i+zBwuKSS4WilLZQypJ8munbAhbNlHpI/uaFUjci51vTR5e5zC5CsePA4rBKv54ztrYYFu1365s4z4ZqYRAfLPeaTMq+im3aze57jsxpriX049VMXgcblbhmnnCVqMGby6pbohnTOMZH4w19gd03zGlDtXDonNvveZUfwHZk/vXvs8WnNRbUOfFgX/4Fxm9WM7yyIsXXOFy+59Jkwcr1/re60QfrGjisX8Ic7sx2Ki/XvnbsRJ46CHtHO+7FVXCanP5zeUNgMYDZyaklp0we5mRVEzCti3lpV5uX38+UhI9lZGzrLH6PbU4VxMhBORUcbQrQkaZc/JaIG5jF+m2dMoyfqzm7kVM3Ah1Y8N8hahJnjMnSUcmtLZtT9u9ODz6HCRrBdKfDY336P+obhl9v0l7eNjGdCgfDGA+Dc8kdlugsEqZ3kT0u7FF0VnVZMD3xZt/HP+eyDBuGxCuzBCwiHq2r6p7nBghlWSGADYZBj8p3z7vR3Nn3aMeFcBlY0ud5jC4KyJtvujY4Y1cdbf6209ScY3HP8J1YD1HxO132Nw4ONJAghE7A6I1QuR8H8cVp55UtVh6VzpUN/rCWOPlB4nbZjJyB7X+52TFMee5kK5prHidiUqzAscjsmn9kfNw3Axinc0zXSTcN/Pmzmdq84b3CbxrVBiPaoqbyfjNN+Fr98wmSsMuXS+hCFpGahDxVkfBhvQ6858F1aSEhDjaP0+p8XMeu7MyB810tNGq+EYx/IGqMvN/4OzgI7OEgm1QaUFtkK92xwI1cY3IHu1VejvKTWl4NBGzf2DlK+SG5DyabkCu5yg5KQ1mSqULYFlwPcx9f6MK6sTYpevnEMIE0l/WVzcxyIQPbUwBh+TNsnGHTsW1775m/UICmGLyUwx9fFvVC22l7fmM7cxknJm9ay3dP4YrImOD1wroQSoxMFv2fMcpvtY8gcACs08"},"preferences":{"data":"XHFpIEPRLRjziGOHhPV+FN/EWsxs74xco1JuUAfNC/6frao+PCn03q/K5Znk9mN9sQ=="},"oneTimePasswords":{"data":"GEy1evbARX4ibdMDLRHCU2WMCian6ATOcGaw4HvRGCKyKt2Gox9ZCGZ1vzaM26PqovwcUJ30xvamvtj61Mp+VZB71YJ25irL3eGiqHplx6V3sf6rCx7EzJBPjykzemuRTI5AgRf7mkVhNz2qPeBtw+Xsm33I4cK70ST7ybh8EKjok5UZOgV86EKSxv97NeEsfhkumSzfRQ7zGkT9vjGfDelPUss2QL9uhjNvm/WvabX7YVHWM1qMgxsCCi+Jzyjl9kNTt0x3G66xUFNk+Mp9GgQcz24S8HRJj0S5b9F4YRhLdUwI8y0CHk4uNPaa6VmWpwLCMEcmdT64uatmCrC/CdLrVp3UasDMGPSqic/yF7R8PR4jrvee3SuIf/NtltRUQU5JT+6wwLYwdR0LEMrOHpXZMg/Hf4V0UQxdNdH4yKOe8H00bbg1DITIL5aILVu3yGFgxlrCBTPW0OL+ql8TQukEHZ4PdnRvYWKzm18x+mmPBi5enizxoO4Us+dYshXzvOoWIJ0VFcstDZxBJSvrcWySsxMtWe37DrGD0TfFGTDj3Gd5t8nPYu4JzBOaESSp9WKtKdw31uh7wynAeuGh61LqHRWS9S5ax1C4atdYHma5Qcjk6QwLtBn+MCDOnJqvAW60YW2V+bGptOz9/nQO+cUASkTQ1uOQ87z5+3CXIsDbNk9T4gEbPqdWS8/SiyHkqarIrVkFMCqncTqzaU5wZ9l2sX29QZqJSt/NYTYPyhTbKQ8gKQOVSqXPONewMdSOsP3+4m2+JPbGUcfj+cWBdQGwoHmLlg65Oa3lWLP0s7yjpzN5Tg/M0h6qhmWT3t/6pD5JbFA6fp8HYzRvo9DC7G1KhRd6uvYUTXkzOKzxRuEzUMciV+dvfY7c5yFEnk4VrM5ssMZ5+CGGgngFG6Ab6epTn6PNmW5HTS9WoEpuwqoNnAPq1Bvv0kSK03EwdrgTW73e5Bw0xTOfSMaIWMZrORwuEf9Eus3znkT0n7pEQhpStP921M4wxT1rO4EGGXHgt/4o0OXoJfF+lgHHl95ZmPJAwxxvwH+sfGlmp6PTycyPsox50GNmkEuwSLwPLEra75YEEVQSvOSM9Wua3ed9J6LkySXd89IjNA432m2qFTXzsqX65/Yi/88CcwDt+mYfSuvkh5aSLbLtNNteXv2BirNq6QRWN4P4CA84czBnZUug6HuDHsIR/Hl0X5Eip6+7tESxitT98sftTry9b5VmxHRih8maSfrGjWCqH7Gkax3i4aQE5ErKwxgGzP7PxrWWmJeJXOlSzWXM/+iGszgHcl0bqorMvWBJGdaSQT4TyOoaeyK1UWZnsJyw4KSZJP1wEGIYAWOs1lnWiT4wrqIR1jdZBRGk1fKQ9qRwLrKzPOMeNvHLBIFkbDdAVYY4ScotmNXqSs9dWLqHfg5SkE1fAg=="},"version":"0.1"}',
+ statistics: 'm+j5iQXSMKvijTYJU5v7iNLF',
+ userDetailsVersion: '0.3',
+ records: {
+ '0bfcbd6662f3771f114295df779a4e4535e8e666842c2336da1b095ca1def657': function () { return {
+ data: 'u49WrgrQIWQsB/ly5AQAmi/RixI2rGkp0JZh9DlBxgTLOhQ35lNVa9ko39zxAXqNC9ZGD/OiQz6kVT7XAA/anrfctPOTIeXEeQrTQTwlHBZ+9c4zq1ZDNP1rm00v8sr/dYpqJmpQzEko5qdaPakxMe+gag6FGdN/FbVPBbn0uVSkpiIZSNpiWEQ0uHjHN0QqfrGTQ6Yl2UeNoe9P019XTDtfaupDZwh2+DL1i+s0UrZqa6JHyXLnsD9Ue1S4muyFtptJjasNPjzSfs+BHhQj8pIpZWEEVhH16Bb3fKlr6crRktEau9uAtEE5bZbPXTDrPi59JdMYmD5CH5ftDxz4nIPuI6Y553s5T6AejfbFIX3QzMG+isJ4SDebElDCQDNBsmavojxjegZ2GG1M/xXQ8Cw6pELlJBYPidfEJaSjb5cmo/eo32OLLiR03PpQrpzqQkzcm2Eh3XrkVx1Udg+JtrC5V5t4H+BxLpk8oTbFhXVDvQ+zdWuq3icrfb1zOd3f6b9GiXFu5tqAq42xTInciZr7pPWth9yeZ3fYI/Fyw+9F2kuowy/MbB4q1TL2VjxT9WfWmIFoLaLRNr/w9E/RsvgTc/LukGb44AjPaVFckVSw+mqpAOqvtZN21kWkJ9rQk0W7CQ9tRYRfrLhWVIu9vwPkjyX2o2t0+ES810GTPNesbbGAsxlo2CC3a1GZLebeF4x+h0v30ShC9UJLhxAMD0PGpGYjc/AOkjGxTPMKLMvyA9sKKZU7PRLQQg2vFGXWIYoK6CHFBJey6Q0nTDY7Nomi+nMlQv5f9BT7YofNW2oib9wQmyS1hwBSCB2Gavh8fd7zPjETCCURfDMfuMlqRFgySiOpl+yYSHLmlBl4S6sIsdU63uyy/4QMQn/SLGh4ASnhI1GRCwODVClachEbt6D1u1JInPQtgBXyNiuKc1s5gZ2WtVB8tPfkSfUIQuuYjK2N9aVaioaWhwSAIX771+EaYMIrVeVq+twakrkFkgL8+YHF0sOoZ8ddQivsWyfsMwDAzHgGk4hMdYzr2Mbb8ee8p9oaZBVqZi8E3EM=',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Wed Sep 30 17:59:10 CEST 2009',
+ currentVersion: '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a',
+ versions: {
+ '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a': {
+ header: '####',
+ data: 'HnjgIcyk9xbqzbZLcIx1BLpcxwQc7hYQ1sHpaqrKVvzx/CFeGGWTmLHoy/dA1wr8/rAUPqvaEFNjZBDfTQtYNWQ9H+Y+YzJ54TmGCQY2h2HYLSCvJWRlucsHKcW1XLIwsxLzBdtZK7AkR1dPRd3s0GQDH1pUcWC7WC0thJM4a2X38lILzxXmoxdqQvawNAeVwscokb2Z4+zQUMLdRt8o9v/CTFEsU1jzrxVSXztrhBzjkUga9TUVcYA7BpOMdFmeevvfRoVmf93BL82wDDWiYIIb6NoA8SjIK6Km/cmovGikoPjUbOErvq0TaKuC6Gl/nUpqnW4kEjR0rVDh+27AuMiJR6MPdqjAYAk7pN8vvfTk4GE6TGxl5IbLbl1yZ/7HHC/CtihstANOSwpdCDpEXLK8',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Wed Sep 30 17:59:10 CEST 2009'
+ }
+ }
+ };}(),
+ '166d907e97005cbb29efd1841757f7d1a57210ddb32605ccb6841f35f72399a6': function () { return {
+ data: 'QxBwxxwjNGkbV5L369GEfAGPghu3xUhmQJi4r0dhbAFscS4SgvfUPuQmX/JvDfWZFBhAHGunrPxHDDHRgx7GVVI/Kv1oMexHKbPuxhRSBRQz2HQlXDAUctW1uPo2xEbDHGr3JaCiqnHltp9XMkmGSP8IYwgizYt+ZwRllKlmDbVkX0gBgM6WzOhP5zekf0E82XauOc2YUW2jZQEKBQ3azi1kKNfTzObGL6NK4awJBlB4m+R8xmKkmybcbDOnnUfo6rXxef6KLyd1Xq8wmmh2oS+I5sbG0CeAdujbhrpJNZMkXFUjKjRu7yCrCU5rUqpKGcYUFtsciFxcklhMwk5uQmjLlKQBXcOM6lmw6OHRwzE0eOMB5iPQF+gRUo5EKdRd9B+lV9QyCJlkTgQlLLQfDSdZ0xAoEe2vzJ0p2Cijg212w5kGf7vEtQrYwb6GAlfeJiYtDKSkXXx+ltpCI8RLOXdg3KZDu7iobQZ43I4MA6QELhGhc+GeRzvHnW9rBaSdxWVgba/EHAsTVq2VSt5u4Upm+WMyAQ89VJ+JMUJu2k++tID9ZzKF4Cfv/DfP+WLGEmZFmfUldl7ot91HFHi9kH5HGgqbkqKUCHTwDyJhQM+2NAed9nPVnV5EKv1YY5ABcVE7M9FGEIVaTlPCQ4Fc2aKD2tyXuhmXlLKK3uBBsSQ3gn7NI/6s1vIDTnWQA6uzUo+IpadwGwcUd3F9TfQ2yckE/FuWq5WNeLV+Y2OeQgLZSf3y0/sqSIhDOhowNMwppZU/fS6Q17iVDhGcmZn+frfNv53rZAOg2zWM8kpLjTOtNCYsToR+2lR3hQuMUw8dJuNs9WHCywj30J2t0FEuLt3091TLD5S8mufN/O7wjloLOH0FtHH7zufyH8YgKm2KNgUHMhopsjnqp3YwXhXgk3OfD55lSaiLO01pLP5kDfNXsmUDyK9SF9gn1pt+xTVJ+ndZiFxzuFvPsASiH6f4Qp6KMoyTxl6w0cIHVZ4e9qHcEWwvTfqBHH2O1KPvijTSmlcZ3gx3HB3zfI9hrY53dJsYv1Wh6mMe1KKT+2ioTlkY0vuR/aEiD/bDJY1yTQ32/TlY5wF4trd3mMeT4yIOPjsMWPLy/H2bF68BOd7QC5EACoik0EGBy13yhg==',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Sun Aug 09 23:43:43 CEST 2009',
+ currentVersion: '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926',
+ versions: {
+ '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926': {
+ header: '####',
+ data: 'InmPOw8JYXqygmHyo1pTce9ig7lBEINjEXHBq3O3JIJxF1+kI1+I7bMwBhPJIu7dwFgrp84YGFzk/rf8i89/55c0an0H5DASo2tyE85RZNA98ZVXDEl7fg0FXvi74248V9vfjqUajSc3z/NJb6ykHLcrVLIDupwr+0UsWXIy3jYrLhpSRUWHKMSnCus44BpqmBkkDCTvHN5YQdjGwGcevC4L0g287vDO8i8rgz0P56JwiEF9yB9jtHMRmHFsG+8RIi0xPAPGJlh7pfCkNqhx/A/aGUjB3K1PVw4z7uDzrbF0YuhElZae6HbDu3ouzELUiOV0YijpuT5Mc6kq/NIvxWenrSwNx00kAGChWScG+SUTOyCPmR7jEUHcxGS8jvaHSPQ7bkr+u8BYgPwVuvHhReQp',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Sun Aug 09 23:43:43 CEST 2009'
+ }
+ }
+ };}(),
+ '25bc43a5f1aa780304bec9cf0cd61502f82243053b5f72a55712525b0b8290e3': function () { return {
+ data: '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',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Thu Aug 13 22:46:33 CEST 2009',
+ currentVersion: 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec',
+ versions: {
+ 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec': {
+ header: '####',
+ data: 'f/VmR3IF/aryj9hlTaXlsE57o/x0jsH2ah+qgc6VsOg1/7xa2qtBQRhOQ8RWr9oYmjnarWqkLVrVZqP63O+0dOTmwWHoSf17dWlSZVxErV1Kmb5ojgFlkbHJX/RkcgPrav72fk/A4yJ7kb1FZjTvGNPMpJCDvSA3VT+xEukGaIig1Zt0KRA4BZasYuge2Kr97yT7mPN0d2EKeM22Ybgl3Vd+Ja+aWkTzkLLo3pRBDxFXP0PJrVHFG3hDpVqLn5/EGZguml95TVGlaqRZfzmho9VHduO/fQpDr5jelWA9ZDNkQhxyA6LlOrZjcidbyEsMYeJqVdVXa4vBnYh+WM0KJIU7XoJhur3DMD6yaGc2wAX8dwM5zyWTaseb47l+OvFkpBgstqBnIBozGqRj3ATG8e0=',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Thu Aug 13 22:46:33 CEST 2009'
+ }
+ }
+ };}(),
+ '2977aa5f99a9f6e5596c1bd7871e82d7328c3716c9ef8ba349ae65f10d97924e': function () { return {
+ data: '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',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Mon Sep 14 10:19:04 CEST 2009',
+ accessDate: 'Wed Sep 30 18:23:38 CEST 2009',
+ currentVersion: '6dd709033cc5be16be0ed897d0a7f8886f88f50cbaf9eedec8638fd7b72fffd0',
+ versions: {
+ '6dd709033cc5be16be0ed897d0a7f8886f88f50cbaf9eedec8638fd7b72fffd0': {
+ header: '####',
+ data: 'hhwId0LMOaldpCUM7uGnhMnjE5hqoMV5DbeA4TsGP81BXevlGklqkoQC3erIiXSatq5eG/dyqDQrzyzkrTl95CwINRWYmXHDhaoH6LftAeSpKHAzfpfRBX83MR9HyT9Ypi8Y1j00L5qEqi9Z+0w3szwPT2KY3ejCsgZAM8NaB/8y3sBbU+fc4sUZtWLbPxocEeS9H7uNBE+NSWjm3Hw5OvfU2PaAR9JcTy8B0HyL3h2g6/QBCEEnf6QiR0L2tfEo3iHrsyVYAdNO+P4nM/vFALCLEPCb/nWstS6tZu/u5q+KERluskP+EKzGgDwuvLwTHjq6n9mXs6umDWmjPmJBefHYQRCYpKMUM+CO+3MFKkZJ2GXExp8ihOVdHPh+zxQlke7rgO2doPJwzLJ9QKH6rnovixYkt02MrbTLNabsmXA7ystuXICcWlSRzds3GlghTdvbjnkgqcGxfzja6kL/ERSx3yq7rKT0cC3O+hWuV6zWd/aYUDnCVbK60gUAphUz/WWCfCMp6LwfRXFn24njkfkPfp9uOKYPMsY8w+crlPP9qBYrVTjX9oyKIC+f',
+ version: '0.3',
+ previousVersion: 'fd57e2d2e48e6ef8db89d8b9ad661d01bd8d49a93f726050f84779f1ce2bab11',
+ previousVersionKey: 'sG96l6ebyht8o5i7Yt3HxAuZe85AJq4ul1cqFmjjzKe058gPKAN0QM0BEoa2xlJxIoXeIrq5A8QsHGPs0iH3OlU77RgBgHUG4TZt1QMyG+Pkow==',
+ creationDate: 'Mon Sep 14 10:19:04 CEST 2009',
+ updateDate: 'Mon Sep 14 10:19:04 CEST 2009',
+ accessDate: 'Wed Sep 30 18:23:38 CEST 2009'
+ },
+ 'fd57e2d2e48e6ef8db89d8b9ad661d01bd8d49a93f726050f84779f1ce2bab11': {
+ header: '####',
+ data: '50+8kvNBZ610YDniT5vM/2VKaFjO46eVWBzgz/kUgU5RmwSHw4PJlupqBRT/VM8UN8NVliS0A7IoSmIP1QWAb8n2KFi2e0V6bYnrso2gPZU4CIOW8Xxh2I8mDci9Qdo9kZSvgB37vcRw+QuYXwm+SjCKqgieGcniacVB37/lcOsGcg3I/o2Vb+ZgXbyARKS2vN8/I/XM89/0t/OUV/4+PUvI4rCHSd+ML/0801t0t9YrD9yXEnIEGl0YzHB5KQebMmhCgLWQKE4NdPN5xnPxtCXRQakGmycUkA6gPzizpBhrRTcObFeQObPD9E/T4UxICLEespPy0FRtipB13Ql35CZbc6YOJ8YbRBXBy9tzZfiP68dabGzPsQoUdhTnudqtSHTvgZgeYP6Y5X7Tl2eaAZGf',
+ version: '0.3',
+ previousVersion: '41e02b4415f5f802c6aedc21cfa873d1a6fd301b351ad064143609280c0be870',
+ previousVersionKey: 'Lhb+2Ikt6oJ7RjzcfBKGcdw58j0p0m1U8vT8fVlPhz2Qgfs49PB+IFDJx/CAYfVqn0XugP6G/C/bt7W+26QIcUywQQMYGA0As7wQlAyntExBvw==',
+ creationDate: 'Sun Jul 19 01:31:30 CEST 2009',
+ updateDate: 'Sun Jul 19 01:31:30 CEST 2009',
+ accessDate: 'Mon Sep 14 10:18:48 CEST 2009'
+ },
+ '41e02b4415f5f802c6aedc21cfa873d1a6fd301b351ad064143609280c0be870': {
+ header: '####',
+ data: '/sQ8oax3ehuArmnZEeX3xiqqDlFMPNgtisChk2A6Jj3jqk+MxC1Y7ioYoY922oyI0lZG23IUHsTvDr8YV2RrIcEMXPBduPl+XcnmGpL65ei3ZeqNSji9Z/i4j7w1JawQSSfnppB9EdE2OQ8x35PnWCIKKDS8pPXLAXnJmnlar5UBhJ1vaTqQY5mi5OCCDra1KTpcFlGQH2RfX0Kl2jwYzFxqUNMyf3FM4hs7cvJcm2yYvvw/c6V4QwRIiANoDjSQjtarhK8dULMJWIXIpaHUkBLBlxpINWkGpGBPyY77CdTOgA4UB5icgZZA5lfxmkHubIpv3QegAf+TKSOUeV9UWmHj64ayHgYjQ4NB7XfSUSrnMshn6q5zY17TlM/b7OEfe2RR7xUonmNgw0ga4OVzYKMT',
+ version: '0.3',
+ previousVersion: '5106520ab71f92eabab279abcd41289831738439fea854d122da13c2d604bdae',
+ previousVersionKey: '4VhpG+IYuvWSUkAP+NhCcFquszJoBeuwBL3A4HkZz6cylGHu9UBjAsn5VWidptcB0jI7A487rHjVmqOdP/K3MlJqVYSNEVzdMjAfkPgZKSGrbw==',
+ creationDate: 'Sat Jul 11 23:23:47 CEST 2009',
+ updateDate: 'Sat Jul 11 23:23:47 CEST 2009',
+ accessDate: 'Sun Jul 19 01:09:01 CEST 2009'
+ },
+ '5106520ab71f92eabab279abcd41289831738439fea854d122da13c2d604bdae': {
+ header: '####',
+ data: 'u/iOk4faLI60d78bNAf1i1/zxImUkdtjS5K+gQqrNRnqquQMJM+FV8qPDt9vVGgKijB/LCgl6Cfvl3Pur/do8V+X7V87fROBjD4XbmMnbG3yBBFgk9snX4upCAkoEL8XrxOY1UyoR0SiLMI/9g10PMRyLmQVCCViwl9RRjcHgI7YKekXPuVWwg9uAUV3pdOamZpyN4POWNAk4QpxVazlK6UoJZ76IAq8UUl0oHbzRNWT6d44LZzWEbsss4SgVf+7+mFMSwKxB1cVm+jgk2vcNs+txAg04EozT2cJGBsiYDqo3GrA+yHTnhdKO8tRBLBsOkmwS60k4H8REZY40xEYF2uYnZbOmBUJPUUOSH44nZ2cD+3C6YyK8GmOS/8ODd/vZ35mCZzoCnHDqqpvogsBv5ks',
+ version: '0.3',
+ previousVersion: '739b67f6c1d52093f5c2153b406df90cd8ebf303ddd0d13d825fc946306114d7',
+ previousVersionKey: 'CNxkOXhTK/SCSZnj+MD4ws83iHGVfl1iBIfkcAhnMeqAkft6IoQQr+r73aZZDRCLDkzGX4kT9iKCGg1qwsrs+EjoeXZTrQH1Iq4J5G3sFLb+jQ==',
+ creationDate: 'Sat Jul 11 23:23:27 CEST 2009',
+ updateDate: 'Sat Jul 11 23:23:27 CEST 2009',
+ accessDate: 'Sat Jul 11 23:23:27 CEST 2009'
+ },
+ '739b67f6c1d52093f5c2153b406df90cd8ebf303ddd0d13d825fc946306114d7': {
+ header: '####',
+ data: 'PPGwtNXTyrZpCY1GKT9/u0pPsSunTuRFhrPfld89swJtAeNgz4VUTXWTT6z0fD9MxnaxsxLhpofDBn2mEYnhQ5ZptSKd7/MYrkVLRyMBQaZ7tPgaWVyFZ0vhJ1et662H5Qj73reiOYuKmU4KIqydFSupgjG0awc0ZV1qwjyEwEWgopwXvrhWoFveGSrG4XO+cbxnb8ek1sRKrUVIQV2zhE6S0QT6PCl01Jr+Zd8kW91EWV/PtZn74rJcH1oBJ34WBzBrU6ARXutBfxoYgwTsOhRxH9Z0StbMSRAsBff55cOYxwuxQQCXsOWXwoK8uE2WHAG18b3DNuTm+jluNkgfUxgWZ6B8gMlFQ4hdgQ0gfWknq4+ZH0xR5TTAOBegel8C/z1sqT+hvdutBMih4uXJLeZO',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Sat Jul 11 23:23:12 CEST 2009'
+ }
+ }
+ };}(),
+ '2eff872ebb19c0f8430518847dafc819c0bf7e0cb714b456d74603c250f2efbf': function () { return {
+ data: 'OjA3UmHDbGw95QFBZ0LMQVUgqwpWy+BM7a4eZ4FY6mb/B+fCl31PadGg6+Xp5E4zk7V4GEwnxl39aCQzmNQOsxWszVZ/7eAIFK+mm0EwmpC26hIrrEZ+8yHW21Oj/K9FBpfPZ42768cWh+K+dLQw0833n5b6UTmrOswJtzQiMyCoZ8cidw==',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Wed Sep 30 17:59:16 CEST 2009',
+ currentVersion: 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc',
+ versions: {
+ 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc': {
+ header: '####',
+ data: '9FchrEXmKOmFxcCcGHhOQRhDf+OWFABlBt+Y7FoQWvmjILdmlZeCNEK8tBrVQDQH+SuJ0s3EHfaW2dQ3TRoe35E9P16lJiGclRj59e5f6tngE0wD4gLyRQnF9TZJTFIM3dYlwjhAewdonyh0uEnAtdZfNaeCF5xVjDKzfcUVyxXIJLa1+wdJde6ycsgTaPvsaJZ0YU+ZfCSRAiL2ACnVcjWjT7hFMQMGnCFQOMJz3OsA6+UWvhvXebdDWqVg4j1h9Y/FDllCYtvIg35ARlaJERioe7+PZiN+jki/XmoEDzd19BkK/AKB2DLC8dPEj9uu7p5r4WAxuA6iRbXDVO8HlkoywstDAKtUj0XmAfHoX2OJkHQjfYyuqabkFCQO0227Pk3vFTFnv6dXecBMLbevAVoL3EKvHpJWICL+mqpIGNJUqgDCGJEB4rob2xBNRLyExgkEmbCKoN9ikFO/JXhDT2JOSR0fmvfcEFor7exicL4HX8zgaokA3oXwZptc2Q7wTtKJ5ipen0E/2uv2rjCgTAK6vFHxgW5Fk3AGG+a2YpDedekRAWNEJdVucimepL8LPEe/GOgf2kGZqb3L',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Wed Sep 30 17:59:16 CEST 2009'
+ }
+ }
+ };}(),
+ '350a8d666e033ec01e203e0b6df730bec53124f9ab25f7942bd9378e4b5c01f6': function () { return {
+ data: '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',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Mon Aug 10 00:39:08 CEST 2009',
+ currentVersion: '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a',
+ versions: {
+ '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a': {
+ header: '####',
+ data: '8TVTh0Tz2AUS6OmJ43Gp1a5ZYHhryqoDcESx/EfyefERs+AWtMg/57XKIEi1GPCA+jllOVmaJ3rnRaEN0VDiT2lST6PReON+IFR7WtZKpPOMit+cF+7WHXM9RbYsJnf00yyzRzF5xKPk/OiP0QwNOnhRrn0UUzJ0akSJS6WLJrIDF/WENBu0szn6I5g4m9v3nUIjJcpsM99BOHS7iQJmakUUQuIp5MPbALEUHmTWLcjmK+BVOctdfE1uPor1GAwgJTQ7epQX6PSPKsyPJEHgf1C5OvCN8/X0IzXdoXdTdyBCh1RaSiI+5Qjp+XHa/RK7oRjVy5aMcpKT8v3bDBlTMa1RmALqJCMDW0lVgjtNrDlQ8mxDOF+gTrDOsLiBv3oHG1H5035E6cU4TRu2xLDqpGKzJ2uPSkVwvc40o9+Qk+Zi6iAx0b+0OLF+Yy1KoXP1ltznmufLBng50lZSueYLrCfEmBfr6e+gc4VZItfGrd5sTT7IilRs7gn5+gL5Xhe5sQ==',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Mon Aug 10 00:39:08 CEST 2009'
+ }
+ }
+ };}(),
+ '42c7a17479baf21938c87af38ccc3ceb3aec21535c644f6c90496f89008f7828': function () { return {
+ data: '5P3FrjzLuEW/pVXRA+eGyKmcmD45HXgsMFS2S5SVnKDSA5mH7FLnCPsR6BGClUNZQlB3iU9vG8IK6iIY1v0m0m9CTM1Ubk3dnDOTSrCi4BTH0vknRvBNZK7vJaChSjH6QgYrRzp85hdNPEIqjZzL+An66dFmWzphjAhCwh33s3QHA/gLlqLaxexPqcTORsyrbSzZKlpRBAF7Hb0gDHKs7YAPUBt+dlW7ZYrxBtNIGYZeh0twjza02AnOhOypsIgJrchYXzJ+wXhU7PPPPwcRKrUjPPlCzG/0+l7E6DREf72yUzIEV6IVyM3Bo9Aii10gRpxeU7XwuONfQExBjxJ3QsK1+IK8k67WzAYYUO5gu+jV3M4NivCpoYK18DrU88teIRgoGry1y/x3gzrHKZOuu8w31/UrcGw1e7lliYxYbEg3eje/znRYKCjFSVZ4ZHHKqXshGPLkip+dAXiKmmdqmn8hLQPrbxTGAPTrVXdM/WyU1NMYtJJOzsEDNTKMxIfBXnb1fRVjOPDtEpuU4Okf/FiQ3fOWkjFWh7IiyFoeKIVG58t7juvwiwERaw4gfJNWtdMAiTvh/o1o6qRAtnmH90+OWc/V0no/fr2xN/NWSBQqv3e6/dj56V8b6wmvu6O7geXF9+n46LfzMDlHoBqS/8tGy7qDnZo29TaGbPoXUkvteX7689FdOYFd66WmSAuoNddvrqogWBCMJSwiuaFpv2JAzFtWNmQAk/nN81TFjnTeiK1rl0drxwPR94Z8MiiiogzMUIkbmkGciUtMfWpUgDNPryx9gXRCCZQZXLh6EfspgahFykUXG6BwviD7jRa/1TFg4xRp9VWuul2djQRUMEQnZQ4q7hu8ZBpBvIcgvC4CxqOfcQrYMAD180UbdxQ2xJEPA3DCDQpZNWzLgJ0m6FrOx87x4/1Jyd0LaaS52SxtQCwqnusNut4dmPFKHTiPGXSuDADrlxeL/enOAXt+j7fjE5SXy4bVIGqeDv2mT8yPUam+b8tb5SNr+CD0HsUB2hsunUxjXVwcJ8Z0JBrwvvVtQAu17rEv3EcfuxFLYB/HwqUdjeCfu14/RvblCxBaX6+lAeJ4rCA8dJWbl/ckr6GkbQmGnLno8uxPrq4j7E7Ia+itowZSeJ/eLlyV+owhbILoVjwNeTqi6pkiH4ejM/+e2n4r9wB7duOiFPKnpEt/SqF1YWUZfzLoDikdzoGIERePNKzlSEa1m0IvXDxJtADiXcEzGrRXS6mnbIt+yG0xX4EsCmDt',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Thu Aug 13 23:06:32 CEST 2009',
+ currentVersion: '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28',
+ versions: {
+ '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28': {
+ header: '####',
+ data: 'cMMqKK7G+t292j0PUNh4gtooVZqEkAoY9B/vKa6FEJWXCp2IfLOSH9sU5xKnlX10NGYV4xZwgidPI8USmCM2WUIcv+ffm+6OYmEQKC1TdptcyAh32+dF2VS01V1Hb/HmtQiHT7nh1IUaV6qn34rTICtLKIfei+AoGEjQm8kwKNzNxeX5SnQfafKCmKHH8ag6SxKPggv+ucO/ECz++n30nGpjwG/tWCyMd291HfAQkseloFTPedEgEmfRfGrNmsq2iwtwKLddZJ4xvY56H8Ppxo483KZj85AuE/g8vS5Qc961YtFjA9xbE/BSchXYobLH9DAoKYtiREyfNCqHYh1cxhqE0Tk1f0+9IvGcsB9d6fahhTfQERnUAd+f+C+hsx7rMfmub2z1TTjt1CnvCEI=',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Thu Aug 13 23:06:32 CEST 2009'
+ }
+ }
+ };}(),
+ '5931d708fcdd39af284d4809135393c81210a10b0e9d56b49b2f2a3b8adc9394': function () { return {
+ data: 'Yr0K3VCx9pWKSjRuk0JTO8kyYKqqYBb2xz0nP4h/WSx3is3bSy/jb5dWJhI2WKNdpK42eP0jfboITWX/4Wdg7HZoLv/usE8ld3MGKfxxzUNZDIkW25y7Chq08wFxvv4O0fHM6QyFmHQx2KRQ67e++pm3Fuc5CBl4Cgnqe9GPtMnAVJdaei/eDK2icOJ6EldBb0NGIaX2TWE84efJPVNIZjQ2OXZmLse0baim7TtS4HXljZSBNHob2v1KJ/sKh8xvw6dY8zQBAalo17Vxhb7Gd9/Vd2A03GNixS7WZAYP+ybd3lZFMMBuNXTG5bVRaMZv/hnjw+CLak+tOyNRG+ara7GivBAXjgfd0oN9qBvvM7aSm3iFV1xQkxBXhv0/GceSZNE/uPdJkUCQutikv0kpsDxWBHvPI85+8mBmzgF+aT0aKRTTnQfYSBLvPspopEv7PxhwIdjDBJPrfkAMUFuTSnZ+hriDMHoYM62Kh5anX3jYXIPmrRRuH1NN39FihR4uBNacZPEiFKmFQu2js6ruCNzaLkUFQIhu2hzdnQt1kOIG2nngruI7SEt/b3YwHIh41udtve7qKWrGaO8IjIaR8jgCtxvavH6NaRWIr6Vx4cgvqiyMAZUewzsCgY49BOWWYBR1FwcXzk0itWH0ZzGc8htlbVJ50I58Iu6Nfv2IGQvHY87arTAbx+sUNxou6Ht03KkqaONFEr1/VkAaxTNsTcuWFArAKaC25oY1EkriGUC9frwvJyHIRBSHyIzpbbtO2/mnBG7gJZUxAtEDZ3Bb3AqP6v/3k3N03pP0Y5HL199iLeKTz3pK7sgohrr8IVM1XvcsaVyTBZ3di1E4UZVbyxbrMIyR/+NMu1ZqlwGI0wjq/emTvtDEI2/l4WMxMIfQLCwdSjDYi4/HVZJvcyGNugS2gUf9hwavz+BUnV1iSI1JuxQihby5LY4Em4Hr1st7hqElfZLgq64iCVvBSzOidM1SE3lm2l2/Xx0SvLKmVxt32vO7brNSrBB1fQyq/BSOwlp6TbhnPKbh8aF+MIjexwPLU0wfs8rj+5X9j5djBKVtlCqDFtlvng043oC83lvOdbyAeppNXcloRWH8gB0+orKD0VCMMt3NTCJ6xlrDeIWqKjn67ucXub1LB35B4mJDbUT4zYWi+YWAp7QdFbZbWJUa04BzZOY9ggtbdrznLzQOXnek1gqEwrNSytvVPaWoqz25KuMpb7niKwQNe4d20f9GUMyjFcwjwlfyfwv8B8FujQ/3bCi+v4R01UirsVxmRd5ESOYi9C945ErgQZX41x18n7a4Es35Bnl743w4ZdVQw8/BpwRZ0pKe0275eDw5CJv4gFdsnTVvAhP1SqG53sREsIVE2STr0/B9cANQMjFI270JKKVG5ckYTueak3QlcqW4DXQE0wkcU59wODSBiiItFDKtZAk1pKll0s2jnuWlW/WP4yWddry6uMtTnj+j3uLNcV9O0Vp2+v9rRAEdHCymEPkEbR01Nz7FE6xRXnxnfn2xQP0N5KVZvzXMf3evbN0bEGnV9kH/gIHkiMr1CgYJeQDGcxZgKtlxqD75OV7XUSIAd9b3+j2aDmjf7a3cZrvGjkSHNBVTyPSwsIw8/09Es295fGLKRu5ZfwgZD8xjUfErluT3QAkx242RkhayNPn3yRNAGzmBZ3t70N8dgVG096lZ790eDDT1fUdusaIxAGlPebT1zZWS',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Fri Jul 10 23:26:41 CEST 2009',
+ accessDate: 'Wed Sep 30 17:58:49 CEST 2009',
+ currentVersion: 'e26bf4c9ae24bc10a265f594b0d75426fc1664ff8143c52d98592cf1c68baf5f',
+ versions: {
+ '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130': {
+ header: '####',
+ data: 'Q3Z7AjwPFzFuRm7BJSRnd8Y1/tEqXiLdCxG2JCurixClv8uvQPQkCECmE7mn0OqMRzlMStD9UojsRK+cxsaNbQn3OstaOgm1OuZe1WLg/oSM/UfcQqfBRmCtHwKX2zjRTSzCjNamwV4n/l1/92/JOBeydVWe9pNe/WvjjfNYRRhTWViNnOaOAipfLR3uSbehgUlQ1NX1y4nrC/yEDge+73BtJNJhb9FOkKGG9ySf7vax0fEo6jVVfyV8KKFmXLL+ea0D7CoiyR91eeTKZ3bGzU1MD3KGXfPorpCoaoRK7OKrHGHGfAmNK2yAGhJ7rFnTbkna02tMSbdwHaEXVyLHejub5L4LUaqTSnAGdmSpiVEpkNbD+K2mLW8loZcMUetxFqDh5ta7/IEnPMicmpSOAVlYTW2ytpLppvU6fFKAtGdJ71GaLwQzgfKE8ZJOueJ5WBx990K0MjSXZcsqEzFzGjiyXpIBMYwFDuRwTyoxowgtlL4W8DTtrxW/XA2j1esrMXS3Bf2g6ujdSPzlve/8nimW18OkRAgPuL4seEySvs6GKgF4CyR/TsIsche2kWJ7XM3eO7Bh/Wxu6WmNBjUUVbjvOTF8pPyDkAfEIhXhTliHf6lDkW7zQs36BrGEPfOC9MKjSlX7v6jgwX9gy1ToSiht5OB77G5luThsGQhEBkydw1QGZvcKkblrzaGFznM10RXbuVyfw9HnMQQO9h3aBIgq/yynJAc+uBUtfPsGIfXbotTZ+bN/y9mNl1gng/gyy0732IS46Qikov/7KRpOv5RrosTCYaU+WrAn1ehbMzd2xFlNcKRpQSGQkVundl3A2BqYtRElJCd32FUPSfxo6gZZosI8s0+GBiRjIVihPpglE5uXk5vjbsCEpahm3XEMEpqGdyXct/blQqEsa5o2NrvIlNVCbsDIKYZ/S31b1BjVO/auWGILqzbG8RA0IGZEJhyRTx60dJEHZSayGlunkgU=',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Fri Jul 10 23:24:14 CEST 2009'
+ },
+ 'e26bf4c9ae24bc10a265f594b0d75426fc1664ff8143c52d98592cf1c68baf5f': {
+ header: '####',
+ data: 'ITaQ5yMCeVUO2140QTcV0Fy8ucHd3zRohhgU0F9AdvWxwVm3yjZrwjZWmnOS82bZ3y/ZSrz+HGhuxuk7+yYOXR/Gp8I45UTrxFzeqJNJdWurpH6SbBGtd2CH7wHM4Bi7fUBGR9B/JmUbrTO7iT71N5MqZ2nRxr2vvCBXMcOPlFg7SSMDw6eFqDAAn6iMyaQSJvntLvM+WmOXB0S3OgUdhudUihK+Eb5tHPAy2hZKpqjavjxdGUiBEJoegUwBiv6SbCjTCDZWNXeFviw9wBJoIhSUegokGr0lNGQqMq1BpNHQ58m+VvIF2+qhwGq3UGd6qfyb75DwXQus+XezIQNOPFwPYW5uARY91KBgyIzB3Qj7ATpDVqPiW8lMs3wHXg7h6em0/FEFWonzVnoAx2HWfU278op1XQTgSTLn2DxFfM0vFeHRfb7tSwSNG9RNb2hi/cKaz5GJEQ83MO9MwGznSFHwGfn5fFW6ZZLf2cn0l1Y4VO2JjGDwy2HD0z+K7LdH+lefW/CyMmOKERnltHnMIDpEOB+jwhBj81wbU8bO9C8vc47myNtXu5hROIB7SDcV29Ufg4kXU48gXlaPuyiS4TYiM3kjC/F+6+iWkJbyFtKirRibGBIKvitkBIYkSJeD81b9IN3Y032bpZkS4uT1oELFxi1ZPWeqayEYSV6ZezqprT+t1PLvtLokKkVerbGhC0FXKkTQg27YHUNOZ3qJCXeSFEXEIWKRrHAlFvavvdIFZDUrly3nRW2H+hEbSVlD9UC6nzfgJbjh0AMS3qSgZrbf/asya3QqjM30r1gF+yn7yceyY2rEdVZnNc0x2siie4rXCa6CbBuf/OA560g0O24H51dSsrxVcgIzwvFMXWZlTuHzU9tKjGqO9sLITGy2Ap1FiLRJ+58PXtBYSixB/ADrEJFQLzbOFjALRqo6CtVzo+FUVEh744+dNPpsVLQ2dERKbrdSUxfedCyanpuW1js=',
+ version: '0.3',
+ previousVersion: '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130',
+ previousVersionKey: 'PD0gxj542sNjh49y13zXStCGpXNRRLeJpGJIal1KoFm7HlR/BbXNo8mJPFvGT7Ye2u/FQG2L7OH5RFD8QSZrDkyG2kthr1vTosT3TkDerCLeyQ==',
+ creationDate: 'Fri Jul 10 23:26:41 CEST 2009',
+ updateDate: 'Fri Jul 10 23:26:41 CEST 2009',
+ accessDate: 'Wed Sep 30 17:58:49 CEST 2009'
+ }
+ }
+ };}(),
+ '5ea084cfa5ce8198528f466e160862b4f17d0a4f63d3af45518c96413d16fe69': function () { return {
+ data: '47feWxZIAZlVAXvXRvAZkVgOzfklaI/tJVT/5/TXfM38kA3UIkm2L4kpfybLlJolAL+ia+3NbeDI2qqftV8nMU9VSQONuu0UGybzCYNBRm7jK+GrI4dLQs4j/slm9oDPSlNxH4DuM5Td8pae6UUdZN9nPFF3eOQTm8sqv05plhw7bElInA==',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Wed Sep 30 17:59:27 CEST 2009',
+ currentVersion: '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7',
+ versions: {
+ '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7': {
+ header: '####',
+ data: 'TJGyQDdjUyqLTS3hlbfYNbwaQ1/LvuAtNwE/8ccsxWKK07eHHshnFBN2j3D01X9nGgWKHnC3C5UZ/RIbJmmqx+Dp4xYSF0Qbrxp4WMtx6BUib0zwXOiopeZ+XaVyvcaz3OASav+Ayp1VEVoXiM70caQ125Ljmp17EYCWUrgk4gSKIy92d33Ia9GBT03x+uuVZ69y4sctTK6UsEEtrKpU3s6XzvQO/xZKtR5c1RglgRjjy+9DlFgt0+naBlpYkofS50lYsn5TjuAw+2+sc6wA3e7euzWOCHBmQjvnP3gx9nxgv34mxyuyj6ej4gSKyayee7tAKM98//2+MVJlQszfD0DAr+EdwT7EtJsjEz7jTAXmGAWSEh7yWkcWcaq2nuJhHDzocidXTuXX273ki7WxTXE2X0pZB97133iY1GKGwY1Wm+xjN+1Kkxt/UElkp9mk997BdT6ZTb8G5iLawtp4XWkRcNExFP2x66YHEhl2vzkxvwXIre/mBILJzfj29iXks59rmhxglo49J48roMZ8vMV2mMqGUFQjbchT59btyBHJSFiNpO7eqTExGdgUlE9/UIEBXSPLw1He5uANApPnuf4dPOPDJb0loYTCI+n7iMYdVJto/0s/wE1FsHQC5QfHMBlXncyIoq9PH9+aje28HRQFJlCtqs3cNr4sVbcg8h6UKi+5Wn9PD6xyYmOKeMdLKhrC65ugYMTAK/OaJnnEioWFklO1OOzSeY+4naKq8v4J89Catw7/t91+jmZeakudvQ37PXpFkbgyetL4m7rbBPb24noT6tyKcxX2xlPZwDavsRVdWKJsBXBewqsTpshIjuAE5qUPHNBfqAPzhNc1jvPjgTMYyiAo5ibVJe4C9N0N1AbR1Zqsy+ifwbSTB/9SHVSWEPjDmV+XdolPCWSifSGDhUdq7kk+nJ4Nt4dD+OcfGZlSPNH/976KttkrvezGrz0il5ssd6f+DVJU7QAwWsNax/lODSaRytwzg+5RxfO0K/tP3VQpi84RYwiJZ3T/hZqD6+9fcLJ2w3avPFyzJsGtwE5FrFOXbBHh0jHs59cBkuAfD0DNYbKB6e3M4byde8kM3MH7rEop2fDAdPclP/yClV51PMoNcMtduTc+xv7Ywf+tvBbfXs4k+UAc5sE++Ed3d1fooDwSSIB5xmHQZhlbcwmOlObnrOk=',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Wed Sep 30 17:59:27 CEST 2009'
+ }
+ }
+ };}(),
+ '63e20b19028b7dd1465cdeeed60ca75b5f5508cd01601937ae8b0d1f981057fc': function () { return {
+ data: 'lhtfrtBUKfNoG3TCgqmbvvdfpFUUGIk3NvD197Rqb0kxJWllLFbCvOJxQfplhuIhIEciS8fIdFDPnhXJxCT6QwMf3VxKc5HM7EpN0Pm3Kmui2lKPsBpduSu1GVy5N8Q3/FE41IZ8Jz+Ht0+z9wZxjSg4ptBAlh1HHiJEsDTN5gixN0J2/g==',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Thu Aug 13 23:06:22 CEST 2009',
+ currentVersion: '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3',
+ versions: {
+ '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3': {
+ header: '####',
+ data: 'e5Tfxy8NhcOTKqnnyhaONWkAYgCwgEh7DMlhOpZHwIFIKp+NUAvD52nNwkpJk1jKyoU5M69MsIGpN/HWFa+Gz/pybmR1iTLUxLE5AtB+Cu6LgiPunH4OrLIl9wbWKiQEs8XGG1Qr3Q/JamLPHitPJi7R4vs9mzoaAGoM2+Q8FSEw99vEwLb1QwhjvtkaYMsOemRCRTLWkZvLgzp94D0QVMqZfpDBhoK/j9lFYVT00EuUEQI3eP0=',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Thu Aug 13 23:06:22 CEST 2009'
+ }
+ }
+ };}(),
+ '7cda06249cfb102884a133952770b85d5442f8049db132d66f761deb765156bf': function () { return {
+ data: 'Q79Uv28nlmk8O5i46/0qkpbJangQTW+U8zhkme5OsgEYpFyc0dtb3YR4CooaH2f55QVSVdny4kzcBm0/JQyrmcItgEIXpbaFeZ7U/ZIZUYAZMvK10JPw0b1EVDfOuychdeOEf4GHbV9sU599v/yiobKTo5FkJYnX7bVOtYuvM0ASBf690GkszmGzHRsdD28QYNUaWLbdufy1X1ovckyDupPGmSz/Sl7SJrJLU/K4+QqKDpg3G9DJbNR+UnAIDWrl1Bt7KJzeHHdCiQ2hw290iHkncnc9h4HsxSEYXavHaSfbKviyV9arPQxRP5B4fPAqO66XwHGoCMzA/SDNfkutXxSInY2iUMfHm7B3k/6zjH79mYvwIP71YY3vGoCrZRTKE4FoKzpDhxNLUn2XYUXFNDKzwSycGSeROWnyE2njcLbMnHhqd/aneNIsDSPCAr2b4GdNdpUPyUp5idfnJ+WyX/F5v/ijrt2XHaK5Jhla7kfGyO1GcWf0e+b+3g5CUXhUgyZ7zz0v2TPG1wCtqwhj44/Q4LORD4zeatSED8nLJkjj+0x7sD6aXvDSKZIphe1/kgpWzeDlUrPJZoM6MxNjvj5OWLdwEDP/h67T7FAeHsVJyEx93GNTsWLjsNAnQEOoTs9r+ru1m17EvtGl+oWq3+qRqpg97HG5+QK0jnz77evslTpotnoSKULq7yXZBycmzmzc6TFuTVrD8FYq2E7hzZ5fQO+D1J+7MB+abPuoR3uKZDdJo+7o1nIvT0fOj5fOhZeDqLokvkhERwdivLR3EKjqnvzHT/bym6psXEA/5ktJASfowR/vyOAhVdXtzMyqakdcFiIQVYmcpE2KUpHybZtCa/52wHU0LyE9xjxIZ0M/XQzbASoVfpqbrQCW/fLI7rKLL/TdlofkxeWDHbt3dPPPNw4opjg+56pPY9hHOk2apE7bWGxcqrg/g+CwCy/7wdhahIHIjyS4rI2kqQ9IFTZse5qrVMeKHpfEQydm7tg5fX18Geh9coGpzGqoKF5VOyEk0DNk1fLvb1p1rItxw46qfK1unjAIB6ftIRHDgvDG2h5uuHnviQjHVg89Yp/+C/cCFSCfIBl78k4QzbHiPtz0x++1HujcMLqYP1+yLtOP5orV8yu8lBspaK0XVJRbob7JvR6wkg2Z4JIW0cGEyUKCOA==',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Sun Aug 09 23:42:55 CEST 2009',
+ currentVersion: '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b',
+ versions: {
+ '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b': {
+ header: '####',
+ data: '84khhUlnVlkWRw4txUcWD5WAGoOmHVY+HxNSlssYiGWOJErHmz3ASdkRCWq4epGjOOxC1sEUezDOOTyDSkCFs3HApOl5k80WLXSCXcjcXPoCiQSX6czufZUfR/OGCmYgeThAbKjnN//GauOEOCdB0AvXYMv1tnK9xTXoDRmOS9PxN6eUPDQdxJ9mKsFBBRRu+LEhANE7jjhu7IqMRmMxt662uo/52rt85GGChYk6qprzbmf1dRViZ4mIccXD6RpYjHsqxS02V9pC5l8u4i08DWRTbghu8fm3FRTgvr/xOZTRFZrGL57Vxps2/D4klKQ8io63uAjxSC//yeU7LHCXm84f9Uh99q+wYNwVcCQ6Fyrz91K9aa8hwHgXq5WJZa50vduwKpeLNZchEbGqLCS9eVT6',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Sun Aug 09 23:42:55 CEST 2009'
+ }
+ }
+ };}(),
+ '91dee4945d6660e7c0db77b72fd2eed3372a46545da1c1e5600a80efd554977d': function () { return {
+ data: 'UDFAyZ9PIzzkr7QKVKzTjavG1a9UqBJXAf+tepc+mtrHQLgTnuce3dz2XQlGMV7R3oCbaRbkUaUQ231KHSPOzScjASVq3YPPfLzoqDIj5YBHKypkMCfVYtx25Hpw6WdFfZfKY9HZEC872LDS/ENXjry090ymmgJ+TP573oPRhenZQ0V2KHSsdUR7M4aEOziIHtSCKFemQfI/7worAVNnw3hg8cDwkDnR3VYtLGrSAbuQszM7pTi3kKCVgBqy2VI4vmDba1W5f/y1bHUQuM1x14wDrgXwoui9voxxtAxD0RENHGcCulX6wpFretwSFpt3G6QaaYvFvqY0UAG8mXCHsDEVC8jsI+RRe7qWSOoEz13EeIhnTevf7+nHkVRHyd1nVHFeawS4uW0hKPGBOBxZw1MSWPpkGmED5Ni7DgCDpYNVGm/8s5IA1giXtIjjYYHFb3+AmTCDSAlQ8q9Yi0YPcJlfQo/HJkSytC60iCWdYbb6Hck/NPU1R0MaV500u3MM7I1iYt35kJoNHHMVTbvfLGOTNPfClDLxA+3zO0TO+N0R+n7nZqNEdz5NzMovPzjRRZejSNyPxAYMLA8VbGGeJ7jq0yAB/Cses3jQ9VZ1HSb4Ez0AHvm1/IVGjCL3sLKATmGCj1JEL5GgGHd184xBiS+3JJSgGWJdSzMV+ig7360jP93In+SqTFrQOQGxhTcSplflr5Pt4W9bH0AkGmbZt6lUNwpfql/ARI3KzcJ/IGFenCMr3xTddH3O3xg7OohuD0kIbfNJE3KOzUkBFs2Xpr3Gon0jCgC7JwD5dA3Wy9GwukkXGLjCvGUCpNQxUSTsEIhsJGd3yvgwVgNRaoyupoYp0aTiBoyVll4/2El9/zyOM+0Rrsy3NwUOV74xuTrclXna2PvSQTssMnd4MglJXYPpkSJRFrWxiErAsRqEK7AxTi+pu59NaubingmoJivpJIJyBgqPDSUcPaztBGZ9DQBhV9ZtO122p4k63+okCOzz2vhvSF9Q7K6D2GXBb+S0w3K6zVfHMY9JWkH0b2uHMUVgWUcEYWYNe7iQtMcTBIsUuwXvxqPbTuMCeME5k8LKyXy+N974JOTXS/QURaa6hxZu8NbuvWZvMfxTSb6cN1Nf/f/5KFEikl5Heta9TPYm1BTIQ30QkOY7LReF+xvy8JtSoBncxryH6A4I5Sq7lkCTSv8lsimETIZnGWaAaZB4hRatJCtET4bD1JJ4j3NGTePfLZSmhrd/tDGP4d2N90eHFEgCwVyK622/KN17M3sngnDxAMNYljbsAAmfxJvvIXs5OUTgQOn+BI50UwGpIGabdZqJKCfczS5y2A50FWrDCzD22dCObIAc+Z3M+LShI6CNsmWglrHht/CgJnSfqtGmPcZFDjaafwiyD6vgkEcbqScSGfRZcmoS3u1iJp5738PaOlbQRgAV0xf9BRVN4gUZ+V8+XxV7tZ1Qd6ZZ1Wqnrfw6KmdD4RgVud/msF2pJdNWVLxBv0iDH3jBJDTYaGuRXroog+KK00XMLXI/er3oSONm4mC3gCcVj+CRiJg8gq+XC32d4A/ahSu2hbTe6oBOh44SR+A0B1gIt0MoHwnFW1ApvfeXfB6Kq27zEJRAryMypiCGicWWv5/ezdi2JXLWdCVIrPJM4+3AoqpTNqaf5oPolO406aTiw371AYRYuHCj+YSS7W46hCg84QTsqlIHpcN/XuhDrbGDGMk/6GOQrHw204nllpYBto/79eCZbFFhGB9kmk+g/fhXroc7+3r+Qnz8twBRQaZBueM2n7u3l12aRwu5Rx38BOokMHz1i0MDtkYZk6O4NqTCIxhhdLMXWUP/NDzVUJYnFblvh6IAn7JsFuHLvRvQ2rgI2g67E2Tvp9MBgQg10Rgfm75O0cheCK28aLkXxcuJjyNg8rbwthYIWiP8iGDzmPPvarHsC5Zhu6CHoptX1WXhuqB5aKnK8ki0VzEAXjxrbQnYGAuQs+QrJ+Lx5tFzos4MCgzIcvJUqZO3gZS1ec9LN4qABLoa9JqKXjuGqrgrSOfIDy3bhoha8exiF0ZnuWivAZjH1ksZCMwIuEm9cIceeYFbLXi8ZCilMvk1tSu8/rtGEzBUBUQS7J+mqz7+tSqJYe5MHUG6DzlxYwSyijvVlXN2VohE2xOwJ2ktvF6yj81qAc5eO0xEW4pgZFeq1rk5Q1h+laebR7ckNREAS6Vw4cIpH+rNaLsGzP3Fsu1gvaCPNf5788G7TV8h3IxUSvvkZQ4E1EYSBxXuTy1uuxXIpSl58qE4dWGOwByGF218dSSkwrpm06oKb/7UlqYFDNakHrJLb2SZqbEq9LZM3CYLb1Bq5BaPBUnpiuQQmrmVK/dOcAMRIBZv7NpR6pq+qPrOVe7UI5KHycbI4HQZfGDgemAouu/n02EzuDVezErlXHhPuvEwIZ3KZFf5rQLn5+p3qyqEPE9MYJC1w2fjvxC0ExT/7THWbKaF7xpGXlAuoiYVvUb6QgrlYmmpflZiwmtQLI0m5GllHThplaarLmeyVSPbix8kypI/F9NnwnuffMrK6psa7m+3usVgr68brTmfzabmOykSzzGCO+5Dekuj0s3KHIdUyHsenaadSDvwQdo16KWuqDl73wo5K04dpkoQMfcyaLm6AfZLHP9PSUa7it2jF5TLlr/KmSegpXvJSwSPvstPANx9upUuQcM6DQGRVUsVEytEnfdSM0YkVNRvojlJOEyn41mtz6hd3oTbVJMqW3i4uP9SjT1UX8ANn+VL6H2bBOovCS3cfr2ma0q2by2Km5NOhdpRbDy8AK1EYbIix+LnOnQ1yutVfPzl14PxA9FUQGpQ4QB1KkwtoVl2Y545PwXC3IVgfMYjaV6YqZ+Dn/uxl/CS4tltoXq/XM1+gC3PA2RK9bfHtsoTRI874nh/EdIoO9G2YlpkfKhmq0j2ebfxpyGRU63LWd/d+8IIIJ9RTLxSKdPq3CBASFpfGMpvOF7FQdvm4aKCM0/rE9XjXXxJONdrSAOaXwz3E5MF5uykG5Nqx3UVu8dzlnNAkpX1XL2Ic/vcNVZowqOKUDOQ0jk16gc89PJdg0WNj7nAYXrEMLf5yf+NLEqAwBFbuIl+FgXpHiLhoASMpq3ZUDkXPiimbwXuczclsxbl9ew4LNQc7Kj5ZWrLfRWZ0ywa51FeWUs9DK6z0oLaUX3tAwpv6gY7/w1p1f+4BWu0MugKVTovOIw2xdlVvknrHfankqrD03fJRf5lyQ7qFnerOLFqI9W32sSsZiHyVb8cUIJSzlz1oiiK6yW4BtBg3Otu9IiBgmBQFdVv9SlaMFYns18nRyk+OnM0+OFLG8OPKpbEmcCb+cum/EBD8Yj25/6LrbVYDiFhXPhZcJA8tAP305uuxOVIpE7xCheHPnpkOatZKLdOS03aLpCYCSEJkEvjx/kw5cNnWkKapKOopwI6Ggelo2t34/X474nlt9NNKQ76W+pJG/x783lsDO1a+qag3QkRzTBNmMCogLLNIWUASqGOqBqXA9zSccc/4fWAg+hM+zDGw0vqiEUrEu8zRWX/yupG1GoOs58ic1S/vUvACH6hJD29022IdWYEDxe4ns2nHg8efIjmwf0ibe/b5pQw+m2gtjLIjtaNtgGm1qczJcJnCrpsMPT7VycQEvXMJ7+Jxbjmky6ry0q88F/gtmvpEmI776TJsbho/hnEWLDXdtlC9rKNP+oRAlBVEKpRyOUuaxG11nmEGcL2FyWQ5RK7AMTpZ33rMjP4tArLh7U+ILAN0ArrBqi0uTb6yVTkg/avtrtGhVXvPToiFo7KxqSqZGS3wdTu8fiOORYNXvCAIzJh2OLkQi67/auxuqp6eB2PZaI872PzGhzzgO3t8pDzpdxseBW1+lVuGLR6PciseF+NgHlRFODokEs2cv99nwXaGKHTQ/iGYYpa/EK/hgmC3TC1Tov8OVnlJCPqTG8WrE/ZftJAkEgfmL4TWviC5QJWDoWj36pO7E2uClcq3LolbT2y7katK88iCtvYN2QHCb9E4tasi12PzqcT+dqYbCy/Be47kbWSJTWZ6A2pXPhLGOiVUVj1Y9k5WGkuLU1AsnuyOyA1mRQTTAMBCOlmI1j0Tl1cNBPkNidghJfzUR2G0JoYDFm0zOheCK6Cnxze7ryRHLvLEHJ7UcNogDf8y802I0QkWrCIxa2uCvA4mqRJ+BrdiVWBN78XmlhSnSAY9MMZcXVXZrd5F1VR9tAkPwyY4KA/KJC/xZ5IDzuvYRxpBI14IFq4iVKGo6SGLDypjXM7lw+Q8A0lygvExV9oygbtkkwMEvNh9oIzV52tvhfU+fwLdjo5Ckx+deEUji6Hju/f5jMz0CxrP4KOBtCJqMfLMAu0yqkV+2Mt9zEYwQvK96ZEW2u+hKet3pE0N/EmN6UuT3KEBd2Eb37woCC/tveR374SUyMiNFKa507pCxXCgLr22xvToJyjzLc93J5CuV38t85hdVWQWyXibkPwId2KglQygZ6NvkCAn/ruRsMlewOpWNxlfXCKtuJsYLHESU3IKhVUUhwYCMuzBod7aOrUV1TIN+MgOS4LYgOPQXJb76thw/RGMX1MhPw95fap7dD8ftFCjOvWJeRh01vMoZ84xDpEJPEXslF3+80gulnxKyHq6szay9MkSJy32DYG1tpqIvWjyQjRSTxrLcXwUSlj3LGjBfckqx2s0G5SQYQ1+i/EClsRQcHm324hJrBx2QNGvtDaz+qzOFsmPWQL/JKcQTRkEJ5a7vkMkvyrBzme/DJRbTGio5E+Vbn1ek43giJ+ISs2/fd39g2xYJx/UBbsfnRPGCRBJTZOUWFh8OlvnK0HRrrhqmLZK3Wb6U0t9Fq67BAJFoydCM8MeAUqCTEuUPWtTroXNHtyKbn5vg==',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sat Sep 26 22:06:53 CEST 2009',
+ accessDate: 'Wed Sep 30 17:59:38 CEST 2009',
+ currentVersion: '4b78e26a7c5ba770c11ca1f799f47112100c20565802ecdb8b0d736c1fee31af',
+ versions: {
+ '44aea76475425dbda56abc538b83cd270d00d8fdee6ac0575019bfcf4c719a5c': {
+ header: '####',
+ data: '9ZWZoxsnhlLjlSulSykBQr+WpToHUzdQ5Q3tcB/l9SePIhgQuHFP4PkA6dZGtLKazPj7EkJ0Slu3Y9TclBjggZVaA0hPpbxPm20hjS2RgFCboIWWOp8ib+xjy796TKGVGMz1RG5di8YUuSH2cc+YoWy9KI8+jJjiT28qT84fdazGag6ZamzQErDsPzMdCvxwF7W1Hd3QEA7AEU3dxvKC1LFuW4tsISrtoza/yBl3g+Vr4Ojcix3c3RnEZrhCQXxX6i9k2ASSlZytDg5dj4KAV4ZM6LZAt7hQS5Ff6IkF+5opTyM3Ahfg/t1FcAAyST74SOVI/+a/CcbQ7uGIFDYCfFWxkYwpo6fw/ezWKcqs88naHp2YVvsyfDI5OWoLCa3Kfhz1hvihX9tMFNoFi/9G',
+ version: '0.3',
+ previousVersion: 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf',
+ previousVersionKey: 'nR7icOODtT2RF4o9EMxZTH4+qZAigTLp62lvjx+t9KZvpz0+JbFnmkbsp/X3tqswLKeOyQ2wCkBIKIuvc5ot6IJNx2QTVf+Nyibw4JGWiU8qoQ==',
+ creationDate: 'Fri Sep 25 12:16:12 CEST 2009',
+ updateDate: 'Fri Sep 25 12:16:12 CEST 2009',
+ accessDate: 'Fri Sep 25 12:17:17 CEST 2009'
+ },
+ '4b78e26a7c5ba770c11ca1f799f47112100c20565802ecdb8b0d736c1fee31af': {
+ header: '####',
+ data: 'i2axYBOEjs54cYL/YuYRbYVWTi9AVokVcgYboJ4A8il9yQOqev59Veb9+/B4yI5IjRHsz1wISAKmcLvMaE3ON79P6hLvGmf61aDEeyRzWnfcGTBJ3Tf5o2SBsOeVjPIHYAQF3gcSHk/vyFAKq9FUMcytgqMs36V6euMMYT3p2n3diF/wMti0nnNaA3dEGHDCZO8KAm/VWMySWH1zMkjkQ7R/Fu8KMKMnsNBJcjX0wFarVZWbuo9xJODg6vEsz5+WakY8UN6YhG//JsyFJA1F/0eynpWhAtKalhyh0JlCBo2y57iDIIT3acCxg05UMog/GpyxMiak3/iz7LEzMcVqkU7M8PGpUpHE4JM8fyl0IvOgHULKS4jcoPCQKmRAUuFbbouKwCE6sEnv2TjD9FxM',
+ version: '0.3',
+ previousVersion: '57b997d24ed1a438f7174e0c821b0c7197b5d3e1d0240f0956543934687a9763',
+ previousVersionKey: '8zvslkM62Woa4lFVxpxDCHteoFi8nAK0eC+/C70zuOkqmyKe/2Mu8YN1/hhd7TvJBW5JjzFElYm5cNv7KITHSmCe9ocwa23Bz/Txl/Yk84KC3Q==',
+ creationDate: 'Sat Sep 26 22:06:53 CEST 2009',
+ updateDate: 'Sat Sep 26 22:06:53 CEST 2009',
+ accessDate: 'Wed Sep 30 17:59:38 CEST 2009'
+ },
+ '57b997d24ed1a438f7174e0c821b0c7197b5d3e1d0240f0956543934687a9763': {
+ header: '####',
+ data: 'dDjbpH7b47K/OR3x8DFAr8317ojvn2XU9UeW9XCXNDI8ilFYvhDh2YdKiaHnoFe9c5nwqHH78g+V/U8xmbv9ojvuAw8EAqhOlen2W3QSi4oh3eAWXGJMc7QHMDhP38l2a6NG/fLCYE20aKof0thHYAZtCA9xh3Xj8P0URjPvzPEuPxSgxxtku6wrpuUJVmE9L8iM6GMxdtBg9ohnhknnwUQl4eWYEIWmANTkVOG+85DscW8AWzSCnGlBxSn2B0nYiYcVIbv3pIh3UwUK/VOnCg3J3zqFx5pL4T2pMBFhXMSH4Wg9KglSLPb2N1aR3+1l2W1mRWy2TmqBRmis6SKz8VhXlU73wPiL1xpdSXVXGdNTIkDLkP9MYugdF7vu/u2+DgPmbFZXNcEWaZP0UwWS',
+ version: '0.3',
+ previousVersion: '44aea76475425dbda56abc538b83cd270d00d8fdee6ac0575019bfcf4c719a5c',
+ previousVersionKey: 'Dq/81arpQSERdDNvvERMt5uVHxOzjUBKZ3bxe/CRZI6zdf06G19iT5L5Z7I0ZKUoKEoJNRTiB5Lh7PjDNibtY4oYRmmKXpUEPbiJKp351W23NA==',
+ creationDate: 'Fri Sep 25 12:17:31 CEST 2009',
+ updateDate: 'Fri Sep 25 12:17:31 CEST 2009',
+ accessDate: 'Sat Sep 26 22:06:28 CEST 2009'
+ },
+ 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf': {
+ header: '####',
+ data: 'osJ+5cwMZ/4Gq8WSNeRGwEJ/On/jDfUapgeyDYyGzkIznGaBIs74iT7TCv/i/EfJjqJQWKT5CAMtGngGjyrSC2wlhTB29VrCagyhYVZe85FHHLqxShwXVXMlCTPqxnJ+tUWAme94Lq54W8U+/zsFBqRhxteWYcfsAT1eGxMZbHTGU74OLLYCemh4jcvV55PGg7u55MTwzUebPlJvrFOg2KIqsqUYWuRzY9TjEWTb582rihGBJmj6SrPYcBN7e5j19mKtestLFMOw05oEEFNTPWaN50GD/8IuwHc2wZyk+VNxV3NDRwwqnGiKIkQTs/ddmKe4Ny6efvBXH8a4eDvDxlDCa5UHbYAT77RTg9jFS/pNeoHp7ZATy26/P5C0WqI3YfKfvuf8H1yRMzhDTtU9',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Fri Sep 25 12:15:47 CEST 2009'
+ }
+ }
+ };}(),
+ '983f262760a45171a8dbaad13a7c87b8a3dd267d1cdba7850b07e58af0460378': function () { return {
+ data: 'NUhdggGXc0aw9EgLWE1zCX4yTNZo5rxAvXy1e/i4IFQfromU3ARkbjBkVOui/VLrCmiExe81XqujgJHOqVp9HrgGuNxeo8ODqbD2p+/1YfxCzconrCggYf2eSvsIXuBuYJc5bGVdG/Mcp0DPedM5Gw8MvU4ix3EwVvIaoUdRi3RJYlsO7W0fPQjcWTt3rhLI0lkGTFvEbaK3b5Q0xv5mBup3w+SISIqDAvbmzNhc2DO9BzbcW158sv/+hBe9IHEtj5MoX/gY6pBdg9Dlnblql0jn/Mrfd6SR+1FAv5mS+NLqt6NHejs+8n1xnx3fOv1Tp2JoR+WbHBhL9wOlbMUjbzhM6XXB292Mb+KsqAzDdtNe/3sc1krIaSxYS6GwhPhesZOY3L84iUhAay60qdB1AQa1PDGPM+lkFEI3uqUZu32uWqnuudFAOTsgKcWVSTktk8AMD43zGbBhYKu+9cW2Ye8U1lL7E3+iI8fm8HnRiuWxGB8zKoqUZQ+FDnwiSFSsBYlCa7iLH7F1Cz1AjhCec8QsdlIA3TvbiKzzLCTmGZhezEJP8JiGifV8CDmWnrsRxgBcGj2CXAzksn0tuMGyBA1WwzK2DVtKI9utb9TV8CASn2uyzrr+OB5D7KPD0fuRDHSK2SEVPFkP7xXyLEZkFWy9W3I5bYyt7j9eUhHX+uk3WdT1onYAzogr3AhVIcMQSAeoyrxds81WaIyy3hEs8h+QzWVKhc021Xw7S1z1j5v413RLBSolwYaXrR0WjcA9VDnn+vOxsurR4y+Eca9T0+Fjt5Apzs5+nSarvi5rQbr6ggJVQ66qRv3SPIs/c5niiIVEK83xrY1fsEnjcJf836P10Ho35URQzqMlggICI/uBc7zgzPdkMBIvySqrCk1gzZi9PcHZoyNZO0i49mpGWnqDk2V24R27T9FwGkvRunOGw4nFS59NE3ixYz5SWZgIAayPBNJ5V2sSM3hUJAqXUl2vDlyXlqhhW9n5j+7nXhlwgibQ0Rk65QchlAXbmwm6QrSOX617DYhcBH12aUQMB8cQgURWmyysHV3pqvuLANvhjV1u9wkxfzuOdDJJCE4in8W2VUCTcdDtWg2L+RDAjvNGHFeLNmYD94JWdbtYRAGnH6oQWE8G+z1fgdnY6u8GNx8WsIH1thxHcle9UA==',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Sat Aug 08 16:29:34 CEST 2009',
+ currentVersion: 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463',
+ versions: {
+ 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463': {
+ header: '####',
+ data: 'K1a+K0TdDtLXo6e4ayBuwGN6XSjub5Xgy5ogA6HWVqe7tiSoi4Lo7qMloK4TF29YPB2KpHOyxodkXL0YpqztESCrBK+F1Np/t/uThl7iXEFNSXSIz4l/Eo54UX/PZEmKZ+4nMiuYFgMq1rV3VLQmciexJkic9rABwnGMreJfKyDt2fEDxdVUwZXnA/l1PPPGFVSJmkNRjW/WLRByOMwJxHDK1ElbIFHdkFRzg916aPTTjcV+KpUkSligoNlxi9CgmfeBweLuDRJL75Osw3ha9WjQXrjTlr7o4sSVud3gbivYmJGgbOTzgge3K0A6ztS9+8dvvQleR9NETiWDDhJ1+3Y00jXc9jgOEyAQklD1dQ2dew23fvIVXSofVpr5lp88X6gc0OnD90BbxrTxjL0QYIMlklgTq40vNck=',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Sat Aug 08 16:29:34 CEST 2009'
+ }
+ }
+ };}(),
+ 'a0d5d8796793035d1b109654c68d34b94e2aa64b5f76d50f01d9a18ab1cdfd5a': function () { return {
+ data: 'dIOpF0FJxZCaFDj1XeU1L9/CcnHDffBgeOxN30sAH+++Dv0+skIYibSLkbc5SFOFKkZtKGeXFq1fZW1Uynj3ogRJ3Qqb8+4eyBiwViLXTFefYv/g0LcHqUYBrRwYpsATZg5VcZpIvXzwIT0N5dtQoh8IskMovV8QgBICHDAJImB64c8bDjVpSn9GWMSiSqsSOu+j1IG/C2/Qxxt5smKD6iINfJS8Y36iovV9vRocW1crj6mHatJxut/EhWbKrXA7U148q2/08EZPfAS3q+Onv0VUaKxgB2+nhsUSYjP3tvVlc4LS17Q9CnbA+eNYz/DfsaMtnYKTcSh/91ViA8Kv1AGzEbWIMo6On8shuf691bzKBdRG9Fcpm5Hhb+DziJ0Go7W99yu4n6exHAxJerXpcA9t5fpsTH4T3lGhbWI5HRWoU0jDqwdE2J5jyZaUVf78CjfgESRdJuOKIuV4QX7xxwRJP9vcDHgyhr1LcscVi96XQHnii/tl+BAUYdwgvv2vtTmuoR0ydtweQbDjgLXtk/zmyYmP4dTIYbU/Qec1m4E96jZdTalWU9K8AtnopuqfLdTlFG5mGtHrRpRpmu2o7b7P0v5V/WpUpPWzk75sv2AsFD7oiTHuZ5GKUfDs8pbp3LcMNk3nSour1NyiDWFB022hwbEk66aQaNxJfCKOWwWimc4TfxhVG0imjtdlp3MdcWcAY+tJMWklDm/q5QkuHy+JxfNzHFRI63+c5+/KSFHVUfZNoIRNdDIlnTiX8zKojU2X0QRzxEc/LYkIpon5OGRnJy9Rb/HotYbovBC8yS6610ttGohDp9v+zVO1uST2COV8j8p5iBJT+YVgQvLGXg/Y6ZQw1X8nGeQClBZnPZVhHcnTtQV3tyBdsc/ZkttJ5tLW+FF9hAt48IBnI1um28Fhh4y55rznF2W4U1PyJvsmVk9eMK6ccHCXFNvzCN6XUDY862pm4atKSbIMQVuT9nOC4G2cSl2/Pte2W/s9A0RqeU3kpZg6inXYNknhTAufQc8MBHuNPkMJGTOjOA/MUKHM73+b5Iaz3pBXKiw0qlgkfsGoRZ4LVI3oU10geEqNoYeeseDU1o/UDDC1wobRxy6mrob/EstC3zoIMvM651k2h0Pj5KbjE0+I4d2mmObIN3R/OF+hdeVAtZYwuv9aa18nTlYCx7Wo7mGwzPhFVThaZT1jgNfHVFa7lxvcdi3zo5ihhPUXjC11RrcKcdINMxdvQpa/xfwV5VNagXN0D7aXaxVQj+HTlttXx2v7ElkhpLpTA632ggWBdL+HZNdWMPjE9pZO3KhU0Zg7x77wfrj3tN2QC3uDUSOJOCp4qM4=',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Thu Aug 13 22:43:56 CEST 2009',
+ currentVersion: 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5',
+ versions: {
+ 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5': {
+ header: '####',
+ data: 'vWUk4EzThQjfNp/Ji11ZI/fO3n2sp8iUr2Fahuz7Cl7uOCNnXXFoHlbbvZNgZsrVVmK3+YV5WxblVxQYlH2IRwdXsvkfzV7S8aqJ4V11tgst31kZ03vQ+pfPV+26Nhv32sLWLK6t/h+Ap701KpPsng6rrWd9YgSRzN0gQt80aHZtxVknZcpAUmh1thx/VaehNWEwLPFOvcGr6H0Ku7U6v/GNFyBmkgPYMh2Bo0VIhns0s20mgA9L6TxwLcMYikU19WqxX9GO1n11ii3WAWA10gfFjAwYagnQiwpl5REU73I5raYI9XU0XjouhRtkMMBtCJjeIDb3GCQQQZwTcVFXeokjtAlP4JHdMy5Hrl0LvjpDI77OU/rDHKPc5TqZngvFk06TjoQ7pg2cm7c8y34=',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Thu Aug 13 22:43:56 CEST 2009'
+ }
+ }
+ };}(),
+ 'b81f9a1d9267daf4afb786e8d477c15aa3e1babc59b8ba09bceddc700116ab0e': function () { return {
+ data: 'bJdzIqpYsh6++iVT/jTS6bj5SgXkW5alx19H2laFERykhmkA0hxjOTaz2Sizlcsg+NKEQIASIjrVrLxcoIVnCFeJjDv4FOEACpMxNEzAiWTppWx4h6hepKT+h8gtkF4k6QvvVXHBXxRahQT2tqsbJWmOgmxdIBEeNETZb0u7gD7TjI8ATetaQ+TnhKlNbObUd/LsuJsZuWwpeZllEtNTrwNOrlHQJAUe3u+xI9O0lVBvH+/KHX4L7QyY98O/aI5wosDWPUZyv811PKOCMCsL/+2qBrH/D00YA+gCPy24riBrrK6RJWC0BdpSAUhPZA3OJSm1miqHNC7/JCUfH/alVMaoTzrI+A76LouteQmwZrXE/taTPY8zLD+TCgMOGhgxErVcw6278PQSfuERIJuXlCiXX1z011JrRE1k6JX6Ual8gwENvYlbXE2/iv/xzXK3WtI5vD+x0kRqa9LAClyhSqY4o5QXlEBJ663j9PxH/+vC25tluAtupL0nnm4sEtFmVMiZ3S3cRRZ6ZzquPD6rQjzdPpAJe0S8anC4Pf7F86Z+Ag3lbsrmV9Y5uDhx1T9pyWaydL6NzyJBw1gjgobSOw1wNMAzn+kGLqH9dP2c+Jv9zp60vR5Ljdf73jPxWcVTQxHZzXuWfb0MpYTwRDmpjqEsIKkyaYu1e7YHYaD9RNro7Aek00n4DOkPJ+lQHdeGLioNYraYwhQq7Y0HAKFsUYxv3o8vI6X8YXk6GgbhLXjBIyly9oyVMbGMShCuDE2dt+skM5Y1Wd1AcENJ+YzQrRwc0QWrYoABy/MlZbhgh4LpuQG6WajXw2kgS1Rme1tMviR+qqtnthsdWClKp0y7GZEA5ycBKABBX4RDrwIudiitswMkvBCrSLAxT3KYGxjlPwhGShf+zGiJ2vS6mMh2KS5rrcKaFtYsOSfBoNDpPaK9w9QS2W1EtwuUY4zZbUO6V1K/URx5PkZrSAcIRLw2CjLad9CbyhOZ7H1mW6ovHYXHwDPAVU4wYEqO0213w50QyBOM',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Sun Jul 19 01:09:10 CEST 2009',
+ currentVersion: 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8',
+ versions: {
+ 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8': {
+ header: '####',
+ data: 'fUzxKwUtvtyjL1kIN6jfxjZq9CWEH9nlvSbND8x9sn7cAhmyuvmYR99cl3e8GJ23uzxHn9uKn5hTG0uUHXBMrqIpCw/QHzu4FDXWS9RrR3iGJba4DIBJPY20VpFJzWr9xbtnC8R/TDt0FXryE/V2ibiiF7dXNucbhlO+dPmyDXQpNDQf9QRRpPILCyfd01DSUVlvr+91DWgtGk19ZTAGB3Cl9WuUtRHUnBH9JhKLEohzou5p/1KcfEFwMZ2SOyiZPwwBP1NqE5fqHXqzPNzvvQL6bDxH8czkAfMlw3URJfhnlSuSKa/o15bdwMLyFaNrTjod3Erw7uvPxpyFg8Sw2yCOM4xJ1Bn88vttklNQF1ut5SkAwDYi0wUbbyP6CnE0ItVvc3MKZx+0r5RHzasJpQY=',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Sun Jul 19 01:09:10 CEST 2009'
+ }
+ }
+ };}(),
+ 'd8568a483a8f443190ba723b391960554962760cd886b2484f2698816beec530': function () { return {
+ data: 'PKAlMlebOZaZDdwgP/Y5cZBzXYLpBdppooxzQn7kzWNg3ut1o+M+bpfjadwdM07MTtU9PpdanlG4GfDPf1uPn/XYN4msUo2V68J/tliU7M0q2t2PKqA2YUDl3UIxMlffhvyYBpwsdary+4t41pKkPjFt3/WSthLyn+E44BbjAKRbpp5w1y//GscTXDlQzdDGoSNdSjpu8hx8Zs4tqf/9UnlwH5kh6Wzq7+Uf+eqiC7S4fPfZ7G0OZ7+N2oKHiV7EBRSX4s7vcrs5t1S+v9HUhk6SkZ7mMZBjSg1x8sB3ZZB2sLAx+QCJPyKv9+/uZLrSMe8uFHBI2H0dx73mWXE/dHK8IjG9mZs2riA+KYutHT4jV6ja5JZeLWWuZhKzooJoSk4A7cbd2zxvkyaqLkscgVBWYWf212EvGZN0ardI1fW1+RTE8QchyX6ty1AyjbU2T15HKwLvdlL0v5aPscZPQJwptOMCrjYOwkbMTvxe8YRKZb1Z1VzyCn0m7ODxz0iXV2H6pj2hierKuqeOuK3HWV4rk584ctE2KBIHh7WJnkqRYKCCQ1s90T8SNkqQiEow4Bz509seQ8ZRROy9F8GSCOeIQS9DVbQkRjgEOMo8DFSTNT1HzBiGhcaQkweh7+V7oAx21v7F+UYEIIvHlSvKXTEA6rK+eHunF1EHRvoGGTD61btaaqpfn/Z53DKd0AMGK4Uh3eSGkqKM5IW0mgebs52//xQI/BUrEimvSu5u2UYLh6V9sa/kT9yNv2BfnRckGuNvaNvQBrw5LFOfK59UXeO9h6DcWs4AErrj9afu29xHFI/h+HdaixEzsmrboBqEn0g3EghL+de7N8z4CGGQ/CzhIKmAlR5f/u0YC0xebVNLSKUzTi1m3nOhreywKCO4C0kzwbduEX/bJ34SXuYOpkjS4W+Y1mdd6tnsAPsY1Ku22pjPQz8/aKRlDvIUKi7R+6Sk6Q1pIpcwh3hvEkN1OSBea1BUho4udaulPolefLv/kqNwQZeReztukD7sfgpZr3GEocBwnui+cCLj6WpVu2qlZpxGvnitmfJbaEEw2HM3RgzibGtsybeXwWK3orcEnPqquApWtnTXP8rhP9TBW8svHA1NjCgSrvDbjmSUPsRAHkV/zlXhH+JJZMv7tg4BYNuukJuiBFn/EewEIA==',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Thu Aug 13 22:35:14 CEST 2009',
+ currentVersion: '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3',
+ versions: {
+ '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3': {
+ header: '####',
+ data: 'wuvj0q69S3FdDA0x+DniTe4no4vW6EF/xMiRD5GoDdNYxx6Npyxf6h/FiIjujncc7GK5W+p09Bqh4mHdsyBAwe/Y9c5mshB9VpPgsF9YctR6iLnOs7TGOWUJ/ScgskhagSGZme+huFkFjEe57yx2FiiswUW2XVI1SPtzHNx+sAGoL+XcB8B568zTyU50IpJfXlXR+10OTRMekaTUyNmNF+hT4FnRXQKY4XL6NKSvSH/7gafKf960kQhJ1HWI62OFYER04ANTFLiOdhfZE7YcEIG9W3G4UFPRI7NyZRewah+ETOLSrTdbhItY0kb+FrMrhNSrHLBjg2t3xmuaptDV7BoPYtTfOaD5zgwPgUCj7KnnbamgQiABGjKJnl9GMC3bej4KpKqlgMrHqUqu9AGVCtUc',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Thu Aug 13 22:35:14 CEST 2009'
+ }
+ }
+ };}(),
+ 'f8141d3cd5cf93f3ade420838f98e4bd0e5206d202b45a24822afc9099827c17': function () { return {
+ data: '6xoQmnyFcq066ExiktwoyXTDnu5+d7+7PwMtvUVX8AjU/1jJJpG0tN4FnVWaKIngm4cdyh9Em3F9iZ2wDJgQ4+IlqVAal5pFgA3gvsw8awqsOkQoibFcmlatSO4H3vExZ9P4vHFherBMIqo9u3zwqUClgAFEyw0UlVIJ6VIsE1qSQFksBlnxV3sKu9kjigYVWd/KodpNqiOiX3CEgQGmX8bHTh77VWXNFkYGRaGhZvXN7gx9qLSZwSLn2fzgxzBbjOlX9Wj5tQQ5pxev5pJd19pPAmbzJZcdZVFtaiWh5A8wwROX44P4X6qfcNWZt/rx8DRdtLGKlJy0GWTQMZXVeKqmE15I02EYeOPPbPvE81psZfCu+zToehQa86l270wbLKu8Cv+8Bfx8XJBLsYLL9asv6XzAoLMG2lWX/TkAPavJb8Doqpi+SEeK1YmYg7YE1hyIEjDrsHoUY1hVxruYfygahBDEoa4pyjQovhq5d0e1Arnzfo+LD0jcFuxFj6zcLjoTx8ugs0X4A0PeP5BG7VYuGYx/mBIWsu+0ksjGlkmC4EIHJpHbSeMUqfTxoMALmdg1Y8oGnHfCKhlr7ztjOBo+nE95iMQI+L8Hwnjto0hcotY/ualKzwDXf/BvlxlNov+Z9DWvMe6q+8yqyiVZE9HD7O7goienh51Pa+wV6K5jdnzCUTrK5ygk6rfbA6tLdjc1kAzCU9oJguLSwtM4z7WMel2V48kOMD7FaWZHPCatweKPaanV2WCeYhtc9X6OvIJWvv5O9j7fNd7xFByZNORQYaHFN+5xONOVJ6T28TtDn/VdVc8u71kfAYWLEG0Au+b1GY9doAxHwNN5hcP1uGHEsc5uR93qgiQLa+zZbUc8to1OylcLZY+yWdyiyUEXM01nZH6ZYuDdRUSiS6WkM8KPYLwy3NpX1Q3ZEC3uM1yi8589scPl4JhCd2XBdn5+iu231Uzu4O/fLTmN/8kNNV00x9Xa1Rj+0+Srht2WDgJVcTBoODikoh4733txmOl03KFCQd/HrRIS1DE1hrGAQNexh0Om7/WO+rzaSPmzFdyskqF1bXek0f3V1YROWxKIfHF8jz/wvqVgsGEtxgtCmXqyT3dRZlKUxNXn/ajgbulsensAQxUEpeB3OeVxNPl0SExb96oLSvMrLJO02E7hZLkB116ATnqN/GVtzHJzQLT0c1HPu9UuGQPv3D7qWpx1qMABuhaHbpyY3OcN6DOZTHuOzdVETIkYlPoja0TMyt6iHrlOM3dFtVDUos+TJyVSWjBSHVV3b7tbpGFulSan5J2BWbCNcSCMSfJFOX/U/JlovKAodr0Li85K6nej2XI4N8rVtV9ru4Ktq57/z6REvoBaIS2YXUOm9s2YhOA54CByVWvKXj0Pez6U7YVJvsviYtdp0IxJE6OrebzpVx1skZUFPTbcmuD5/GwOv6PmgciOJMY/nMQ3K+7F3A9AZgPFihLLPOh2NpNhoj5Zy6IlK3ObptD6I41HHlN3BsADzV2buAbcTDyYYZJ9VkBI2ZkkFhrcB1WM+qrkODiPxumXYGnGSHvbuZq0m5k8Kw+WUblmedHyMCLNEiwH2YQsaRd8s050wE4BcKnNU6wPn8HExn5b7CFjMJReiST08BMcszUTT677QQOcsbGvNPq1iYIrv0f2rrNHKhg2Kq42+jvHYxndfuxnTUjecCGtiGpuLdh/iehozSjuZfV7fZWhJsYOz/HAj639sJy+BMg7+gQv/yrujd1c0n8FixDryiogKLfxnnfWIUW90rRqcjRW5tn4mUfhf3eEP83PmKvafvRCyauY9Ho=',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Wed Sep 30 17:57:12 CEST 2009',
+ currentVersion: '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74',
+ versions: {
+ '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74': {
+ header: '####',
+ data: 'IQcdAD6W2pehgomwdoNVtFe+Aq4PAiHM8lngNDSesbTPs7dzFL8DR9iR0VdPUfnpL2ddaWB1dkOI83hQ/vFZUeAHswU/6Gmg7KQPpciVsbNMAHkxidDQMncMvU79oi0QRUvgWCrVbpuNd0J9Ir1vZVU2UT8LNXi4RibORSLhFo1GIyy6Kss6GOvDDWnUzBV6VYqzcv/nrLDlL908CnbmQhCaoGd5j/TjC9Hx1UaJ/xfqOwPP0jgw5b8+ArB8tICkpLbEEXSzKG64hGyY5DToAo5FS7QvZBXhzhm1qc0VM0RCUcvU2+sCm5yvT/qV3LRPDHKcoqle2PzlumsxyuiAlI5y9UaT+6GBbTrJ+FeU1zm8fVAyg3Q+FZWN8A/YBj1qb38z8E1D+38f0hGv21QfYg==',
+ version: '0.3',
+ creationDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ updateDate: 'Sun Jun 07 11:22:08 CEST 2009',
+ accessDate: 'Wed Sep 30 17:57:12 CEST 2009'
+ }
+ }
+ };}()
+ }
+ };}()
+ }
+ };}(),
+
+ 'test_test_with_otps': function () { return {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ '9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8': {
+ s: '55a27b18e8fdf1fb5e5bcf859cfa50fcbc69c9a41f04e371606a86411a98f460',
+ v: '983a6c79e7d5d490c3f13645c49760180fca05cc677914bf60fee009ead5a65d',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"3f5cad41321c89a0570c310f8e994a13c39c83842660c540960586fa9f2d2fc0":"0"},"data":"cllv5EtmluxBR3AWjet3jfZsJZDUXFddl1hIO4285PJOUymk5VP8nxLGSkYxkrbwIKHxxSERdwhcSVeuz+QJLFzx4hP/wngSNJT3edxh9pwM+fUs8nJunyK1LNS1JatoaWOIobTV1DbotfvxGUQI5QIxvKA="},"directLogins":{"index":{},"data":"54KM7x3emxWZH4CQDLBj4SkT"},"preferences":{"data":"AwOQXmReKkLpp8qZa4zjaWcY"},"oneTimePasswords":{"data":"1FTEyUjZ/MS1Kp91l3j00WNnOel6EFQhAYyAhcr90ozYwu6UDqlKNKyp5f2ndVZS36ReoxXbzIUYUJoaQegdvic/aVfyU/drjqVA/Ta2S5ICR050ewTUBs5BebBQT2WAMzKhmhQoKvMNCJFpNhLhJ7sbevyAHX4lZbpBUz92hTQ9jtpTi2pZ7IBUFI3JPV71H0reIs8FFA+Ugx3UPVVq77famGm5mh4I0rjY68zVvqNvfB5APM9OKR+AM3jkSHUa1QEzCEObMndR8WfKEyXlYoEhnhr1UEra8v5INHpSacU8210="},"version":"0.1"}',
+ statistics: 'tmRcqihMK0YvsnFoMKH5F/rN',
+ userDetailsVersion: '0.3',
+ records: {
+ '3f5cad41321c89a0570c310f8e994a13c39c83842660c540960586fa9f2d2fc0': {
+ data: 'nlihNmY5UjnGFxilT5LoDRvdp5WoHausCTiulBY9/Fm82ZJCEZ0mwH96WzsnQ6zMvrZPFHAr1zGAQPr82/MOr7xTVILjbEP6MKq9rOyEDRhY/3CVQgJVWLPfwiL9ihw9jKkd7ea3eU/RSj7V0UQB1zXzEXFqw0FwQcpSuCOl5hkYPecydA==',
+ version: '0.3',
+ creationDate: 'Thu Oct 01 16:21:50 PDT 2009',
+ updateDate: 'Tue Feb 09 08:57:03 PST 2010',
+ accessDate: 'Tue Feb 09 08:57:03 PST 2010',
+ currentVersion: 'ac353e86f69528d21dad0b17d00bbfb3e56c954e2ba71d0d091c903880ba1479',
+ versions: {
+ 'c84928db21b880a53e7ba1e51eebc4acc4b2bffe66f30368b8b7070973f5912a': {
+ header: '####',
+ data: '0xBSvvZ3EJhc/PmW+8PtpaLSAOmGo4i0sG9Uwe9RGbzDILvna447spjscE3IxIucj1EuBagtc2hvIT/tgkA5IIp4fq2dSvk3RF8h5+hXPy877tEZkiQFpigyUHd27smpYDSYc0Bzv0DWx+eR72TFIjwbU/CXxKR3qqyzma+q1pqIf1GiaZWlM+Qv4xmKEkJnRd6NdOyTwuAQoZ9q0O9pHtkDQ5eKQlwvuZuL+8Tdhn/Mvr5HzIset+4wo5HNvmkLNAtonChJpWWnj6Gc8LTI+ImSjM5PVku/O/pJKuCYtMovzzEoNuFWrtdn9XESKF3yjtpKzuDxsNPrfX5Mz0iBZCefbWEtmqeABn3o5IgkpW/rhSmsyu8UcCoq91O+Yb9+8qlcsJyjcLECd+wgkpN926vcg/LMTWUW6Oq8x1a6mM8Bw1u9kT0eZGgKvu0CZpv3bpgVAWbfGW3aTM/0moWjHa3amJaL0DPjF8Pe9ujUDlqVEiPHznzfS+aVB+M3DtjfNEMysab77imICRs39cm6N/XAz+CNnSuP+W4WPfbZZ+3xWU4BgS7YXd/AM5rlI9sXNQQgzVmQttNo',
+ version: '0.3',
+ creationDate: 'Thu Oct 01 16:21:50 PDT 2009',
+ updateDate: 'Thu Oct 01 16:21:50 PDT 2009',
+ accessDate: 'Tue Feb 09 08:56:46 PST 2010'
+ },
+ 'ac353e86f69528d21dad0b17d00bbfb3e56c954e2ba71d0d091c903880ba1479': {
+ header: '####',
+ data: 'DGvb5Ur86eYxzJrqITEX5XqtGQT3QiaR66B2vw5F+6fo6cxWwCztnoEFyLUPzZGWqYMIIwA2rKaNBW0PxO1ehu7kyyQ/Tj42g64JiI4sVtb47W5/En2blTtkPe1FjpBiVW9ZaTDo4ia2wMzrBxTpUJ/NCT/Hn/xAyhZrafL+SN8U94F/FX6n5x98fV9KwrtjPpqeDEtfwheiEzws4qoPy1arXgnaECxOFnri7KpjwE8WVzwbU/WFOGPewKY4bLcba4pp1KjjObhVcYyj3K+GkSHeXyBDQqZi1grKvGOGvoZkFr7CDndseaXZ8og3A+NpqPcOzbqNst97gsky2RWc7bD2MfyAJ+QHzw5uDFCoKnAv5VH1HxwkShLb2QswQFf9/AGT3IDFi6ssvELk8xSMTgICV9jUwcTwkjkBa1Zpf4GTr6qrzen4YzNeK6XxgAqueKFbJoC8p0l1dBGBoH5zP0bkh3QENEFk67FT3aXUtInP7ZDX9Fnbe6qPkoztgmG7TukNUs2pk1Z/iJTVrUdLTVtwFI56LaTfRT8Ica+yFJc+1zoKeEg9LKcnbgfPY6WK58o1vXlhYb8j',
+ version: '0.3',
+ previousVersion: 'c84928db21b880a53e7ba1e51eebc4acc4b2bffe66f30368b8b7070973f5912a',
+ previousVersionKey: 'vy7sCLt6q3xaMngGjJxVLcYe60vW0LHXDVZGo7QWZCIOjK26Yn9JvpeAi4rKJ0/ggGGyYJncqHVr68u/VHuwJRUmlRb7JRk5k9gJOyuroyx5wg==',
+ creationDate: 'Tue Feb 09 08:57:03 PST 2010',
+ updateDate: 'Tue Feb 09 08:57:03 PST 2010',
+ accessDate: 'Tue Feb 09 08:57:03 PST 2010'
+ }
+ }
+ }
+ }
+ }
+ },
+ 'onetimePasswords': {
+ // OTP: 'yaxx k7ww - f8y6 tqz5 - 58b6 th44 - 9cwv q0fg',
+ '7074103e8ce35f813dbfb9c90665bd66ba3f5b1c9e4fa7a3d8aee679b7a38102': { // reference
+ 'reference': "c3664af5744319c6d3b874895f803df19cb0492acf27cb51912110d023ba9b38",
+ 'user': "9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8",
+ 'status': 'ACTIVE', // 1: 'ACTIVE', 2: 'REQUESTED', 3: 'USED', 4: 'DISABLED'
+ 'creation_date': "2010-02-09 17:57:14",
+ 'request_date': "4001-01-01 09:00:00",
+ 'usage_date': "4001-01-01 09:00:00",
+// 'key': "7074103e8ce35f813dbfb9c90665bd66ba3f5b1c9e4fa7a3d8aee679b7a38102",
+ "key_checksum": "53739910c97d74c80c6028eb3293ffbc652def811d9aa11725fefa3139dfcf29",
+ "data": "aN3rPl5rusBWXveUpjKqZNFLRPWJgH2Zs8HYQIaS65QObQFWFTZ8lRpBXFoPlvSOHcHQpEavZUuq31Y/2Y9sI/scvmZjQ8UEaT2GY9NiWJVswGq1W3AX8zs32jOgf1L5iBVxK54mfig2vXFoL8lG0JGGY1zHZXlkCvFPWuvwuCcH+uRE0oP3it0FvNFBV4+TiiGnGYgD9LPAVevzr/Doq5UXjn9VplVU+upeDTWY+7rlOdIOnZG/A9P9/dQtsyMb5c5zABD2FNpQQ40JDfG/nHt5WvfuWmPwUisW1181oBAd5BwF9LgVHdrhcSh8OuUL7rdbKTPTlWT826I6JNrFMzYGMY+NV6gllDvc6eCNrgI98ABhL1AoZNpAXXuCy4uQhEYmj+O71C/eXEDw+crMAXiCn6SZrbTM8GT5TQ5yF2NcxhudopO4qoILjnwEHZZ+i37kRDFg6oCBccCD67oHTPexUkSqnKIIYLli5CdmE7UdvX6LuVG/VYJKevOUgMf0UzHDPgvtlp3gsSo09TfNPOtoeAiogL6cAHb1seZwv+6E8Pz7WqkkOTsBQYeHIfPE0OnQPDtUjVRA5MTTX5zt6rCCNDKNbqfkPu8V4am26ykaWOSTXZYIcfnywkG0TfPzdAyQvyxdUyl/r1b36bclQFiXcRzkz9zS9xx14Il3QjYXRbIFWcwm/mEFltBFPdATKo5Zh+wcTLiFh56YEUVa9/h6oN8281X6zxH4DOw=",
+ 'version': "0.3"
+ }
+ }
+ };}(),
+
+ //-------------------------------------------------------------------------
+
+ 'otp_user_test': function () { return {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ // username: 'otp_user', passphrase: 'yaxx k7ww - f8y6 tqz5 - 58b6 th44 - 9cwv q0fg'
+ '0faed660854b02a5eaa7140f58d9dfee875361b353609f638efdd013b95458c9': {
+ s: '61994a953b7c053abca196ecbdb76547c9936654a434972d3d1de84e927077e4',
+ v: '9250fc0a479f36b9aff3fc0c37e88169cfaecd25c2c6d59ea2f58271c2106265',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"a1bf4f4c924a10ff0e52bd9f9e7efce8b09e97a5b0389b1342b4a62226be4cc1":"0"},"data":"Yw3NlPSpFc3YQl9pMh2tvcVWHVwISUBoFGqlJBwxtuLb6vpyEg9AJs1LDjtLd+4Zh3rkBD8Hnxgc6R+DpNBrVAq/hENoMVtAtFm9FznEQO4YOe0jKGJei/jTRrG3vf4pWG92jUHd8JDZ482AzArp5leaQXC7Pg=="},"directLogins":{"index":{},"data":"a52Xx78tyoffHRu5J99fr3sH"},"preferences":{"data":"AFqk+zN3X8UzmWw7HI+p/BvL"},"oneTimePasswords":{"data":"9iwi/ScBH0o7SVZz5nLvu792"},"version":"0.1"}',
+ statistics: '68Nb/l04isS9JcTQf9bmwq5/',
+ userDetailsVersion: '0.3',
+ records: {
+ 'a1bf4f4c924a10ff0e52bd9f9e7efce8b09e97a5b0389b1342b4a62226be4cc1': {
+ data: 'hNdplOo1+O6pW7HQ6ReYx5CBDzWL3oopwf/7dMH0RVMYHu1LbMRZDRZTpjnLX33UoCkthF4Br3xkLwg5gDMuR3unx7Eyyf35yZj3rcLr+ckj/z3rV2rlBgVahwV5xh1E3nVXiZueKG4qUqQisnrJWj3Cl88c0KlXtsMew2s93l8OuJJS0g==',
+ version: '0.3',
+ creationDate: 'Thu Feb 25 14:11:54 PST 2010',
+ updateDate: 'Thu Feb 25 14:11:54 PST 2010',
+ accessDate: 'Thu Feb 25 14:11:54 PST 2010',
+ currentVersion: '7b0399826323da5fe938d8f17e2e03192b84af2e95e6d6dae0c8717a34cf4a72',
+ versions: {
+ '7b0399826323da5fe938d8f17e2e03192b84af2e95e6d6dae0c8717a34cf4a72': {
+ header: '####',
+ data: 'QZgYCpbzVvTd4KNRZW25SMXSyv0PWt7oje3nokC7TWSi/bdxcS8vQyosyFWWa9r4lDpO8/y7FYaa4O8b0ksX3MCOiQeQNI1a5+Bod9sZHWGnILwUnm8jVnuLcOrG/a69/ElLXdObwTXBvYDgHul1gIGWaV7cxYZmYFU1TlgPm0lklPrWqvteurZ8EzdBa9wrUOdKEfEWncn83Mn0KGXnm8xARYu51X4HSWrzKO5fpYqk5o223esndY4X/nLG416HAdPTCOwigMcqHV41asoc0pZRacQbqEhK56xAVKmTnquMt3oZVc/oRuW16ZajXl3A0I1U6ZASOBIZzSDaPW2vKYyEzLT2jxL3fq/GDgs8V5Ctlk8/b0Z4KjB/00NaikyLaVnEvPy4gBbzPHWNEOXjdAGynL/Ez73mNIgBEEUSviN5D2usydJYHF2mTFqldAy3',
+ version: '0.3',
+ creationDate: 'Thu Feb 25 14:11:54 PST 2010',
+ updateDate: 'Thu Feb 25 14:11:54 PST 2010',
+ accessDate: 'Thu Feb 25 14:11:54 PST 2010'
+ }
+ }
+ }
+ }
+ }
+ }
+ };}(),
+
+ //-------------------------------------------------------------------------
+/*
+ 'tt/tt_data': function () { return {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ 'afaadd70f647886043b9196c861dc04f5605baeab3812ea23707fcba08c4a54f': {
+ s: 'df781ec363a380a0bb171d7d4c226248259272a964f04fa2340c77ff84bbc594',
+ v: 'eca214d990ec971a61cd9c5082e62c2d241f8e1ec805a2c26b1d31612747bfb0',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"77ecea1a9917ede00627788a28c6e90acdf7e5c12864cf236d1f41e718af7528":"1"},"data":"WrCX6cVPslFMYTvGWv7PVwWicAlBqB1I3QX0TNfxM6jrPrObeV4hRrRezUn1rLbQgXYFiuZdQ9mN8n51wNFcQvAXi0TcqmhIu23t6LI360ITPIwq9vNNEndt66ma6W1ANYcx6w+4uKga4ci5NA5vRwXN+s9M2G78HKApu3tvg1aayXmcr7FhoQ=="},"directLogins":{"index":{},"data":"h0MTipBOXYKi5HWM7eAEMw60"},"preferences":{"data":"Ws8wpQlRPwzQCt5hRWrKUUz3"},"oneTimePasswords":{"data":"eclAiKZ8snvT4Rwe7fCyUYXl"},"version":"0.1"}',
+ statistics: 'tfQF+BrjAQUWyiXWOMkWApmq',
+ userDetailsVersion: '0.3',
+ records: {
+ '77ecea1a9917ede00627788a28c6e90acdf7e5c12864cf236d1f41e718af7528': {
+ data: '1DGumxvp+09fSbLxed0wnGW5kh31ORuA7xhVOA==',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009',
+ currentVersion: null
+/ * versions: {
+ '': {
+ header: '####',
+ data: '',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ }
+ }
+* /
+ }
+ }
+ }
+ }
+ },
+*/
+ //-------------------------------------------------------------------------
+ __syntaxFix__: "syntax fix"
+} \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.data.old.js b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.data.old.js
new file mode 100644
index 0000000..1cb92c0
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.data.old.js
@@ -0,0 +1,172 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+MochiKit.Base.update(testData, {
+
+ //-------------------------------------------------------------------------
+
+ 'OLD_joe_clipperz_offline_copy_data': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ 'f527cdd90d0d47f8524b4e165398ad1455eba515d04abd101d1e93b3c6ae0674': {
+ s: '097ca38b1792023d6c1ffca50606b6040c6b27a7667e355ba9e54e6d47d8bf23',
+ v: '34b9f3ab193bb12dc93c791637b8d80364564b9a39ed7130cd168d52876914e4',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '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',
+ statistics: 'iFI3fKfuUd5Tqj/iRCJnIk7isZ2FOYPr/yNfICm2U35oUeTJ/RA+l+kbWiYrecpIEgk=',
+ userDetailsVersion: '0.2',
+ records: {
+/* 01 */ '062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80': {
+ data: '7sgxSQlqR+wh3g06M2+sWp7raQxjjQ9jLIz2OcEB7SckuQcXNrhMlDCbL6ncSljtzgqhioWrOB409kIG8lc7h6ekghOE/Mhi7rVwAiRfNGB7r3mYxpEXRe96O2RG7E+NcSp8ezl+5gJ9D0o1abXPeFQYGcr95hUioCfyY+xrxY8TJVwdb9nHkYvBdKV7rCl1dTxgsKWK3nlo1T7e5uyiz5YUAE6BrCtTFAqtprLI/xOpRti9C+llohS7D6s8hkCBPZfp3chKFDrgpsCBFLhXN8jrBKSjHi1PJdRQzpJsgrxyeBj0dZx3gTsYOXqrYgdIzFUo7K1Tqb30yNprBiDMr7j0YYXiSvEb7OuOIP+HTXGN+yt09bk9LggyY6Fh0e+tenjQQ3soySN/XznOBpEjXbzXoz6fR1MXVnE9GgaX99LVNqwWfq2rIBdSE/FfspRiWP3BY5jIrEkNeRclS05U1zw3K3wxOL+cB9r2IynSXnK8QcrDNNRZ0W3PhsSFfByUXuviLSEOPuJa1mYP29L9Lj/WyHL1Gyl8xLbt2H41S6+wvIleKMuc7teH6wPXbnYphvbwBowoI6HZTEFkz3dQKhhY6VF/81iCXsuaz6BjyrzFX6SkQ4S3lN1tv4opQMJFvnmHb6EkXqVWfeIXzJIJO+owL4vDOf4okpAD+HPjjlVXhq6fvyM5UBIK9+tzJW78X/zifrQOfWRIhwjVsfUdZWmZ/S35vnHWNuXkM8GBYrDysqxanDtah3U8XLAiIhFtBOzpzr6qGaNDOKKgG3K8QXT4bYHOq1rQVUwzQuKhlCyStrRMQrC5Ry251xmLy6dKfppRarVeGDtzB/30BbtFNdZmzMNG2g+Jj5tFCrEtCMvMiQEWZHMU3tGMFxDef/KKdv1fFTJC16jmaUiCHUZmNjB3EO9R6xPVcMlAVKf57n3efrpRk/GTmm9JhAFkuF/wsveH4JjPpDUdkHYFu5tHbb30sbga3ufBAXbQL4ck10S24akU/cKraFGLvuKGaR2U0i6ih911TBSf3pAfZ3RFbBhVIl+6rSknC5+IXoBR7MRstBPW/xC9pQVjN5Qyn0g3aUjUSI+q4jcTuvMl32NtTJbWRMGhfkrpVzypZTyPnIh6XJkyBghlUARXw23MlbjiZxmY4ScDmcWZRZJWIknHlqjDKFDKNnwrfnEI9qWyMDno+jA/DEQz0mnpdZYEsoz1/qAmAeDt89vx',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009',
+ currentVersion: '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3',
+ versions: {
+ '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3': {
+ header: '####',
+ data: '.....',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ }
+ }
+ },
+/* 02 */ '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ },
+/* 03 */ '36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113': {
+ data: 'B7RNc32W4K53PWYWQ4aUkqSLV2O4bwExYXVPFT+50MHxrhYt4/yh2idYXAooF1ImaIlvyUsIbI4EnIoBQ33ed2wxuSA9HVC4+wTrE05EfjYOw66yJO6R6TbIazOs0Fob5PJCFEW6evmb6WWf5KsHwifOo+ACMHK799yZ1dxfaIEjRBmLCtnc8sTNvo8i6McAf7WCffA1vXbyVPEhxJjmrfIDqvkWsNR7jDV5xIA021WicOS0FxOnzU3FecU7EF/UPcYjTKfe8IKw4nDXSKIIgXqCdzNYsyZkw2OnMDVJoSwNdfiog3H4zFy2m9KZqPjwnHHj5BE8rdx0JuZoSnTFLR05p4KdWfOU4BrjehAWXZdudYqsovtDm9uMLgUfx4DV/JKVmGAZ49GWM1Tx7pY5PBbJRTO3674FGWYHTPEMiIpDk+zt1sYIR2YBbJTq4fFOIPsgmOfvYdTkSvdHLk0fbxoK12w+atgmXAiNgE6T7DlYT0IMZlEesw0Spchxoo7lTBUPXC93bl/JugyhoRLUof4dxFvsIvd18Gnop+h7aCVW1S3lqZ36TG/N+hlM4U54FkpHjJi2fN8M8EKF0N8n399m58RNfsX2FriUVHozdb5gpgUXnQnVaAUrtv177lz0sRO+9KqbhJ16dCDzMFLcarBvXGqWkj+ZfkpNIaoyl8KTeHTQTbSS2IwLTvs69fbMW6Mub3VD81CXyY3MXyF4hT0U3CFVD4jQg+xODNnqqrkl/LebWy/XP/HOoNTxjygEu1JcS7zCptRagNoucXVkWinyKGjR9fSEltsrXG2pm4w2qsovRB3vfYp7kx2m5I9qc11K+JKhgPUmpm0S4BnPdfpRMXq0w8kxu08Mwm1Debhrzrgjw1/s1ZtcpoFgJv4EWLboWbo+CKWYdq0AGl+b5UHREPnGOM9o9bOg3uvaOEKZyMq8wxECBjdas4wjRbMY83PcBfzCbOU+POrcbalmtwn4/ILkHPsUcaOHYcnKwkxSYIDRxQc69mHw1+vilSHUQ5dZYSWIRvV3yPe9eqZPWJsWrOyhPLCf18BoNdfbgHFL7b2KN9xLMz0tdHxVozH2TnwAavcNqAE0hVIgtyEDoT4rI7FVMSu5mCIN2KOxgXB8XREZokT1BQ8+rz6JraS3JYQNz+7Bd6iB6OaTStsFoaBkj50MszNdwhRViOCCUk4bUr45XRtyh4ZEXj/I4pyJUkhR5H8/qKKD',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ },
+/* 04 */ '507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a': {
+ data: 'ncSFmp/+n1pYUKi2fwhMCevSwFYO5irdcpOlSxC6YPOKYavK4iUbtBsilYWd0hpvUHW2ItaDwiyNFxs2Lwegex6dawKrpMYkPBcaZQDa746yACGgCkhz4MAGnUn5HCmz6xhpCVXMMKe3w2nEOjRB+pOMOeJt2n7aw0hCJ9tQ9JTFNrZOxeXrqoexrd210Rmr9FnKhLIvhNTN1/vXRqP0ys10omJ2mowzF4KoEVmz3ET6pS2d7tGjt9M/OYsH/ETWWc92doF5PO84g5/3HePaCo8NCqq4ul7AWJEbdnkxxmd7urJzIscPQPcoLxL7GfG5LhHTFyHlfFz9dNlccfA+OPftjyfjXTjLYZzbxxbi/nAB9Esqj5AoHfqaJM1ZOrZ+qAvm8Am3+HAXrqtiybDITrCLmGH9ukWDsx7R3lYTlvjArwORBUH+4w4/uYGscVm9kOYj/Rmz/ZMH9JibYFcPcOnr3rWXPFUL/XsXTrm9lzOvPyEYJmkENzd54AHC4Lr5vHpeuipWFLiJOrtn2WcgDG/DdLaYGKsmISXj74XDtP6Ee5lKOtbwwcmVNrl11UCQBEFHNybhXvpil5laKddOauLJDKtaDL/mKYPbr5YSk7HPCzRyE7HM2dC1MpBHuJ8g+hDkgU3wQcxYduKLRpuC0uOqrODigGWhVrdiKdZanlWUq9EkE3eH+E2A/CA8mHl7UNaH89XSvgV7uZyOmK7iZ+1kd9OzhBLQdJnK9qqP467Y14KsTt1E1+tqlqVAuK79QMnllaR0e3ztBRAQsyf5SD0KuSGXWz+z9/RjbhamW1s0UFRGh3voQMypU5RcYfYUA5KVg0BiVKFaiZBZKLo213hKbrgE2KoqVDEmIBFmwsu/S3EDzUY22tTB+o8ZKQiYesAUafGtnvsOLa+h6weF1ZvQVBerbD3fhb2o+d4ZyPkoRAsop+5it0QxsWuZL+J2oWybaikxIP/1ZM2ow4QZLaAVqihyHxqhF5UxZ9zrWxfp34BIPzzU9esSifrD0gXZ3mwutaCukZoijnGODJZtFOy9Rl1gyS1IbpyRbwz5O/YRl4BsD2aOk4InajT13Sa1BLPblQcrau13aeg/IzQhcUJ6n7enkrqiJFTP8N1aFAuYv8ilu0V2ymIuCLUtc4cbo7KyA+gnHhZA+DjjrhG/izOyWtQY/WtDsqvo/6ILwFk37JDjHfkchPEVcdl9qT7goG/4zTGX+lx8UTKKZJjJhLjA',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ },
+/* 05 */ '6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728': {
+ data: '3oUg1TD+Lu4ou06j/MddOTXDqRM+qSKD+6Iuzia1Hop1w7v/BXidqeoKJZQI2VY9oO9B70Nr3B3wDROF+ycy6Rq+FM/xqUGHKXn1lAaSc6Wgj6TLQ6eRF6YZKSPqTj7TDWyw/2pEWk4HjcT8drTrCaC02tzAXMhYWlYPQPW4fUdq4hawoHIdopUN3vafQuFjY47OhqXKav3bNao=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ },
+/* 06 */ '6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a': {
+ data: 'b2mcYUi59l434kGl7ij6dBu3063UL1dToMIu3Zsa9RV9RzeLKnezJhLKunqoAm7KwiJeqDo/REexHI1cshGYtHasVXXuyJfMx1grH7yhoWnkSRF4Sax6w5E5wnGkEpGJHOxXJ9rOjWHZ7yqCUUCB/dqLw4FwPOtRb/ynkBEYztEJA6EKGJuz0vrrTOsT8HMXtj/w6MEZ7qI3fPs=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ },
+/* 07 */ '6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18': {
+ data: 'jzjPgxRHApIJA/6hiY4XCtb5+eKzHlOeoiGwfVDvip95zU7ThHbdmxOUomeyCOZ3S1SGPT4lHvqZgfVG5m5RvH3JaAIa8EY1ZElRohoX3rETVPJzI/Ov5Rp3lZjtWlu5meNrcJz811HBHrtBuJxAmSjYcY3CCal+oC2zcK2fLZR/iOQ+69ONVFhdV9KiOqzNf8IisIa1sIgFopqsdHXiZ9oLe0a7Y56q+OplyU3A+TmxKLI+Qq+WkjvdMzZDDqzYH47me5niugYPdkQwN6WQUE0sK9QPs0uU4TOwqCwN9nPH/DoQ6oXWAu2+R4iCyt6ZjLNkClbps4s8Cwz6wfFQ+4T8bcldjveJenmrYwiUzxSd/4xa34yFVXVw2OD0n8yZhtvNFvfoPy+X9z+Y4f5HlM0qzL9zYya4KwWjFQzhOxFjni9JyGM2PJ1BctB+q1J+CHuhlVjUF0Y5zIS3zFTET8jjDGBZDWB+Ao9E8fUD+0OJJUdKJ4kUfn4ZUZUG20eLBjmJqWBGYZX7UFaPv8ksahoK26Ol6FnBE4KpPStQeDgXZDzGsiLlEsxHJLUFkNtAUXozw38bWWQvi2VIFtkw/ZViPIenmSNT14kUVWdrlKQC8x0+wECeh5ffv0i8UUw3v8QC2ZE7GV0OMl4ySlRCuDCfZ53YFoB3HIR1hSZMhHlHJDPUz8JOuXdHcUQaJeNrfWoC2KkKb0ZecBj9iXooDh9yGi0g7TS7eyhlz1LHpzEWB0CPsZqhNGMxmfFWur7v2hrYzoHQOeB19ZSmWzfUwd4dRpqMp0x1lZaF97jr+yyYhnuQvuO6lru15Pg6FqjzhsNiLtaqtyoaMiHZ9veZs04qZZ9Fn3U7HeJzjZSAssdLnvopXi363cXm9JqoClyV2OemnVoRwOZN2gdSZxGeOefKR7U+lrBAbJwViMnmT0Nd7AC8C1k34iEt8HJmpztXeOgX5CQpwUPENMCUPsookFbIh7e4aByllEQy0gBbxUz8JMIWYyw98hdASnZ4s8bQfSmiMM8Iw3YxCexKB62LYYJn1UY51NSnwCtwRep+NhaKDk2d6SLh9owxnFbjhw22RriPd5f1InJycjtpvMzWLavl/hDsjjj1kWpnCUBTM46LbERmjz+s4x7fSf2FhhguBT36elz69ivXoiXI+7p0E8f8HsSwm8sgN/AA5m1svsXsdWeZFUiWtAwLg0tI8YNHlazbvFCXfIC6Uhq9eDv04iqdZ3rn2c1rwSx336A7ySTBFdxOCJ46F7ShIhNKm2N+5Qf0K5B2L882fbwqiLsa64+X9aKvufKTsd11vyf19Zivg/Ze0FWoGC8D63Nh91k6Hu32RT+uAtJIjQIZxu9yXJM9lMaRA8ieER+ghrLHaGQqF9J3WmueER3UzU1midvTynOV6g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ },
+/* 08 */ '9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291': {
+ data: 'xXZUJjgxn62OqnzAvScHJNo4WjYEFp1vQ4ueBe1sk8dH4pXZUKV6m9c1d2cLUgBj4rUNP5cC66GiFHV7G5BDZGLrfrxUlYU6BWvzAz4eG463pRDhHXQgPrhlIGDlK6ovaIsjwaifvHaEfLREoXvLFluqu406KG58guhtWdIFK0rLypyRo8uyltGbTz8wZdu8atY/JYQnb8NaAf4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ },
+/* 09 */ 'ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c': {
+ data: 'YXBq1ZlFhoosb2Krnk0Tk8+LKyecTeZ3UdJujrryEgvMnhGJvSVVtN3uph9gts10Kw+tF5wvdAtBFdMUpvcP3mOlbnX7+HCz+JsJcLLVvuGBU9ciwok5kRKQuvWffmP7qFLuqO2VJUj2ozjcpVssStZOrfDXWrJwYfkd9IMnOJVmCwjFeXpPlkOeHNyhjPlfZhWWlTga6xLdEXaVeZyjDegzhlhh9U3e1CLupLTwdxXtNCPRXp8gU7e/I9HP/qdnj5BzgDxaKx29v/AUcgOt3jq5oWwePXZL9nVOp6rh/UqduM88tyxEbnBQxcGj9KxTVsIh6ywzQZgnPtfrPaqX4Fvb1P9cGN80/F+/JXVgL3fvrcxJDGxZj6VYFTA+cHM6sV+F4/7wMLUVlCcn78BB6/k3DC4mYUv+8LSxfZf22bWCcSyubPTRhmCm2/sgdOloDUKT4AjfZivlpJjkYNDtNmZn/rUpMr3uLiHeWDDNB+eGqk3lAFhihBPXqDJ3o+8c9jrznedMxQPkgYD0V9ryDauY2RYjQIhmXqQlnGxpGOO2lFDGYtkwsBplPy6LDkudzJVAqp5trBR8Ty87k65hbhinGCra/DgPqIxjaN5pvZbXkOLoaIoLnE9RRGdAwfUTMIg/maNRoDKaHO0hJ3ksCflu71H9tzPjGM7BBjWjQgUvwDJOgnEPyZv+noOiHfNIq3u8CfI8e867gnEbdtd3oPYex1aBYIQ1ELAxI8szUtSeMDHOouXrZKwy04xVdC90KHnVWl49scE2QfgqV4hqzFjtuQgZOqQ50bI+duWDm7YYTwKVlo5QKy40faW6dPIfDPRsxY6M3gcL2OPBm+WMopUC/o/AFSpxPaut1DOr3mXBip0Ejam9xmJhMOUwIJDoE2U+8S2s+UJjRunLb680vqbddF24aWxpLL1Fg+hlRZ/Jz1ZajonH9ktQhoQaTl+w/4uHhMZjKH7/FaRqge2WMMwVjOd7VXNByBPia6W7VbmDk8LFCeCsC1DchcDaMj/JmoGXucqzDO/sOIby2YCBsV72ReqTNtu6SLZe4G61DWA7j+6NiOSmAutYox6VsoRsKaJYkyBgmq5hWDZmWOJ/cC1pQa9EMoXzcaEPicmXx5YE4xF15VWpI8cKTM/StLtLcqTs78Z0fQAicz8YhhNdVCGp/zcjJRPyL6XCDhpvMxcIOnU7',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ },
+/* 10 */ 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ },
+/* 11 */ 'd620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045': {
+ data: 'Ate/x8b4UWG3C+gZ7IzIfZrHSlh3eSANVYtd034pXi4V73+rc5OynELEiMxDgvcr+4r5YGNPKvTB83KzOBznmZsEJhNpCd2Ezyk1i3FEo+Wur/6EYBBvDfHSQNrRfYVcNlx6+i1d6a6lDYxOcxfEPuL2141KsCRxCId4FWvDU1Om48ekFNyeOl5ND+k4GLymYIjG7HC6VQZOwUQgzlTfZpjeJ1q3pdPWSEtX8a0b5pgmHVB9X56u+vjfYFcs2ieh3UcR4Vg8fIJQOth/pE2XoZfbALyT3pnEcW8vQrrmFcavt9bDGGzlEkGB9JEIyMzUqVndV9Sw5OsCMgOEpMKvELRnlyieUvcsYSL1s/m8GohguMrXDiRV/nCUhZbH/j/8jXEX4kfiaIT5uvPBymTyMTGGLoPBT7mOWLuV6NoU6ND0QwSEXNMpZDJDBhl37hR4kD3GgjCv9gjasADAmHPZF386LNxnOIMTfrOIwK3sXkfhEU9EKdC+QT+W85o6HQrWXsqNesxU2cs2uW7rmadUBoQdyYTtWH3cBWcwKH56vzlOG33JG1+DGH6MFEd4vn1I0aoluPuBom9ERgLXEoqw1tx4OAx8UCcev8dnZF1YcGhcUXyORjgjd6CTfMDz+f5YMkulGwPRcm1D7uof0a2ryV6+c5WuccUX+Pe/Vj3WOQXts7pdukLp+idnlpdSw4roJWU++1i7727MIWGUFcKMH6qyH2yZ1nxLNour/u6FYlxRvNkB+vCr+hko7iBlTw2GMVWUMgnFS0A+lQ1tGawAM9h8lpb75GCbiWNXdnbTx/GdQzKMJJXKGpOeuWOXlJSEJHjWzVwbP21ql1OaFLr9ihUJdLzSsjICW7pGH/iuhuIlx84N57ctV2BTAYJtPLG+f3rv709lOD/5pgdXTLijjX473Ymq0TgGBSI9am0Pwz7SB2k1LVkBVfAVxR6p8Vb0h3S1LUojoJS5dfGV7TtTu67CemoRNISdOVL9kxCoue1QMsd7GTnY3sy/P4eFHovCtU0suUYjHRojUz5B6xPlL92Jbdtq6fGv+V+p/HnKFXkf3BgPnSm2zexCAEgT8yuJ86UIIWIEhYN1UtzJVJ6BykCCGbZrCSEHyfCcRLreYYpNcMPWpLOLTMFpLiHtW6+x6/tVB07K2NDpYZUY4Ekym4bRrLUXtDjjcltL8qUPQf/uBU6tfpGrdZB5OAWnsxzR0x+4ycyz84Pq81NMUVKnvhUWrygtatZhFYhNWYCz4NRfqwnwSRQxTr/2NliO22BhGc6fjZWdXdqmyw1+UXVp692nsV2FCldz8+k6LMA0AKBuQXcK5v4mYQOWmSKlH/CpkPkOEIPrQVmgjMv1/qWaEIvRJUYpPsnFUD5a12NlBBxBvHpcXemHZZvdgnBnOyAjIbhxCAsQnw2Rc6SzF1z4yviZ8PSeh5+zavbI9rgO3UtsPBO+R+5kky3KxtnLSV9m6m6Lb1QmpwDKQ2ddTDXFLBasyE0WdrCDBTDpCLDRsLWdODzyeCH0yWx8tfKfKRI5dzBQz4xJ9swkC3LAr7XubkCw8RMzCUAC/WKMRIsoyXMP2Il38fSG1aO6kKyUvY6ai8a8IDx3Do5TQMgS53N4tQNls8ZcglYDydcXhxsH7ztEjis/2omJbwadtTRYv7fu5jbZAC21XcGhfbgPp8h3Zal0SwuN6s+Uyz8LSwnZgrN0N6d2cNE39628kZkAwI7piZG7VV0XocrGnIu+6oe0QmJsxiAMvaheh0K9Dkf98rS2OF3LDwosaSzxUBD06BD1C2BkleM9',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ },
+/* 12 */ 'de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4': {
+ data: 'ZYvHAVCnw96hB+0XxnBY6p+vwvup1BopHUeepu7yOOSdYNFFOFEvtCbxXXoyVaKZAeSd2Vd7YEwRP4TTJjjWNPapT0D65AFqM8x+0rEjhmVfQGZAS4L3QctzRAgBoR1qTr0iqI/46ETkNq6vHz9mPLHEL3MQ/zoh4Pp0T+uMsY5ptzuMPcG0YwajSm5J8XXV2V5ZBEANpgL91xjgh1I9LiKJa/Lv3R9HAZG1uuCvzqjA2LWYeH+6ZcSpadk/UPxDw9c78FUnSNbHAcjuYZ/yI3v5SaZTjEzsB1MtAh6AFiHtvKIMWpqoOs7XQPhz1xXPoGZ7VR64A+/bN2h+Uqn49bQrKjTRGegqkEWFcBwhFH/ZkYfSHCGmZQTVqOakqyofJ22tS0ief45gYaO54YvIliTNTY7SZMRCEhUzz6dz8ENqP7FxhUVcQRbBr0JTmaf6DAwu86iDgkvcp1cY2trnUmlvrgz2GW6TgXoFjFlchUkHIByFeIJ02olfJg4zP8PzgYp2zhwmXL8iXHXnwzuP9bQKq5j8o+UhR11zn4MFvWQyD1UEplK6vphMdS8iXDViLrOwuMz1XUf7RxNdW0gqXwx+qLU+CeypyWLMIlgTlOr1pBqD/S5Jx+Gbn5GHQViuFZHJUjJsU0xel001KjB2Wf1Y15OSdLZ5l0tn/4HYKmZLufTYpub0xrss5r3Z72RYz3wvAWFXzkxWa+oBiRQiF6+ix8DBPTc3tm+ORnQBYcV/VNVRziimV3MFSsD1nHgIF1zu+eXIKE7/b3lzY19KpvtiBio94dejWoA/WO7KXWv2sHH0JoZnRh6lzu0HRFgYqVm/052nCGVA6XSfrFtfIupxdBs22C9wrwC5/Rwanf1S8BQIXpm25P4dv9Y9cS6c2/DUHcle4tsUJlqC+LpRGKXRdolFkiL9r01V09Kev/K2oXaWGYmBLbRfIyvEHyHNeNXv5fnaZ3pTlIwXjJ9K9yKA/1AKAsAEuKlM3N5ep9pfyuyfOWj1I6RvBwVqKvcBZtYJ4u8n9jrxiyq3ZZ35eB62D+ceOAD2s5+LL2IylYjiJA1OO2qpu4x9rt1NHXM6LYJAruBnUrJ0Ylqz/ElcJn/lXAzY6RLqVcZ+tuV580AUkFiaXFEDcqdJbbzh0R15g9DtaeiQZd1PG0a8Xblj9aMQoRDRJeksw1GWO7TfrJX1Cu4k+sgARWRzZ0DvB0SJAxPcmhg2iBByn2ESlcxPvMOpzuJI11BUQsZZ7dcynubeMvdqBeKsC6HMcm+8DLEUPmzsC3HIfARlNbt1fOrGJNuKaLvF1AAdwllELoPf3lQ6EVZI120=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ },
+/* 13 */ 'eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ },
+/* 14 */ 'f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732': {
+ data: '3sIazRfi2ps3Mh69YkIYFFyDRXU8cTRuBjCevCJHyJOfxLPOcJfUX+QuWv50QMRchAG1RYTwqTOFd4G4ixzmt9HjHlJSpFXva8TvNfUaoggUWWTzNraRxB0gJex3JGfQd4Nlve+wdISrn5vUJSWBYcFEFo9504TcDAkVjwFYrLhBDFv53d3B5WuanLzpRuB8lIj5r5ZBYszraRDeSjEKQ0OtTojxnkZOB7dDi2IYdorhxhOeBmi3ucAXeDLZbaZdPAXmo6CNEYxAr0z9/aCrvLxZEfNoBvBMOnHT20wljSGsjf6QG/KEm352ix/uGSrJNbRMMX9tVloeSmEkwxkAn4ZQwIVq/0IS970MkL+jOH/RFhO6UT6x5OPo+Yyf3EKmRWKKeZbv95C5WNRcfLjeNVo5Zihq4fAUEfwHtNTaEEpLoUdCbzgZqBKcbLk8jo44lznz41T4R9QM5ofRAexywqVlEzagztakcrgyAMGumqquuKscJmqxEyxZLwNWD706DCUkiG2a1m/umxNvVkCNE6VBxbZ1+SPrcsRVfdtAx3eee056xo+KYKLdf84j3DR27H/p3QYm25sdLhUU0QtUTDTP2aKUxEcsLy5MIZV7256AlRS23upmvtb+VfJCsT+FwedLNCzu4SEk8Iz5AHFJ2VZ0g/2A7DH7DiuaxSqEn6iSqVZRnTrhWsW/lTZ61Swji+wvzk+5RnY8wBFZeudUX6ERy9n0e4n8EkGXCObwSnyIe+Dxs32MQFXb7b6NUJEfbq4GxHUjJ6fzRuTqQysRKlQ+qj9Hl5+HvGhyliDpe+PQ3V6kFE52qVArAYzlR2sZJmxKPIgU6wPPuCMcg+97own4gSO6PWrnlSZs87ptZdZ1iiYPDajQjyLI9WV/IN3APbiRufdEjjmCkoxB1zwSHzyW50Wdl1pEW19/0j+KSFDeigXXVg0LAko4uuJIPTLR8L8gOrcNZvIqHB85XnsbO49+SUwcykXSlZSq3il7D/9FuGJK0ecKdEMf/UetsSaX7x3L92fzSIjqgFSHrCPrqLVWdI5Sema4vhx3aes+hF9oohC9jqb6vS/b/vXfVf2vs2hPelqk7UIRzPmaeapzF0RyjGoAljBIrPFmyAmXcpQ/NlJSI7UjMjoFWsOXshJiy+0/luVkzfoFSordVm2ZhR9zkVKKDHlrFXXkw1upVnf1xFV9Z4SEVAZKgWRr2vLbmD5tITmR7qxzNTXrikqujVvOeFCHkAW1c5IcOk/VjPO36CNL2EZbpRHc6z25gST8NYn+Ypee6FGliHGFbzJxTwHa67fRncf9H1Iunzl+x3J3/0973z5fILk4OtMq3MKUFjdj2r+hqwU893+Yaza7l06Jm+dODTXhPA0T+JL4gaWHE4Ci9SsX85uvpZR++Tfx3CB7uXvOKGATmVYkAMndNCOBCbHz1/zz/Fg4Awu4aAPap/DqWsoVXajuYBSBNpaxpFWeioX65PPEPgn+HHmtjn2c647vwdv3iBopTJJlipoW94vkTJe4tpO1e7DA5EPnzdxJoRyXGbipfCRlfblcurQP+hXZHobfqmzMuyEPp4t7b5oiYpwzNnM4/sh9NxTpj/a4urjnIwg8yzLNvdletAuME0oQu4DkcWpPKhyDpelAPtdhDka2YID/WhUfg+gHKpIjKU271eoUwhScCcW1cBY41htaSNftJq96r77piMYo6EAAuf4X++MIT5LiwsYs/qzjOrmQm5pdSeAmR9f1fkqsIAv/TDhgAgIC0zAmvUJfkxIEHOMn4y5i5qZqlDS/Nvd/ZWl0lMjPSJaxd1pm3echWZ8/+gPKMib5sSO2eYYOMq/DR6k2ILThbHJp1G6gqcyD/LymNO7BrCIDfGEgp+fCBFXYBjC6+Otkukcvxs1uJsirwWbYLaoC25iYChdhwmoOys8=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ },
+/* 15 */ 'fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6': {
+ data: '4zgqvaaWm7nJO09LKN6o5hbWwGzOv7VVmXDu5T+JCHTSOXbteogax2Zrv0uKLkfooGFThJBk0rXfXxE64vMOq3AeHXGw7Chg7hz8Z2Lpjr4FfE6q7Em7UuAlAuL1PiyXXJJK5iSsRY9tkizuYl19aXW+CgpPznYD/PyXgeYxqt9WLqK8cl5iAU87R0cQDhwl16ivzVgiiFeaB6B5FQqWBAHCEgXhqTsaw2gv4snbmPOqcUZbHy/Vb9hv4lPBJwGFNxQzeZUad92VBC8YbIjmbohDsXjteqD2/k1qOgpUB/U5BpyVwsi+5ahgb8gbS+AqYoRDYzkaj83ksPI4JzWyZhpqjhDauaI6M7hGnJ4GB8UZc0M3WPgrlf1r+TXCgpcfembqL1MyteM+C+ItPRP/QdaIXxLOmvGFOBKQYEI7UceUWBCSEzORlS2S2lltlqt+K4B8QTULiKaXCfRmF/u60FpJufIkUX0pE/rQVChxswSWvh7uJFDBIDx8MplTX724A7DN5d4/Ad4Yi2cj3V8X/DEErnHTvirP3tZ2F2oAe7kIdu+JuCqKcMaGB4hVijzv+yim2TCPvrGTFaMmg9PvcWHpik9jEIabCkdqAR8EGIkD29+yvG4vD0DTRKv2vPIfr60ZQnsgs8nlPPoNa6lNHvI/EO0nBGBYBc1TW+syV5h/zOG3rHX0XCHhISZmDMjra7eUETWChncR88P7ciC4yJQtzXFGzeXp2ktzZ8m5g1EQfgtlUVZsHN8e4OQ9DjKt0unfq5RFBj2jlG8TBZn6ZpebxWR2qOxp81KQLHJND9zRTy3h65+k5wo3MnnxE3GbeXg2dFIORRvGUT6bWsqW1fqR/pg1GO8KNtrt3CryZofgE52kuk6hlcmSk9974JR5523+1/hbts8n5VrTi1C6GWhnxpiJb1XIvICdag5g7C2iYppzLKVzbJcFMegwDUrapbmGhkqnGwSY1EQSDyagPr2xlziWhdWdCOVAYcyw8dOpdD97QhVef0OWrJ8nbgFKD6wn21475OFxooheWiMCyZwXqESVG1cVCjeaCsymBtEVPpmQdSkOfMdXpKVF+3osb4K2XDpPeU1zPWVozeMp68YhLztQ/g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ }
+ }
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': ""
+});
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.html b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.html
new file mode 100644
index 0000000..f77bcb6
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.html
@@ -0,0 +1,106 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.DataModel.User - test</title>
+
+ <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Toll.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js'></script>
+
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/Date.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/DirectLoginFormValue.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script>
+ <script type='text/javascript' src='../../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script>
+
+ <script type="text/javascript" src="../../../../SimpleTest/SimpleTest.Async.js"></script>
+<script>
+ Clipperz_IEisBroken = false;
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+Clipperz_normalizedNewLine = '\x0d\x0a';
+</script><![endif]-->
+
+</head>
+<body>
+
+<pre id="test">
+<script>
+ Clipperz.PM.Strings.Languages.setSelectedLanguage('en-us');
+</script>
+<script type="text/javascript" src="User.data.js"></script>
+<script type="text/javascript" src="User.data.old.js"></script>
+<script type="text/javascript" src="User.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.test.js b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.test.js
new file mode 100644
index 0000000..4e7a21f
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/User.test.js
@@ -0,0 +1,2082 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+
+ 'invertIndex_test': function (someTestArgs) {
+ var testIndex;
+ var invertedIndex;
+
+ testIndex = {
+ 'key1': 'value1',
+ 'key2': 'value2',
+ 'key3': 'value3',
+ 'key4': 'value4',
+ 'key5': 'value5'
+ };
+
+ invertedIndex = Clipperz.PM.DataModel.User.Header.RecordIndex.invertIndex(testIndex);
+
+ SimpleTest.is(MochiKit.Base.keys(invertedIndex).length, MochiKit.Base.keys(testIndex).length, "the inverted index has the same number of elements as the original index");
+ SimpleTest.is(invertedIndex['value1'], 'key1', "the first element has been correctly inverted");
+ SimpleTest.is(invertedIndex['value2'], 'key2', "the second element has been correctly inverted");
+ SimpleTest.is(invertedIndex['value3'], 'key3', "the third element has been correctly inverted");
+ SimpleTest.is(invertedIndex['value4'], 'key4', "the forth element has been correctly inverted");
+ SimpleTest.is(invertedIndex['value5'], 'key5', "the fifth element has been correctly inverted");
+ return MochiKit.Async.succeed('done');
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'joe_clipperz_offline_copy_test': function(someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("joe_clipperz_offline_copy_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ is(someRecords.length, 20, "joe_clipperz_offline_copy_test - joe has 20 records");
+ });
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.methodcaller('label'));
+ deferredResult.addCallback(Clipperz.Async.collectAll);
+ deferredResult.addCallback(MochiKit.Base.methodcaller('sort'));
+ deferredResult.addCallback(function (someSortedLabels) {
+ SimpleTest.is(someSortedLabels.length, 20, "We got all the labels");
+ SimpleTest.is(someSortedLabels[0], "Amazon.com", "The first label is correct");
+ SimpleTest.is(someSortedLabels[1], "American Airlines", "The second label is correct");
+ SimpleTest.is(someSortedLabels[2], "Bloglines", "The third label is correct");
+ SimpleTest.is(someSortedLabels[3], "Digg", "The fourth label is correct");
+ SimpleTest.is(someSortedLabels[4], "Example Attack", "The fifth label is correct");
+ SimpleTest.is(someSortedLabels[5], "Expedia.com", "The sixth label is correct");
+ SimpleTest.is(someSortedLabels[6], "Google Account", "The seventh label is correct");
+ SimpleTest.is(someSortedLabels[7], "Home burglar alarm", "The eighth label is correct");
+ SimpleTest.is(someSortedLabels[8], "Jaiku", "The ninth label is correct");
+ SimpleTest.is(someSortedLabels[9], "LinkedIn", "The 10th label is correct");
+ SimpleTest.is(someSortedLabels[10], "Lufthansa", "The 11th label is correct");
+ SimpleTest.is(someSortedLabels[11], "Microsoft Office CD Key", "The 12th label is correct");
+ SimpleTest.is(someSortedLabels[12], "MyBlogLog", "The 13th label is correct");
+ SimpleTest.is(someSortedLabels[13], "MySpace", "The 14th label is correct");
+ SimpleTest.is(someSortedLabels[14], "SAP - Login", "The 15th label is correct");
+ SimpleTest.is(someSortedLabels[15], "The New York Times", "The 16th label is correct");
+ SimpleTest.is(someSortedLabels[16], "Web password", "The 17th label is correct");
+ SimpleTest.is(someSortedLabels[17], "Web password", "The 18th label is correct");
+ SimpleTest.is(someSortedLabels[18], "Yahoo! Account", "The 19th label is correct");
+ SimpleTest.is(someSortedLabels[19], "del.icio.us", "The 20th label is correct");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'joe_clipperz_offline_copy_getDirectLogins_test': function(someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("joe_clipperz_offline_copy_getDirectLogins_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addMethod(user, 'getDirectLogins');
+ deferredResult.addCallback(function (someDirectLogins) {
+ SimpleTest.is(someDirectLogins.length, 22, "joe has 22 direct logins");
+ });
+
+ deferredResult.addMethod(user, 'getDirectLogins');
+ deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.methodcaller('label'));
+ deferredResult.addCallback(Clipperz.Async.collectAll);
+ deferredResult.addCallback(MochiKit.Base.methodcaller('sort'));
+ deferredResult.addCallback(function (someSortedLabels) {
+ SimpleTest.is(someSortedLabels.length, 22, "We got all the labels");
+ SimpleTest.is(someSortedLabels[0], "Amazon.com", "The first label is correct");
+ SimpleTest.is(someSortedLabels[1], "American Airlines", "The second label is correct");
+ SimpleTest.is(someSortedLabels[2], "Bloglines", "The third label is correct");
+ SimpleTest.is(someSortedLabels[3], "Digg", "The fourth label is correct");
+ SimpleTest.is(someSortedLabels[4], "Example Attack", "The 5th label is correct");
+ SimpleTest.is(someSortedLabels[5], "Expedia.com", "The 6th label is correct");
+ SimpleTest.is(someSortedLabels[6], "Flickr", "The 7th label is correct");
+ SimpleTest.is(someSortedLabels[7], "Google Account", "The 8th label is correct");
+ SimpleTest.is(someSortedLabels[8], "Google Calendar", "The 9th label is correct");
+ SimpleTest.is(someSortedLabels[9], "Google Docs", "The 10th label is correct");
+ SimpleTest.is(someSortedLabels[10], "Google Mail", "The 11th label is correct");
+ SimpleTest.is(someSortedLabels[11], "Jaiku", "The 12th label is correct");
+ SimpleTest.is(someSortedLabels[12], "LinkedIn", "The 13th label is correct");
+ SimpleTest.is(someSortedLabels[13], "Lufthansa", "The 14th label is correct");
+ SimpleTest.is(someSortedLabels[14], "My Yahoo!", "The 15th label is correct");
+ SimpleTest.is(someSortedLabels[15], "MyBlogLog", "The 16th label is correct");
+ SimpleTest.is(someSortedLabels[16], "MySpace", "The 17th label is correct");
+ SimpleTest.is(someSortedLabels[17], "SAP - Login", "The 18th label is correct");
+ SimpleTest.is(someSortedLabels[18], "SAP - Login", "The 19th label is correct");
+ SimpleTest.is(someSortedLabels[19], "The New York Times", "The 20th label is correct");
+ SimpleTest.is(someSortedLabels[20], "Yahoo! Groups", "The 21st label is correct");
+ SimpleTest.is(someSortedLabels[21], "Yahoo! Mail", "The 22nd label is correct");
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getCredentials_test': function (someTestArgs) {
+ var deferredResult;
+ var user;
+
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("getCredentials_test", someTestArgs);
+ deferredResult.addMethod(user, 'getCredentials');
+ deferredResult.addCallback(function(aResult) {
+ SimpleTest.is(aResult.username, 'joe', "the username of the credentaials is correct");
+ SimpleTest.is(aResult.password, 'clipperz', "the password of the credentaials is correct");
+ })
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'loginWithOfflineData_test': function (someTestArgs) {
+ var deferredResult;
+ var user;
+ var proxy;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("loginWithOfflineData_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addCallback(function(aResult) {
+ SimpleTest.is(aResult.result, 'done', "successfully logged in");
+ })
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getRecords_fromOfflineData_OLD_test': function (someTestArgs) {
+ var deferredResult;
+ var user;
+ var proxy;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("getRecords_fromOfflineData_OLD_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['OLD_joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addCallback(function(aResult) {
+ SimpleTest.is(aResult.result, 'done', "successfully logged in");
+ });
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(function(someRecords) {
+ SimpleTest.is(someRecords.length, 15, "the OLD test user has just 15 records");
+ });
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.methodcaller('label'));
+ deferredResult.addCallback(Clipperz.Async.collectAll);
+ deferredResult.addCallback(MochiKit.Base.methodcaller('sort'));
+ deferredResult.addCallback(function (someSortedLabels) {
+ SimpleTest.is(someSortedLabels.length, 15, "We got all the labels");
+ SimpleTest.is(someSortedLabels[0], "Amazon.com", "The first label is correct");
+ SimpleTest.is(someSortedLabels[1], "American Airlines", "The second label is correct");
+ SimpleTest.is(someSortedLabels[2], "Bloglines", "The third label is correct");
+ SimpleTest.is(someSortedLabels[3], "Digg", "The fourth label is correct");
+ SimpleTest.is(someSortedLabels[4], "Expedia.com", "The fifth label is correct");
+ SimpleTest.is(someSortedLabels[5], "Google Account", "The sixth label is correct");
+ SimpleTest.is(someSortedLabels[6], "Home burglar alarm","The seventh label is correct");
+ });
+/*
+*/
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getDirectLogins_fromOfflineData_OLD_test': function (someTestArgs) {
+ var deferredResult;
+ var user;
+ var proxy;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("getRecords_fromOfflineData_OLD_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['OLD_joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addCallback(function(aResult) {
+ SimpleTest.is(aResult.result, 'done', "successfully logged in");
+ });
+ deferredResult.addMethod(user, 'getDirectLogins');
+ deferredResult.addCallback(function(someDirectLogins) {
+ SimpleTest.is(someDirectLogins.length, 17, "the OLD test user has 17 direct logins");
+ });
+ deferredResult.addMethod(user, 'getDirectLogins');
+ deferredResult.addCallback(MochiKit.Base.map, MochiKit.Base.methodcaller('label'));
+ deferredResult.addCallback(Clipperz.Async.collectAll);
+ deferredResult.addCallback(MochiKit.Base.methodcaller('sort'));
+ deferredResult.addCallback(function (someSortedLabels) {
+ SimpleTest.is(someSortedLabels.length, 17, "We got all the labels");
+ SimpleTest.is(someSortedLabels[0], "Amazon.com", "The first label is correct");
+ SimpleTest.is(someSortedLabels[1], "American Airlines", "The second label is correct");
+ SimpleTest.is(someSortedLabels[2], "Bloglines", "The third label is correct");
+ SimpleTest.is(someSortedLabels[3], "Digg", "The fourth label is correct");
+ SimpleTest.is(someSortedLabels[4], "Expedia.com", "The fifth label is correct");
+ SimpleTest.is(someSortedLabels[5], "Flickr", "The sixth label is correct");
+ SimpleTest.is(someSortedLabels[6], "Google Calendar", "The seventh label is correct");
+ SimpleTest.is(someSortedLabels[7], "Google Docs", "The 8th label is correct");
+ SimpleTest.is(someSortedLabels[8], "Google Mail", "The 9th label is correct");
+ SimpleTest.is(someSortedLabels[9], "LinkedIn", "The 10th label is correct");
+ SimpleTest.is(someSortedLabels[10], "Lufthansa", "The 11th label is correct");
+ SimpleTest.is(someSortedLabels[11], "My Yahoo!", "The 12th label is correct");
+ SimpleTest.is(someSortedLabels[12], "MyBlogLog", "The 13th label is correct");
+ SimpleTest.is(someSortedLabels[13], "MySpace", "The 14th label is correct");
+ SimpleTest.is(someSortedLabels[14], "The New York Times", "The 15th label is correct");
+ SimpleTest.is(someSortedLabels[15], "Yahoo! Groups", "The 16th label is correct");
+ SimpleTest.is(someSortedLabels[16], "Yahoo! Mail", "The 17th label is correct");
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'sortRecords_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var caseInsensitiveCompare;
+
+ caseInsensitiveCompare = function (aValue, bValue) {
+ return MochiKit.Base.compare(aValue.toLowerCase(), bValue.toLowerCase());
+ };
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("sortRecords_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(Clipperz.Async.deferredSort, function (aRecord, bRecord) {
+ return Clipperz.Async.deferredCompare(MochiKit.Base.compare, aRecord.label(), bRecord.label());
+ });
+ deferredResult.addCallback(MochiKit.Base.itemgetter('0'));
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Amazon.com", "Sorting the records themselves (by labels), the first one is 'Amazon.com'");
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(Clipperz.Async.deferredSort, function (aRecord, bRecord) {
+ return Clipperz.Async.deferredCompare(MochiKit.Base.compare, aRecord.label(), bRecord.label());
+ });
+ deferredResult.addCallback(MochiKit.Base.itemgetter('5'));
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Expedia.com", "Sorting the records themselves (by labels), the sixth element is 'Expedia.com'");
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(Clipperz.Async.deferredSort, function (aRecord, bRecord) {
+ return Clipperz.Async.deferredCompare(MochiKit.Base.compare, aRecord.label(), bRecord.label());
+ });
+ deferredResult.addCallback(MochiKit.Base.itemgetter('19'));
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("del.icio.us", "Sorting the records themselves (by labels), the 20th element is 'del.icio.us'");
+
+
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(Clipperz.Async.deferredSort, function (aRecord, bRecord) {
+ return Clipperz.Async.deferredCompare(caseInsensitiveCompare, aRecord.label(), bRecord.label());
+ });
+ deferredResult.addCallback(MochiKit.Base.itemgetter('3'));
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("del.icio.us", "Sorting with case insensitive mode (by labels), the fourth record is 'del.ico.us'");
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(Clipperz.Async.deferredSort, function (aRecord, bRecord) {
+ return Clipperz.Async.deferredCompare(caseInsensitiveCompare, aRecord.label(), bRecord.label());
+ });
+ deferredResult.addCallback(MochiKit.Base.itemgetter('19'));
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Yahoo! Account", "Sorting with case insensitive mode (by labels), the 20th record is 'Yahoo! Account'");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'accessToSingleRecord_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("sortRecords_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Amazon.com", "Sorting the records themselves (by labels), the first one is 'Amazon.com'");
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'accessToSingleRecordContent_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("sortRecords_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('fields'));
+ deferredResult.addCallback(function (someRecordFields) {
+ SimpleTest.is(MochiKit.Base.keys(someRecordFields).length, 2, "The number of fields of the Amazon.com record matches");
+ return someRecordFields;
+ });
+ deferredResult.addCallback(MochiKit.Base.itemgetter('5e822c34aaf1a9fbc0b52585c1915f3a3758abd51923a4d35ae85373bbb839c2'));
+ deferredResult.collectResults({
+ 'label': MochiKit.Base.methodcaller('label'),
+ 'value': MochiKit.Base.methodcaller('value')
+ })
+ deferredResult.addCallback(function (someValues) {
+ SimpleTest.is(someValues['label'], 'email', "the first field label matches");
+ SimpleTest.is(someValues['value'], 'joe@clipperz.com', "the first field value matches");
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'modifyRecordLabelAndCheckForPendingChanges_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("modifyRecordAndCheckForPendingChanges_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Amazon.com", "This is the record the test was expecting");
+
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setLabel', "New label"));
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "setting a label on one of the user's record, trigger the 'hasPendingChanges' flag");
+
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("New label", "once set the new label value, I can still get back its value");
+
+ deferredResult.addMethod(user, 'revertChanges');
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "reverting changes should return to the original state");
+
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Amazon.com", "The label of the record is restored to its initial value");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'modifyRecordFieldsAndCheckForPendingChanges_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("modifyRecordFieldsAndCheckForPendingChanges_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('fields'));
+ deferredResult.addCallback(MochiKit.Base.itemgetter('5e822c34aaf1a9fbc0b52585c1915f3a3758abd51923a4d35ae85373bbb839c2'));
+ deferredResult.addCallback(MochiKit.Base.methodcaller('value'));
+ deferredResult.addTest("joe@clipperz.com", "The value of the record field is correct");
+
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('fields'));
+ deferredResult.addCallback(MochiKit.Base.itemgetter('5e822c34aaf1a9fbc0b52585c1915f3a3758abd51923a4d35ae85373bbb839c2'));
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setValue', 'joe@example.com'));
+
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('fields'));
+ deferredResult.addCallback(MochiKit.Base.itemgetter('5e822c34aaf1a9fbc0b52585c1915f3a3758abd51923a4d35ae85373bbb839c2'));
+ deferredResult.addCallback(MochiKit.Base.methodcaller('value'));
+ deferredResult.addTest("joe@example.com", "The record field correctly returns the newly updated value");
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "changing the value of a record's field trigger the 'hasPendingChanges' flag");
+
+ deferredResult.addMethod(user, 'revertChanges');
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "reverting changes should return to the original state");
+
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('fields'));
+ deferredResult.addCallback(MochiKit.Base.itemgetter('5e822c34aaf1a9fbc0b52585c1915f3a3758abd51923a4d35ae85373bbb839c2'));
+ deferredResult.addCallback(MochiKit.Base.methodcaller('value'));
+ deferredResult.addTest("joe@clipperz.com", "The original value of the record field is returned after reverting the changes");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'modifyRecordNoteAndCheckForPendingChanges_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("modifyRecordNoteAndCheckForPendingChanges_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('notes'));
+ deferredResult.addTest("aproofofconcept\n<script>alert(\"nothing bad in here\");</script><script>alert(\"AAHHGGGH!\");</script>", "The value of the record note is correct");
+
+ deferredResult.addMethod(user, 'getRecord', '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setNotes', "A new note text"));
+
+ deferredResult.addMethod(user, 'getRecord', '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('notes'));
+ deferredResult.addTest("A new note text", "The value of the record note has been updated");
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "changing the value of record's notes trigger the 'hasPendingChanges' flag");
+
+ deferredResult.addMethod(user, 'getRecord', '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('hasPendingChanges'));
+ deferredResult.addTest(true, "also the record should flat its pending changes on the note field");
+
+ deferredResult.addMethod(user, 'revertChanges');
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "reverting changes should return to the original state");
+
+ deferredResult.addMethod(user, 'getRecord', '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('notes'));
+ deferredResult.addTest("aproofofconcept\n<script>alert(\"nothing bad in here\");</script><script>alert(\"AAHHGGGH!\");</script>", "The value of the record note is restored to its initial value");
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'loadUser_withoutPreferences_andTryToAccessThem_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ deferredResult = new Clipperz.Async.Deferred("loadUser_withoutPreferences_andTryToAccessThem_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.collectResults({
+ 'preferences': [
+ MochiKit.Base.method(user, 'getHeaderIndex', 'preferences'),
+ MochiKit.Base.methodcaller('getDecryptedData')
+ ],
+ 'oneTimePasswords': [
+ MochiKit.Base.method(user, 'getHeaderIndex', 'oneTimePasswords'),
+ MochiKit.Base.methodcaller('getDecryptedData')
+ ]
+ });
+ deferredResult.addCallback(function (someValues) {
+ SimpleTest.is(Clipperz.Base.serializeJSON(someValues['preferences']), '{}', "The preferences are empty");
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'modifyRecordTitleAndCheckForPendingChanges_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ deferredResult = new Clipperz.Async.Deferred("modifyRecordTitleAndCheckForPendingChanges_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Card 1", "The value of the record note is correct");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setLabel', "Edited card 1"));
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Edited card 1", "The value of the record label has been updated");
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "changing the value of record's label trigger the 'hasPendingChanges' flag");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('hasPendingChanges'));
+// deferredResult.addTest(true, "also the record should flag its pending changes on the label - 1");
+ deferredResult.addTest(false, "changing just the label (or any other attribute stored on the header) should not trigger the 'hasPendingChanges' flag");
+
+ deferredResult.addMethod(user, 'revertChanges');
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "reverting changes should return to the original state");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Card 1", "The value of the record label is restored to its initial value");
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'modifyRecordTitleAndCheckForPendingChanges_take2_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ deferredResult = new Clipperz.Async.Deferred("modifyRecordTitleAndCheckForPendingChanges_take2_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Card 1", "The value of the record note is correct");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setLabel', "Edited card 1"));
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "changing the value of record's label trigger the 'hasPendingChanges' flag");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('hasPendingChanges'));
+// deferredResult.addTest(true, "also the record should flag its pending changes on the label - 2");
+ deferredResult.addTest(false, "only the label has changed, and this should not trigger the 'hasPendingChanges' flag on the record as it is stored in the header");
+
+// deferredResult.addCallback(Clipperz.log, "=======================================================");
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setLabel', "Card 1"));
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "Setting the old value back should void all pending changes");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('hasPendingChanges'));
+ deferredResult.addTest(false, "also the record should not flag any pending changes, as the original value has been restored");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Card 1", "The value of the record label is restored to its initial value");
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'modifyRecordNoteAndThanResetOriginalValue_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("modifyRecordNoteAndThanResetOriginalValue_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('notes'));
+ deferredResult.addTest("aproofofconcept\n<script>alert(\"nothing bad in here\");</script><script>alert(\"AAHHGGGH!\");</script>", "The value of the record note is correct");
+
+ deferredResult.addMethod(user, 'getRecord', '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setNotes', "A new note text"));
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "changing the value of record's notes trigger the 'hasPendingChanges' flag");
+
+ deferredResult.addMethod(user, 'getRecord', '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setNotes', "aproofofconcept\n<script>alert(\"nothing bad in here\");</script><script>alert(\"AAHHGGGH!\");</script>"));
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "setting the field to its original value basically reset the change, like 'revertChanges' would have done");
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'modifyRecordNoteAndCommitChanges_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var user2;
+ var newNoteText;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ newNoteText = "A new note text";
+
+ deferredResult = new Clipperz.Async.Deferred("modifyRecordAndCommitChanges_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('notes'));
+ deferredResult.addTest("", "This is the original value of the notes");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setNotes', newNoteText));
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "changing the value of record's notes trigger the 'hasPendingChanges' flag");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('hasPendingChanges'));
+ deferredResult.addTest(true, "changing the value of record's notes trigger the 'hasPendingChanges' flag also on the record itself");
+
+ deferredResult.addMethod(user, 'saveChanges');
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "saving changes should return the user to a state with not changes pending - 1");
+
+ deferredResult.addMethod(user2, 'login');
+ deferredResult.addMethod(user2, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('notes'));
+ deferredResult.addTest(newNoteText, "It looks like the data edited was correctly stored and reloaded here");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'multipleModificationToRecordTitleAndCommitChanges_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var user2;
+ var user3;
+ var newRecordTitle;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ user3 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ newRecordTitle = "A nice new title here";
+
+ deferredResult = new Clipperz.Async.Deferred("multipleModificationToRecordTitleAndCommitChanges_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Card 1", "This is the original value of the label");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setLabel', newRecordTitle));
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "changing the value of record's label trigger the 'hasPendingChanges' flag");
+
+ deferredResult.addMethod(user, 'saveChanges');
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "saving changes should return the user to a state with not changes pending - 2"); // FAIL
+
+ deferredResult.addMethod(user2, 'login');
+ deferredResult.addMethod(user2, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest(newRecordTitle, "It looks like the label edited was correctly stored and reloaded here");
+
+ deferredResult.addMethod(user2, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setLabel', newRecordTitle + "-" + newRecordTitle));
+ deferredResult.addMethod(user2, 'hasPendingChanges');
+ deferredResult.addTest(true, "changing again the value of record's label trigger the 'hasPendingChanges' flag also on the new user");
+
+ deferredResult.addMethod(user2, 'saveChanges');
+ deferredResult.addMethod(user2, 'hasPendingChanges');
+ deferredResult.addTest(false, "after committing the changes, the user has no pending changes"); // FAIL
+
+ deferredResult.addMethod(user3, 'login');
+ deferredResult.addMethod(user3, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest(newRecordTitle + "-" + newRecordTitle, "It looks like the label edited was correctly stored and reloaded here");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'saveChangesWithADeletedRecord_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ deferredResult = new Clipperz.Async.Deferred("saveChangesWithADeletedRecord_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(1, "This account has oly a single card");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Card 1", "This is the initial value of the label ...");
+
+ deferredResult.addMethod(user, 'getHeaderIndex', 'recordsIndex');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('prepareRemoteDataForChangedRecords'));
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.ok(aResult['updated'] != null, "There updated key is not null");
+ SimpleTest.isDeeply(aResult['updated'], [], "There are no updated cards");
+ SimpleTest.ok(aResult['deleted'] != null, "There deleted key is not null");
+ SimpleTest.isDeeply(aResult['deleted'], [], "There are no deleted references");
+ return aResult;
+ })
+ deferredResult.addMethod(user, 'revertChanges');
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addMethod(user, 'deleteRecord');
+ deferredResult.addMethod(user, 'getHeaderIndex', 'recordsIndex');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('prepareRemoteDataForChangedRecords'));
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.isDeeply(aResult['deleted'], ['8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'], "The deleted record reference is correctly reported");
+ return aResult;
+ })
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.shouldFail("accessing the deleted record reference should raise an exception");
+
+ deferredResult.addMethod(user, 'getRecord', '0000000000000000000000000000000000000000000000000000000000000000');
+ deferredResult.shouldFail("accessing a fake record reference should raise an exception");
+
+ deferredResult.addMethod(user, 'saveChanges');
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(0, "after deleting the only record, there should be no records bound to the user");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'revertingChangesAfterDeletingACard_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ deferredResult = new Clipperz.Async.Deferred("simpleSaveChanges_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Card 1", "This is the initial value of the label ...");
+
+ deferredResult.addMethod(user, 'getHeaderIndex', 'recordsIndex');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('prepareRemoteDataForChangedRecords'));
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.ok(aResult['updated'] != null, "There updated key is not null");
+ SimpleTest.isDeeply(aResult['updated'], [], "There are no updated cards");
+ SimpleTest.ok(aResult['deleted'] != null, "There deleted key is not null");
+ SimpleTest.isDeeply(aResult['deleted'], [], "There are no deleted references");
+ return aResult;
+ })
+ deferredResult.addMethod(user, 'revertChanges');
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addMethod(user, 'deleteRecord');
+ deferredResult.addMethod(user, 'getHeaderIndex', 'recordsIndex');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('prepareRemoteDataForChangedRecords'));
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.isDeeply(aResult['deleted'], ['8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'], "The deleted record reference is correctly reported");
+ return aResult;
+ })
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.shouldFail("accessing the deleted record reference should raise an exception");
+
+ deferredResult.addMethod(user, 'getRecord', '0000000000000000000000000000000000000000000000000000000000000000');
+ deferredResult.shouldFail("accessing a fake record reference should raise an exception");
+
+ deferredResult.addMethod(user, 'revertChanges');
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(SimpleTest.ok, true, "after reverting all changes, the deleted card is restored");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'lockUnlockAccountAfterDeletingACard_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var recordID;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ recordID = 'eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5';
+// recordID = '507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a';
+
+ deferredResult = new Clipperz.Async.Deferred("lockUnlockAccountAfterDeletingACard_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(20, "Initially the user has 20 cards");
+
+ deferredResult.addMethod(user, 'getDirectLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(22, "Initially the user has 22 direct logins");
+
+ deferredResult.addMethod(user, 'getHeaderIndex', 'recordsIndex');
+ deferredResult.addMethodcaller('directLoginsData');
+ deferredResult.addMethodcaller('values');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(22, "There should be also 22 direct login references");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(4, "The selected record has 4 direct logins");
+
+ deferredResult.addMethod(user, 'getRecord', recordID);
+ deferredResult.addMethod(user, 'deleteRecord');
+ deferredResult.addMethod(user, 'saveChanges');
+
+ deferredResult.addMethod(user, 'hasAnyCleanTextData');
+ deferredResult.addTest(true, "after saving changes, hasAnyCleanTextData should be true");
+
+ deferredResult.addMethod(user, 'deleteAllCleanTextData');
+
+ deferredResult.addMethod(user, 'hasAnyCleanTextData');
+ deferredResult.addTest(false, "after deleting all clean text data, hasAnyCleanTextData should be true");
+
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest((20 - 1), "After deleting a card, only 19 are left");
+
+ deferredResult.addMethod(user, 'getDirectLogins');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest((22 - 4), "Initially the user has 18 direct logins");
+
+ deferredResult.addMethod(user, 'getHeaderIndex', 'recordsIndex');
+ deferredResult.addMethodcaller('directLoginsData');
+ deferredResult.addMethodcaller('values');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest((22 - 4), "Once deleted the card, there should be just 18 direct login references left");
+
+ deferredResult.addCallback(function () {
+ SimpleTest.ok(true, "nothing wrong had happen 'till here");
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'lockUnlockAccountAfterDeletingACard_2_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("lockUnlockAccountAfterDeletingACard_2_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(someRecords.length, 20, "Initially the user has 20 cards");
+ });
+
+ deferredResult.addMethod(user, 'getDirectLogins');
+ deferredResult.addCallback(function (someDirectLogins) {
+ SimpleTest.is(someDirectLogins.length, 22, "Initially the user has 42 direct logins");
+ });
+
+ deferredResult.addMethod(user, 'getHeaderIndex', 'recordsIndex');
+ deferredResult.addMethodcaller('directLoginsData');
+ deferredResult.addMethodcaller('values');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(function (someDirectLoginReferences) {
+ SimpleTest.is(someDirectLoginReferences.length, 22, "There should be also 22 direct login references - 2");
+ });
+
+ deferredResult.addMethod(user, 'getRecord', '507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a');
+ deferredResult.addMethodcaller('directLogins');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(function (someDirectLogins) {
+ SimpleTest.is(someDirectLogins.length, 1, "The selected record has 4 direct logins");
+ });
+
+
+ deferredResult.addMethod(user, 'getRecord', '507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a');
+ deferredResult.addMethod(user, 'deleteRecord');
+ deferredResult.addMethod(user, 'saveChanges');
+ deferredResult.addMethod(user, 'deleteAllCleanTextData');
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(someRecords.length, (20 -1), "After deleting a card, only 19 are left - 2");
+ });
+
+ deferredResult.addMethod(user, 'getDirectLogins');
+ deferredResult.addCallback(function (someDirectLogins) {
+ SimpleTest.is(someDirectLogins.length, (22 - 1), "Initially the user has 21 direct logins - 2");
+ });
+
+ deferredResult.addMethod(user, 'getHeaderIndex', 'recordsIndex');
+ deferredResult.addMethodcaller('directLoginsData');
+ deferredResult.addMethodcaller('values');
+ deferredResult.addCallback(MochiKit.Base.values);
+ deferredResult.addCallback(function (someDirectLoginReferences) {
+ SimpleTest.is(someDirectLoginReferences.length, (22 - 1), "Once deleted the card, there should be just 21 direct login references left");
+ });
+
+ deferredResult.addCallback(function () {
+ SimpleTest.ok(true, "nothing wrong had happen 'till here - 2");
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'simpleSaveChanges_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ deferredResult = new Clipperz.Async.Deferred("simpleSaveChanges_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('label'));
+ deferredResult.addTest("Card 1", "This is the initial value of the label ...");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setLabel', "New label for Card 1"));
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setNotes', "Setting just the label would not trigger the update of the record data and nothing will end up in the 'updated' list"));
+
+ deferredResult.addMethod(user, 'getHeaderIndex', 'recordsIndex');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('prepareRemoteDataForChangedRecords'));
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.is(aResult['updated'].length, 1, "The updadated record should be listed in the changes getting ready for commit");
+ return aResult;
+ })
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'saveChangesAndDataCaching_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var record_1;
+ var record_2;
+
+ record_1 = '062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80';
+ record_2 = '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d';
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("saveChangesAndDataCaching_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', record_1);
+ deferredResult.addMethodcaller('hasLoadedRemoteData');
+ deferredResult.addTest(false, "The card data should have not been loaded yet");
+
+ deferredResult.addMethod(user, 'getRecord', record_2);
+ deferredResult.addMethodcaller('hasLoadedRemoteData');
+ deferredResult.addTest(false, "Also the other card data should have not been loaded yet");
+
+ deferredResult.addMethod(user, 'getRecord', record_1);
+ deferredResult.addMethodcaller('setLabel', "New title");
+
+ deferredResult.addMethod(user, 'getRecord', record_1);
+ deferredResult.addMethodcaller('hasLoadedRemoteData');
+ deferredResult.addTest(false, "Changing just the label should not trigger the full loading of the card");
+
+ deferredResult.addMethod(user, 'getRecord', record_1);
+ deferredResult.addMethodcaller('setNotes', "New note text");
+
+ deferredResult.addMethod(user, 'getRecord', record_1);
+ deferredResult.addMethodcaller('hasLoadedRemoteData');
+ deferredResult.addTest(true, "Changing the notes should trigger the loading of the card");
+
+ deferredResult.addMethod(user, 'getRecord', record_2);
+ deferredResult.addMethodcaller('hasLoadedRemoteData');
+ deferredResult.addTest(false, "Changing record_1 should not trigger the loading of record_2");
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "changing the value of record's label trigger the 'hasPendingChanges' flag");
+
+ deferredResult.addMethod(user, 'saveChanges');
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "saving changes should return the user to a state with not changes pending - 3");
+
+ deferredResult.addMethod(user, 'getRecord', record_1);
+ deferredResult.addMethodcaller('hasLoadedRemoteData');
+ deferredResult.addTest(true, "After saving the changes, record_1 sould not have the remote data");
+
+ deferredResult.addMethod(user, 'getRecord', record_2);
+ deferredResult.addMethodcaller('hasLoadedRemoteData');
+ deferredResult.addTest(false, "After saving, record_2 should still be NOT loaded");
+
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addNewRecordFieldAndSave_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ deferredResult = new Clipperz.Async.Deferred("simpleSaveChanges_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(function (someFields) {
+ SimpleTest.is(MochiKit.Base.values(someFields).length, 3, "The record has initially 3 fields");
+ });
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('addField', {'label':"New field label", 'value':"New field value", 'isHidden':false}));
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(true, "adding a field should mark the record as having pending changes");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(function (someFields) {
+ SimpleTest.is(MochiKit.Base.values(someFields).length, 4, "The record has now 4 fields");
+ });
+
+ deferredResult.addMethod(user, 'saveChanges');
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "saving changes should return the user to a state with not changes pending - 4");
+
+ deferredResult.addMethod(user, 'hasAnyCleanTextData');
+ deferredResult.addTest(true, "after saving changes, hasAnyCleanTextData should be true");
+
+//deferredResult.addCallback(function (aValue) { console.log(">>> #################################################"); return aValue});
+ deferredResult.addMethod(user, 'deleteAllCleanTextData');
+//deferredResult.addCallback(function (aValue) { console.log("<<< #################################################"); return aValue});
+
+ deferredResult.addMethod(user, 'hasAnyCleanTextData');
+ deferredResult.addTest(false, "after deleting all clean text, hasAnyCleanTextData should be false");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'deleteRecordFieldAndSave_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var user2;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ deferredResult = new Clipperz.Async.Deferred("simpleSaveChanges_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(function (someFields) {
+ SimpleTest.is(MochiKit.Base.values(someFields).length, 3, "The record has initially 3 fields");
+ });
+
+ deferredResult.collectResults({
+ 'record': MochiKit.Base.method(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'),
+ 'field': [
+ MochiKit.Base.method(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13'),
+ MochiKit.Base.methodcaller('fields'),
+ MochiKit.Base.values,
+ MochiKit.Base.itemgetter('0')
+ ]
+ })
+ deferredResult.addCallback(function (someValues) {
+ someValues['record'].removeField(someValues['field']);
+ });
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(true, "removing a field should mark the record as having pending changes");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(function (someFields) {
+ SimpleTest.is(MochiKit.Base.values(someFields).length, 2, "The record has now 2 fields");
+ });
+
+ deferredResult.addMethod(user, 'saveChanges');
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "saving changes should return the user to a state with not changes pending - 5");
+
+ //. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+
+ deferredResult.addMethod(user2, 'login');
+ deferredResult.addMethod(user2, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(function (someFields) {
+ SimpleTest.is(MochiKit.Base.values(someFields).length, 2, "Once saved, the record is left with just two fields");
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'loadDirectLogin_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("loadDirectLogin_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('directLogins'));
+ deferredResult.addCallback(function (someDirectLogins) {
+ SimpleTest.is(1, MochiKit.Base.keys(someDirectLogins).length, "the Amazon.com card has just one direct login");
+ });
+
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('hasPendingChanges'));
+ deferredResult.addTest(false, "initially the record does not have any pending changes");
+
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('directLogins'));
+ deferredResult.addCallback(MochiKit.Base.itemgetter('03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c'));
+// deferredResult.addCallback(MochiKit.Base.methodcaller('runDirectLogin', true));
+ deferredResult.addCallback(Clipperz.PM.UI.Common.Controllers.DirectLoginRunner.testDirectLogin);
+
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('getFieldsValues'));
+ deferredResult.addCallback(function (someFieldsValues) {
+ SimpleTest.is(MochiKit.Base.keys(someFieldsValues).length, 2, "the Amazon.com card has just two fields");
+ });
+
+ deferredResult.addMethod(user, 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('hasPendingChanges'));
+ deferredResult.addTest(false, "accessing fields values should not trigger the 'hasPendingChanges' flag");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'readingVeryOldCards_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ deferredResult = new Clipperz.Async.Deferred("readingVeryOldCards_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
+ deferredResult.addMethodcaller('label');
+ deferredResult.addTest('Card encoded with an old algorithm', 'the label of the selected record is the expected one');
+
+ deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('fields'));
+ deferredResult.addCallback(function (someFields) {
+ SimpleTest.is(6, MochiKit.Base.keys(someFields).length, "the 'Card encoded with an old algorithm' card has six fields");
+ });
+
+ deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(false, "accessing the card fields should not trigger the hasPendingChanges flag");
+
+ deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('addField', {'label':"New field label", 'value':"New field value", 'isHidden':false}));
+
+ deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('fields'));
+ deferredResult.addCallback(function (someFields) {
+ SimpleTest.is(7, MochiKit.Base.keys(someFields).length, "adding a field shoult bring the total field count to 7");
+ });
+
+ deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(true, "adding a field should mark the record as having pending changes - 2");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addingNewEmptyRecordAndSaveChanges_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var newRecordReference;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ deferredResult = new Clipperz.Async.Deferred("addingNewEmptyRecordAndSaveChanges_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(MochiKit.Base.keys(someRecords).length, 1, "The user has initially just one record");
+ });
+
+ deferredResult.addMethod(user, 'createNewRecord');
+ deferredResult.addMethodcaller('reference');
+ deferredResult.addCallback(function (aNewRecordReference) {
+ newRecordReference = aNewRecordReference;
+ })
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(MochiKit.Base.keys(someRecords).length, 2, "After having created a new record, the total should be updated accordingly");
+ });
+
+ deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(false, "adding a new record should not trigger any changes on a sibling record");
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "adding a new record should trigger the 'has pending changes' flag on the user");
+
+ deferredResult.addMethod(user, 'saveChanges');
+
+ deferredResult.addMethod(user2, 'login');
+ deferredResult.addMethod(user2, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(MochiKit.Base.keys(someRecords).length, 1, "Reloading the data, just one record is available, as a brand new record without any changes should not be saved");
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addNewRecordAndSaveChanges_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ deferredResult = new Clipperz.Async.Deferred("addNewRecordAndSaveChanges_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(MochiKit.Base.keys(someRecords).length, 1, "The user has initially just one record");
+ });
+
+ deferredResult.addMethod(user, 'createNewRecord');
+ deferredResult.addCallback(function (aNewRecord) {
+ var innerDeferredResult;
+
+ innerDeferredResult = new Clipperz.Async.Deferred("addNewRecordAndSaveChanges_test <internal>", {trace:false});
+
+ innerDeferredResult.addMethod(aNewRecord, 'label');
+ innerDeferredResult.addTest('', "The label of a brand new record should be the empty string");
+
+ innerDeferredResult.addMethod(aNewRecord, 'setLabel', "New record label");
+ innerDeferredResult.addMethod(aNewRecord, 'setNotes', "New record notes");
+ innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"Label 1", 'value':"Value 1", 'isHidden':false});
+ innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"Label 2", 'value':"Value 2", 'isHidden':false});
+ innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"Label 3", 'value':"Value 3", 'isHidden':true});
+ innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"Label 4", 'value':"Value 4", 'isHidden':false});
+ innerDeferredResult.callback();
+
+ return innerDeferredResult;
+ })
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(MochiKit.Base.keys(someRecords).length, 2, "After having created a new record, the total should be updated accordingly");
+ });
+
+ deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(false, "adding a new record should not trigger any changes on a sibling record");
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "adding a new record should trigger the 'has pending changes' flag on the user");
+
+ deferredResult.addMethod(user, 'saveChanges');
+
+ deferredResult.addCallback(function () {
+ var recordData
+ var recordVersionData;
+
+ recordData = MochiKit.Base.values(proxy.dataStore().data()['users']['9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8']['records'])[1];
+ recordVersionData = MochiKit.Base.values(recordData['versions'])[0];
+
+ SimpleTest.is(recordVersionData['previousVersionKey'], Clipperz.PM.Crypto.nullValue, "The previous version key on the first version of a newly created record is equal to Clipperz.PM.Crypto.nullValue");
+ });
+
+ deferredResult.addMethod(user2, 'login');
+ deferredResult.addMethod(user2, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(someRecords.length, 2, "Reloading the data, two records are available.");
+ return someRecords;
+ });
+ deferredResult.addCallback(MochiKit.Base.itemgetter('1'));
+ deferredResult.collectResults({
+ 'label': [
+ MochiKit.Base.methodcaller('label'),
+ Clipperz.Async.Test.is("New record label", "The label is correct")
+ ],
+ 'notes': [
+ MochiKit.Base.methodcaller('notes'),
+ Clipperz.Async.Test.is("New record notes", "The note is correct")
+ ],
+ 'fields': [
+ MochiKit.Base.methodcaller('fields'),
+ function (someFields) {
+ SimpleTest.is(MochiKit.Base.values(someFields).length, 4, "The fields are 4, as expected");
+ return someFields;
+ }
+ ]
+ })
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addNewRecordAndTestNewRecordIndex_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("addNewRecordAndTestNewRecordIndex_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(MochiKit.Base.keys(someRecords).length, 20, "The user has initially 20 records");
+ });
+
+ deferredResult.addMethod(user, 'createNewRecord');
+ deferredResult.addCallback(function (aNewRecord) {
+ var innerDeferredResult;
+
+ innerDeferredResult = new Clipperz.Async.Deferred("addNewRecordAndTestNewRecordIndex_test <internal>", {trace:false});
+
+ innerDeferredResult.addMethod(user, 'getHeaderIndex', 'recordsIndex');
+ innerDeferredResult.addMethodcaller('recordsIndex');
+ innerDeferredResult.addCallback(MochiKit.Base.itemgetter(aNewRecord.reference()));
+ innerDeferredResult.addTest(20, "The index of the new record should be 20");
+
+ innerDeferredResult.callback();
+
+ return innerDeferredResult;
+ })
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'editRecordAndTestForChangesInPreferencesAndOTP_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var user_2;
+ var originalPreferences;
+ var originalOTPs;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+ user_2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("editRecordAndTestForChangesInPreferencesAndOTP_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']);
+ deferredResult.addMethod(user, 'login');
+ deferredResult.addMethod(user, 'getServerData');
+
+ deferredResult.collectResults({
+ 'preferences': [
+ MochiKit.Base.method(user, 'getHeaderIndex', 'preferences'),
+ MochiKit.Base.methodcaller('getDecryptedData')
+ ],
+ 'oneTimePasswords': [
+ MochiKit.Base.method(user, 'getHeaderIndex', 'oneTimePasswords'),
+ MochiKit.Base.methodcaller('getDecryptedData')
+ ]
+ });
+
+ deferredResult.addCallback(function (someValues) {
+//console.log("SOME VALUES", someValues);
+ originalPreferences = Clipperz.Base.deepClone(someValues['preferences']);
+ originalOTPs = Clipperz.Base.deepClone(someValues['oneTimePasswords']);
+
+ SimpleTest.is(originalPreferences['preferredLanguage'], 'en-US', "Preference.language is ok");
+ SimpleTest.is(originalPreferences['shouldShowDonationPanel'], false, "Preference.shouldShowDonationPanel is ok");
+
+ SimpleTest.is(MochiKit.Base.keys(originalOTPs).length, 6, "the number of OTPs is as expected");
+ });
+
+ deferredResult.addMethod(user, 'getRecord', '35b30f9e923ce913365815d44cf344ce66cb71b636093b8ec55b8245d13df82b');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('setLabel', "NEW LABEL"));
+ deferredResult.addMethod(user, 'saveChanges');
+
+ deferredResult.addMethod(user_2, 'login');
+ deferredResult.addMethod(user_2, 'getServerData');
+
+ deferredResult.collectResults({
+ 'preferences': [
+ MochiKit.Base.method(user_2, 'getHeaderIndex', 'preferences'),
+ MochiKit.Base.methodcaller('getDecryptedData')
+ ],
+ 'oneTimePasswords': [
+ MochiKit.Base.method(user_2, 'getHeaderIndex', 'oneTimePasswords'),
+ MochiKit.Base.methodcaller('getDecryptedData')
+ ]
+ });
+
+ deferredResult.addCallback(function (someValues) {
+//console.log("SOME VALUES", someValues);
+// originalPreferences = Clipperz.Base.deepClone(someValues['preferences']);
+// originalOTPs = Clipperz.Base.deepClone(someValues['oneTimePasswords']);
+
+ SimpleTest.is(someValues['preferences']['preferredLanguage'], originalPreferences['preferredLanguage'], "Preference.language is preserved");
+ SimpleTest.is(someValues['preferences']['shouldShowDonationPanel'], originalPreferences['shouldShowDonationPanel'], "Preference.shouldShowDonationPanel is preserved");
+
+ SimpleTest.is(MochiKit.Base.keys(someValues['oneTimePasswords']).length, MochiKit.Base.keys(originalOTPs).length, "the number of OTPs is preserved");
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addRecordAndSaveChangesMultipleTimes_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ deferredResult = new Clipperz.Async.Deferred("addRecordAndSaveChangesMultipleTimes_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(1, "The user has one record stored in its account");
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "After loading records, the user should have no pending changes");
+
+ deferredResult.addMethod(user, 'createNewRecord');
+ deferredResult.addCallback(function (aNewRecord) {
+ var innerDeferredResult;
+
+ innerDeferredResult = new Clipperz.Async.Deferred("addRecordAndSaveChangesMultipleTimes_test <internal [1]>", {trace:false});
+
+ innerDeferredResult.addMethod(aNewRecord, 'setLabel', "New record 1");
+ innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':'record number', 'value':"1", 'isHidden':false});
+ innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':'field count', 'value':"2", 'isHidden':false});
+ innerDeferredResult.callback();
+
+ return innerDeferredResult;
+ })
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "Before saving, the user has pending changes");
+
+ deferredResult.addMethod(user, 'saveChanges');
+ deferredResult.addCallback(SimpleTest.ok, true, "Saving worked (apparently) fine");
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "After saving, the user has no pending changes");
+
+ deferredResult.addMethod(user, 'createNewRecord');
+ deferredResult.addCallback(function (aNewRecord) {
+ var innerDeferredResult;
+
+ innerDeferredResult = new Clipperz.Async.Deferred("addRecordAndSaveChangesMultipleTimes_test <internal [2]>", {trace:false});
+
+ innerDeferredResult.addMethod(aNewRecord, 'setLabel', "New record 2");
+ innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':"record number", 'value':"2", 'isHidden':false});
+ innerDeferredResult.callback();
+
+ return innerDeferredResult;
+ })
+ deferredResult.addMethod(user, 'saveChanges');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(3, "After having created two new records, the total should be updated accordingly");
+
+
+ deferredResult.addMethod(user2, 'login');
+ deferredResult.addMethod(user2, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(3, "Reloading the data, three records are available");
+
+ deferredResult.addMethod(user2, 'recordWithLabel', 'New record 1');
+//deferredResult.addCallback(function (aValue) { console.log("RECORD with Label", aValue); return aValue; });
+ deferredResult.collectResults({
+ 'label': [
+ MochiKit.Base.methodcaller('label'),
+ MochiKit.Base.partial(Clipperz.Async.Test.is, 'New record label', "The label is correct")
+ ],
+ 'notes': [
+ MochiKit.Base.methodcaller('notes'),
+ Clipperz.Async.Test.is('', "The note of the new created record is empty")
+ ],
+ 'fields': [
+ MochiKit.Base.methodcaller('fields'),
+ MochiKit.Base.values,
+ MochiKit.Base.itemgetter('length'),
+ Clipperz.Async.Test.is(2, "The new record has just one field, as expected")
+ ],
+ 'fieldValues_1': [
+ MochiKit.Base.methodcaller('fieldWithLabel', 'record number'),
+ MochiKit.Base.methodcaller('value'),
+ Clipperz.Async.Test.is('1', "The field value is as expected")
+ ],
+ 'fieldValues_2': [
+ MochiKit.Base.methodcaller('fieldWithLabel', 'field count'),
+ MochiKit.Base.methodcaller('value'),
+ Clipperz.Async.Test.is('2', "Also the second field value is as expected")
+ ]
+ })
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'addNewRecordAndRevertChanges_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user, user2;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ deferredResult = new Clipperz.Async.Deferred("addNewRecordAndRevertChanges_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_someExtraOldData']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(MochiKit.Base.keys(someRecords).length, 1, "The user has initially just one record");
+ });
+
+ deferredResult.addMethod(user, 'createNewRecord');
+ deferredResult.addCallback(function (aNewRecord) {
+ return Clipperz.Async.callbacks("addNewRecordAndRevertChanges_test <internal>", [
+ MochiKit.Base.method(aNewRecord, 'setLabel', "New record label"),
+ MochiKit.Base.method(aNewRecord, 'setNotes', "New record notes"),
+ MochiKit.Base.method(aNewRecord, 'addField', {'label':"Label 1", 'value':"Value 1", 'isHidden':false}),
+ MochiKit.Base.method(aNewRecord, 'addField', {'label':"Label 2", 'value':"Value 2", 'isHidden':false}),
+ MochiKit.Base.method(aNewRecord, 'addField', {'label':"Label 3", 'value':"Value 3", 'isHidden':true}),
+ MochiKit.Base.method(aNewRecord, 'addField', {'label':"Label 4", 'value':"Value 4", 'isHidden':false})
+ ], {trace:false});
+ })
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(MochiKit.Base.keys(someRecords).length, 2, "After having created a new record, the total should be updated accordingly");
+ });
+
+ deferredResult.addMethod(user, 'getRecord', '05aad20ee399b11ddc923e601fcd1d096233634f2ad4c55db4f6435e5f9cc17a');
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(false, "adding a new record should not trigger any changes on a sibling record");
+
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(true, "adding a new record should trigger the 'has pending changes' flag on the user");
+
+ deferredResult.addMethod(user, 'revertChanges');
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "reverting changes shoud restore the previous state on the user");
+
+ deferredResult.addMethod(user2, 'login');
+ deferredResult.addMethod(user2, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(someRecords.length, 1, "Reloading the data, just one record is available.");
+ return someRecords;
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'logout_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ deferredResult = new Clipperz.Async.Deferred("logout_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(MochiKit.Base.keys(someRecords).length, 18, "The user has 18 records");
+ });
+
+ deferredResult.addMethod(user, 'logout');
+ deferredResult.shouldSucceed("Logging out should not trigger an exception");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'lock_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var returnPassword = function () { return MochiKit.Async.succeed('clipperz'); };
+ var failPassword = function () { throw "Unexpected access to the password"; };
+ var currentPasswordFunction = returnPassword;
+ var passwordFunction = function () { return currentPasswordFunction(); };
+
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:passwordFunction});
+
+ deferredResult = new Clipperz.Async.Deferred("lock_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']);
+
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(MochiKit.Base.keys(someRecords).length, 18, "The user has 18 records");
+ });
+
+ deferredResult.addMethod(user, 'getDirectLogins');
+ deferredResult.addCallback(function (someDirectLogins) {
+ SimpleTest.is(MochiKit.Base.keys(someDirectLogins).length, 22, "The user has 22 direct logins");
+ });
+
+ deferredResult.addMethod(proxy, 'shouldNotReceiveAnyFurtherRequest');
+ deferredResult.addCallback(function () { currentPasswordFunction = failPassword; });
+
+ deferredResult.addMethod(user, 'lock');
+ deferredResult.shouldSucceed("Locking out should not trigger an exception");
+
+ deferredResult.addMethod(proxy, 'unexpectedRequests');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(0, "The proxy should have not received any extra request");
+//deferredResult.addCallback(function (aValue) { console.log("PROXY.unexpectedRequests", Clipperz.Base.serializeJSON(proxy.unexpectedRequests())); return aValue; });
+ deferredResult.addMethod(proxy, 'mayReceiveMoreRequests');
+ deferredResult.addCallback(function () { currentPasswordFunction = returnPassword; });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'registerNewUser_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user, user2;
+ var username;
+ var passphrase;
+
+ username = "new";
+ passphrase = "user";
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+// user2 = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return MochiKit.Async.succeed(passphrase);}});
+ user2 = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return passphrase;}});
+
+ deferredResult = new Clipperz.Async.Deferred("registerNewUser_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']);
+
+ deferredResult.addCallback(Clipperz.PM.DataModel.User.registerNewAccount, username, function () { return MochiKit.Async.succeed(passphrase);});
+ deferredResult.setValue('user');
+
+ deferredResult.addMethodcaller('getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(MochiKit.Base.keys(someRecords).length, 0, "The newly created user has no records");
+ });
+ deferredResult.getValue('user');
+ deferredResult.addMethodcaller('logout');
+
+ deferredResult.addMethod(user2, 'login');
+ deferredResult.addMethod(user2, 'getDirectLogins');
+ deferredResult.addCallback(function (someDirectLogins) {
+ SimpleTest.is(MochiKit.Base.keys(someDirectLogins).length, 0, "The user has no direct logins");
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'registerNewUserAndAddARecord_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user, user2;
+ var username;
+ var passphrase;
+
+ username = "new";
+ passphrase = "user";
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user2 = new Clipperz.PM.DataModel.User({username:username, getPassphraseFunction:function () { return passphrase;}});
+
+ deferredResult = new Clipperz.Async.Deferred("registerNewUserAndAddARecord_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_with_preferences_and_OTPs_data']);
+
+ deferredResult.addCallback(Clipperz.PM.DataModel.User.registerNewAccount, username, function () { return MochiKit.Async.succeed(passphrase);});
+ deferredResult.setValue('user');
+
+ deferredResult.addMethodcaller('getRecords');
+ deferredResult.addCallback(function (someRecords) {
+ SimpleTest.is(MochiKit.Base.keys(someRecords).length, 0, "The newly created user has no records");
+ });
+
+ deferredResult.getValue('user');
+ deferredResult.addMethodcaller('createNewRecord');
+ deferredResult.addCallback(function (aNewRecord) {
+ var innerDeferredResult;
+
+ innerDeferredResult = new Clipperz.Async.Deferred("addRecordAndSaveChangesMultipleTimes_test <internal [1]>", {trace:false});
+
+ innerDeferredResult.addMethod(aNewRecord, 'setLabel', "New record 1");
+ innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':'record number', 'value':"1", 'isHidden':false});
+ innerDeferredResult.addMethod(aNewRecord, 'addField', {'label':'field count', 'value':"2", 'isHidden':false});
+ innerDeferredResult.callback();
+
+ return innerDeferredResult;
+ })
+
+ deferredResult.getValue('user');
+ deferredResult.addMethodcaller('saveChanges');
+ deferredResult.addCallback(SimpleTest.ok, true, "Saving worked (apparently) fine");
+
+
+ deferredResult.getValue('user');
+ deferredResult.addMethodcaller('logout');
+
+ deferredResult.addMethod(user2, 'login');
+ deferredResult.addMethod(user2, 'getRecords');
+ deferredResult.addCallback(function (someDirectLogins) {
+ SimpleTest.is(MochiKit.Base.keys(someDirectLogins).length, 1, "The user - even after a brand new login - has the newly created record");
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'changePassphrase_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+ var user2;
+ var newPassphrase;
+
+ newPassphrase = 'zreppilc';
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+ user2 = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return newPassphrase;}});
+
+ deferredResult = new Clipperz.Async.Deferred("changePassphrase_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(20, "This account has oly a single card");
+
+ deferredResult.addMethod(user, 'changePassphrase', newPassphrase);
+ deferredResult.addMethod(user, 'logout');
+
+ deferredResult.addMethod(user2, 'login');
+ deferredResult.addMethod(user2, 'getRecords');
+ deferredResult.addCallback(MochiKit.Base.itemgetter('length'));
+ deferredResult.addTest(20, "This account has oly a single card");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'rearrangeRecordFieldOrderAndSave_test': function (someTestArgs) {
+ var deferredResult;
+ var proxy;
+ var user;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+ user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ deferredResult = new Clipperz.Async.Deferred("simpleSaveChanges_test", someTestArgs);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(user, 'login');
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(function (someFields) {
+ var fields;
+
+ fields = MochiKit.Base.values(someFields);
+ SimpleTest.is(fields.length, 3, "The record has initially 3 fields");
+ SimpleTest.is(fields[0].reference(), '6a84c414866dd6d266186f0255a595e9330fb34973c085a81a6e4906876c721b', "the first field is the expected one");
+ SimpleTest.is(fields[1].reference(), 'fde88847cdbae6f7ee7e38aca1a242492888ff430a79c997bc6ba4afd0540ca2', "the second field is the expected one");
+ SimpleTest.is(fields[2].reference(), 'bd4e3bb9d3497f63c4c3a507d4b80f489fdb57deb9d1b342a5e1cff65936a410', "the third field is the expected one");
+ });
+
+// "6a84c414866dd6d266186f0255a595e9330fb34973c085a81a6e4906876c721b": {
+// "label":"Label 1","value":"Value 1","type":"TXT","hidden":false
+// },
+// "fde88847cdbae6f7ee7e38aca1a242492888ff430a79c997bc6ba4afd0540ca2": {
+// "label":"Label 2","value":"Value 2","type":"PWD","hidden":true
+// },
+// "bd4e3bb9d3497f63c4c3a507d4b80f489fdb57deb9d1b342a5e1cff65936a410": {
+// "label":"Label 3","value":"http://www.example.com","type":"URL","hidden":false
+// }
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.methodcaller('sortFieldReference', [
+ 'bd4e3bb9d3497f63c4c3a507d4b80f489fdb57deb9d1b342a5e1cff65936a410',
+ '6a84c414866dd6d266186f0255a595e9330fb34973c085a81a6e4906876c721b',
+ 'bd4e3bb9d3497f63c4c3a507d4b80f489fdb57deb9d1b342a5e1cff65936a410'
+ ]));
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addMethodcaller('hasPendingChanges');
+ deferredResult.addTest(true, "adding a field should mark the record as having pending changes");
+
+ deferredResult.addMethod(user, 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addMethodcaller('fields');
+ deferredResult.addCallback(function (someFields) {
+ SimpleTest.is(MochiKit.Base.values(someFields).length, 4, "The record has now 4 fields");
+ });
+
+ deferredResult.addMethod(user, 'saveChanges');
+ deferredResult.addMethod(user, 'hasPendingChanges');
+ deferredResult.addTest(false, "saving changes should return the user to a state with not changes pending - 4");
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+*/
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+
+
+//#############################################################################
+
+SimpleTest.runDeferredTests("Clipperz.PM.DataModel.User", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/DataModel/index.html b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/index.html
new file mode 100644
index 0000000..d762093
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/DataModel/index.html
@@ -0,0 +1,47 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.DataModel.* - tests</title>
+
+ <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../SimpleTest/TestRunner.js"></script>
+</head>
+<body>
+<script>
+TestRunner.runTests(
+ 'EncryptedRemoteObject.html',
+ 'Record.html',
+ 'DirectLogin.html',
+ 'User.html',
+ 'OneTimePassword.html'
+);
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/Date.html b/frontend/gamma/tests/tests/Clipperz/PM/Date.html
new file mode 100644
index 0000000..106774b
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/Date.html
@@ -0,0 +1,59 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.Date - test</title>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <!-- script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script -->
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Date.js'></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.Async.js"></script>
+
+</head>
+<body>
+<pre id="test">
+ <script type="text/javascript" src="Date.test.js"></script>
+</pre>
+
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/Date.test.js b/frontend/gamma/tests/tests/Clipperz/PM/Date.test.js
new file mode 100644
index 0000000..df271f1
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/Date.test.js
@@ -0,0 +1,90 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+
+ 'offlineDataParsing_test': function () {
+ var value;
+ var parsedValue;
+ var expectedValue;
+
+ value = 'Tue Mar 27 06:41:37 PDT 2007';
+ parsedValue = Clipperz.PM.Date.parse(value);
+ expectedValue = new Date();
+ expectedValue.setUTCFullYear(2007, 03 - 1, 27);
+ expectedValue.setUTCHours(13, 41, 37);
+// SimpleTest.is(parsedValue.toString(), 'Tue Mar 27 2007 15:41:37 GMT+0200 (CEST)', "the data in the format stored in the offline copy is processed correctly [1]");
+ SimpleTest.is(parsedValue.toString(), expectedValue.toString(), "the data in the format stored in the offline copy is processed correctly [1]");
+
+ value = 'Thu May 10 15:01:21 PDT 2007';
+ parsedValue = Clipperz.PM.Date.parse(value);
+ expectedValue = new Date();
+ expectedValue.setUTCFullYear(2007, 05 - 1, 10);
+ expectedValue.setUTCHours(22, 01, 21);
+// SimpleTest.is(parsedValue.toString(), 'Fri May 11 2007 00:01:21 GMT+0200 (CEST)', "the data in the format stored in the offline copy is processed correctly [3]");
+ SimpleTest.is(parsedValue.toString(), expectedValue.toString(), "the data in the format stored in the offline copy is processed correctly [3]");
+
+ value = 'Thu May 10 15:01:21 PST 2007';
+ parsedValue = Clipperz.PM.Date.parse(value);
+ expectedValue = new Date();
+ expectedValue.setUTCFullYear(2007, 05 - 1, 10);
+ expectedValue.setUTCHours(23, 01, 21);
+// SimpleTest.is(parsedValue.toString(), 'Fri May 11 2007 01:01:21 GMT+0200 (CEST)', "the data in the format stored in the offline copy is processed correctly [3]");
+ SimpleTest.is(parsedValue.toString(), expectedValue.toString(), "the data in the format stored in the offline copy is processed correctly [3]");
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'onlineDataParsing_test': function () {
+ var value;
+ var parsedValue;
+ var expectedValue;
+
+ value = 'Tue, 27 March 2007 06:41:37 PDT';
+ parsedValue = Clipperz.PM.Date.parse(value);
+ expectedValue = new Date();
+ expectedValue.setUTCFullYear(2007, 03 - 1, 27);
+ expectedValue.setUTCHours(13, 41, 37);
+
+// SimpleTest.is(parsedValue.toString(), 'Tue Mar 27 2007 15:41:37 GMT+0200 (CEST)', "the data in the format returned by the server is processed correctly");
+ SimpleTest.is(parsedValue.toString(), expectedValue.toString(), "the data in the format returned by the server is processed correctly");
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+//#############################################################################
+
+Clipperz.PM.Strings.Languages.initSetup();
+SimpleTest.runDeferredTests("Clipperz.PM.Date", tests, {trace:false});
+
+
+
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/Proxy.html b/frontend/gamma/tests/tests/Clipperz/PM/Proxy.html
new file mode 100644
index 0000000..573dac8
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/Proxy.html
@@ -0,0 +1,65 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.Proxy - TEST</title>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Toll.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.Async.js"></script>
+
+</head>
+<body>
+<pre id="test">
+ <script type="text/javascript" src="Proxy.test.js"></script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/Proxy.test.js b/frontend/gamma/tests/tests/Clipperz/PM/Proxy.test.js
new file mode 100644
index 0000000..8a16a5b
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/Proxy.test.js
@@ -0,0 +1,117 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+
+ 'simple_tests': function() {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("simple_tests", {trace:false});
+ deferredResult.addCallback(function() {
+ var proxy;
+
+ proxy = new Clipperz.PM.Proxy();
+ ok(proxy != null, "can create instances of the Proxy class");
+ is(proxy.shouldPayTolls(), false, "proxy is set to NOT pay tolls by default");
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'simpleTestsWithTolls_tests': function() {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("simple_tests", {trace:false});
+ deferredResult.addCallback(function() {
+ var proxy;
+
+ proxy = new Clipperz.PM.Proxy({shouldPayTolls:true});
+ is(proxy.shouldPayTolls(), true, "I can set Proxy to pays tolls");
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+//#############################################################################
+
+runTests = function(aClassName) {
+ try {
+ var deferredTests;
+ var aTestName;
+
+ deferredTests = new Clipperz.Async.Deferred(aClassName + ".test", {trace:false});
+
+ aTestName = window.location.href.match(/#.*/);
+ if (aTestName && (aTestName != '#')) {
+ aTestName = aTestName[0].slice(1);
+ if (aTestName in tests) {
+ //Clipperz.log("single test execution, via fragment identifier", aTestName);
+ deferredTests.addCallback(tests[aTestName]);
+ deferredTests.addErrback(SimpleTest.ok, false, aTestName);
+ } else {
+ deferredTests.addBoth(is, aTestName, null, "Wrong test name selected to run");
+ }
+ } else {
+ for (aTestName in tests) {
+ deferredTests.addCallback(tests[aTestName]);
+ deferredTests.addErrback(SimpleTest.ok, false, aTestName);
+ }
+ deferredTests.addBoth(is, true, true, "FINISH: completed the full stack of tests");
+ }
+ deferredTests.addBoth(SimpleTest.finish);
+ deferredTests.callback();
+
+ SimpleTest.waitForExplicitFinish();
+ } catch (err) {
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+ }
+}("Clipperz.PM.Proxy");
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/Toll.html b/frontend/gamma/tests/tests/Clipperz/PM/Toll.html
new file mode 100644
index 0000000..7937380
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/Toll.html
@@ -0,0 +1,62 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.Toll - test</title>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Toll.js'></script>
+ <script type="text/javascript" src="../../../SimpleTest/SimpleTest.Async.js"></script>
+
+</head>
+<body>
+<pre id="test">
+ <script type="text/javascript" src="Toll.test.js"></script>
+</pre>
+
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/Toll.test.js b/frontend/gamma/tests/tests/Clipperz/PM/Toll.test.js
new file mode 100644
index 0000000..b54996f
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/Toll.test.js
@@ -0,0 +1,202 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+/*
+ 'simple_test': function() {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("simple_tests", {trace:false});
+ deferredResult.addCallback(function() {
+ var tollTargetValue;
+ var toll;
+ var price;
+
+ tollTargetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32);
+ tollTargetValue = Clipperz.Crypto.SHA.sha256(tollTargetValue);
+
+ price = 1;
+ tollTargetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32);
+ toll = new Clipperz.PM.Toll({targetValue:tollTargetValue.toHexString(), cost:price});
+ toll.pay();
+
+ price = 5;
+ tollTargetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32);
+ toll = new Clipperz.PM.Toll({targetValue:tollTargetValue.toHexString(), cost:price});
+ toll.pay();
+
+ price = 6;
+ tollTargetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32);
+ toll = new Clipperz.PM.Toll({targetValue:tollTargetValue.toHexString(), cost:price});
+ toll.pay();
+
+ price = 7;
+ tollTargetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32);
+ toll = new Clipperz.PM.Toll({targetValue:tollTargetValue.toHexString(), cost:price});
+ toll.pay();
+
+ price = 7;
+ tollTargetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32);
+ toll = new Clipperz.PM.Toll({targetValue:tollTargetValue.toHexString(), cost:price});
+ toll.pay();
+ });
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'deferredPay_test': function() {
+ var deferredResult;
+ var tollTargetValue;
+ var toll_1, toll_5, toll_6, toll_7, toll_10, toll_16;
+
+// tollTargetValue = Clipperz.Crypto.SHA.sha256(Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32));
+
+
+
+ deferredResult = new Clipperz.Async.Deferred("deferredPay_tests", {trace:false});
+
+ tollTargetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
+ toll_1 = new Clipperz.PM.Toll({targetValue:tollTargetValue, cost:1});
+
+ deferredResult.addMethod(toll_1, 'deferredPay');
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.ok(Clipperz.PM.Toll.validate(aResult.targetValue, aResult.toll, 1), "Payed a toll of cost 1");
+ });
+ deferredResult.addCallback(MochiKit.Async.wait, 1);
+
+ tollTargetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
+ toll_5 = new Clipperz.PM.Toll({targetValue:tollTargetValue, cost:5});
+
+ deferredResult.addMethod(toll_5, 'deferredPay');
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.ok(Clipperz.PM.Toll.validate(aResult.targetValue, aResult.toll, 5), "Payed a toll of cost 5");
+ });
+ deferredResult.addCallback(MochiKit.Async.wait, 1);
+
+
+ tollTargetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
+ toll_6 = new Clipperz.PM.Toll({targetValue:tollTargetValue, cost:6});
+
+ deferredResult.addMethod(toll_6, 'deferredPay');
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.ok(Clipperz.PM.Toll.validate(aResult.targetValue, aResult.toll, 6), "Payed a toll of cost 6");
+ });
+ deferredResult.addCallback(MochiKit.Async.wait, 1);
+
+
+ tollTargetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
+ toll_7 = new Clipperz.PM.Toll({targetValue:tollTargetValue, cost:7});
+
+ deferredResult.addMethod(toll_7, 'deferredPay');
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.ok(Clipperz.PM.Toll.validate(aResult.targetValue, aResult.toll, 7), "Payed a toll of cost 7");
+ });
+ deferredResult.addCallback(MochiKit.Async.wait, 1);
+
+
+ tollTargetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
+ toll_10 = new Clipperz.PM.Toll({targetValue:tollTargetValue, cost:10});
+
+ deferredResult.addMethod(toll_10, 'deferredPay');
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.ok(Clipperz.PM.Toll.validate(aResult.targetValue, aResult.toll, 10), "Payed a toll of cost 10");
+ });
+ deferredResult.addCallback(MochiKit.Async.wait, 1);
+
+/*
+ tollTargetValue = Clipperz.Crypto.PRNG.defaultRandomGenerator().getRandomBytes(32).toHexString().substring(2);
+ toll_16 = new Clipperz.PM.Toll({targetValue:tollTargetValue, cost:16});
+
+ deferredResult.addMethod(toll_16, 'deferredPay');
+ deferredResult.addCallback(function (aResult) {
+ SimpleTest.ok(Clipperz.PM.Toll.validate(aResult.targetValue, aResult.toll, 16), "Payed a toll of cost 16");
+ });
+ deferredResult.addCallback(MochiKit.Async.wait, 1);
+*/
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+//#############################################################################
+
+runTests = function() {
+ try {
+ var deferredTests;
+ var aTestName;
+
+ deferredTests = new Clipperz.Async.Deferred("Clipperz.PM.Toll.test", {trace:false});
+
+ aTestName = window.location.href.match(/#.*/);
+ if (aTestName && (aTestName != '#')) {
+ aTestName = aTestName[0].slice(1);
+ if (aTestName in tests) {
+ //Clipperz.log("single test execution, via fragment identifier", aTestName);
+ deferredTests.addCallback(tests[aTestName]);
+ deferredTests.addErrback(SimpleTest.ok, false, aTestName);
+ } else {
+ deferredTests.addBoth(is, aTestName, null, "Wrong test name selected to run");
+ }
+ } else {
+ for (aTestName in tests) {
+ deferredTests.addCallback(tests[aTestName]);
+ deferredTests.addErrback(SimpleTest.ok, false, aTestName);
+ }
+ deferredTests.addBoth(is, true, true, "FINISH: completed the full stack of tests");
+ }
+ deferredTests.addBoth(SimpleTest.finish);
+ deferredTests.callback();
+
+ SimpleTest.waitForExplicitFinish();
+ } catch (err) {
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+ }
+}();
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/UI/Web/Controllers/MainController.html b/frontend/gamma/tests/tests/Clipperz/PM/UI/Web/Controllers/MainController.html
new file mode 100644
index 0000000..6fbdcd6
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/UI/Web/Controllers/MainController.html
@@ -0,0 +1,64 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.UI.Web.MainController - test</title>
+
+ <script type="text/javascript" src="../../../../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../../../../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../../../../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../../../../js/Clipperz/Signal.js'></script>
+
+ <script type='text/javascript' src='../../../../../../../js/Clipperz/PM/UI/Web/Controllers/MainController.js'></script>
+ <script type="text/javascript" src="../../../../../../SimpleTest/SimpleTest.Async.js"></script>
+
+</head>
+<body>
+<pre id="test">
+ <script type="text/javascript" src="MainController.test.js"></script>
+</pre>
+
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/UI/Web/Controllers/MainController.test.js b/frontend/gamma/tests/tests/Clipperz/PM/UI/Web/Controllers/MainController.test.js
new file mode 100644
index 0000000..3953558
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/UI/Web/Controllers/MainController.test.js
@@ -0,0 +1,90 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+//Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+
+var tests = {
+
+ 'isPassphraseDelegateLockSetAfterInit': function (someTestArgs) {
+ return Clipperz.Async.callbacks('isPassphraseDelegateLockSetAfterInit', [
+ function () {
+ var mainController;
+
+ mainController = new Clipperz.PM.UI.Web.Controllers.MainController();
+ SimpleTest.is(true, mainController._passphraseDelegateLock.locked, 'passphraseDelegate lock is locked after MainController initialization')
+ }]);
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getPassphraseWithUnsetDelegate_test': function (someTestArgs) {
+ var deferredResult;
+ var mainController;
+ var delegateFunction;
+
+ mainController = new Clipperz.PM.UI.Web.Controllers.MainController();
+ delegateFunction = function () { return "clipperz";};
+
+ MochiKit.Async.callLater(1, MochiKit.Base.method(mainController, 'setPassphraseDelegate', delegateFunction));
+
+ return Clipperz.Async.callbacks("MainController.getPassphraseWithUnsetDelegate",[
+ MochiKit.Base.method(mainController, 'getPassphrase'),
+ function (aResult) {
+ SimpleTest.is(aResult, 'clipperz', "the password provided by the delegate is correct");
+ }
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'getPassphraseWithSetDelegate_test': function (someTestArgs) {
+ var deferredResult;
+ var mainController;
+ var delegateFunction;
+
+ mainController = new Clipperz.PM.UI.Web.Controllers.MainController();
+ delegateFunction = function () {return "clipperz";};
+
+ return Clipperz.Async.callbacks("MainController.getPassphraseWithSetDelegate_test",[
+ MochiKit.Base.method(mainController, 'setPassphraseDelegate', delegateFunction),
+ MochiKit.Base.method(mainController, 'getPassphrase'),
+ function (aResult) {
+ SimpleTest.is(aResult, 'clipperz', "the password provided by the delegate is correct");
+ }
+ ], {trace:false});
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+
+
+//#############################################################################
+
+SimpleTest.runDeferredTests("Clipperz.PM.UI.Web.Controllers.MainController", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/UI/Web/Controllers/index.html b/frontend/gamma/tests/tests/Clipperz/PM/UI/Web/Controllers/index.html
new file mode 100644
index 0000000..f3283b6
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/UI/Web/Controllers/index.html
@@ -0,0 +1,46 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.UI.Web.Controllers.* - tests</title>
+
+ <script type="text/javascript" src="../../../../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../../../SimpleTest/TestRunner.js"></script>
+</head>
+<body>
+<script>
+TestRunner.runTests(
+//
+// This is still a complete mess.
+//
+ 'MainController.html'
+);
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/UI/Web/index.html b/frontend/gamma/tests/tests/Clipperz/PM/UI/Web/index.html
new file mode 100644
index 0000000..9afa73d
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/UI/Web/index.html
@@ -0,0 +1,45 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.UI.Web* - tests</title>
+
+ <script type="text/javascript" src="../../../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../../SimpleTest/TestRunner.js"></script>
+</head>
+<body>
+<script>
+TestRunner.runTests(
+//
+// This is still a complete mess.
+//
+);
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/UI/index.html b/frontend/gamma/tests/tests/Clipperz/PM/UI/index.html
new file mode 100644
index 0000000..867362b
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/UI/index.html
@@ -0,0 +1,45 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.UI.* - tests</title>
+
+ <script type="text/javascript" src="../../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../../SimpleTest/TestRunner.js"></script>
+</head>
+<body>
+<script>
+TestRunner.runTests(
+//
+// This is still a complete mess.
+//
+);
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Clipperz/PM/index.html b/frontend/gamma/tests/tests/Clipperz/PM/index.html
new file mode 100644
index 0000000..acc45f7
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/PM/index.html
@@ -0,0 +1,56 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.PM.* - tests</title>
+
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../SimpleTest/TestRunner.js"></script>
+</head>
+<body>
+<script>
+TestRunner.runTests(
+//
+// This is still a complete mess.
+//
+// 'BookmarkletProcessor.html',
+ 'Connection.html',
+ 'Crypto.html',
+// 'Crypto_other_implementation_comparison.html',
+ 'Crypto_performanceEvaluation.html',
+// 'CryptoPerformance_ByteArrayArray.html',
+// 'CryptoPerformance_ByteArrayHex.html',
+// 'CryptoPerformance_ByteArrayString.html',
+ 'Date.html',
+ 'Proxy.html',
+ 'Toll.html'
+);
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Clipperz/RoboFormExportProcessor.html b/frontend/gamma/tests/tests/Clipperz/RoboFormExportProcessor.html
new file mode 100644
index 0000000..7fe9a84
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/RoboFormExportProcessor.html
@@ -0,0 +1,210 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../../js/JSLog/jslog.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/KeePassExportProcessor.js'></script>
+
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.Async.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="text/javascript">
+try {
+ var deferredResult;
+ var keePassProcessor;
+
+ keePassProcessor = new Clipperz.KeePassExportProcessor();
+
+ deferredResult = new MochiKit.Async.Deferred();
+
+ deferredResult.addCallback(function(aResult) { return "[Gmail]\nGroup: General\nUserName: joe.clipperz\nURL: http://www.gmail.com\nPassword: NHy08ZCMYsqUeLQCawR7\n\n[del.icio.us]\nGroup: General\nUserName: joe69\nURL: http://del.icio.us\nPassword: tS1cIEeqp5y0wkU\n\n[Amazon]\nGroup: General\nUserName: jclipperz\nURL: http://www.amazon.com\nPassword: wvpkqNPIsqlI5g6XE9Tz\n\n[Paypal]\nGroup: General\nUserName: joeclipperz\nURL: http://www.paypal.com\nPassword: 24T4wIcvHnM28T3L\n\n[Technorati]\nGroup: General\nUserName: jclipperz\nURL: http://www.technorati.com\nPassword: UcVeNqF\n\n[American Airlines]\nGroup: General\nUserName: joe.clipperz\nURL: http://www.aa.com\nPassword: AtrYbmi7lmSjR\n" });
+ deferredResult.addCallback(MochiKit.Base.method(keePassProcessor, 'deferredParse'));
+ deferredResult.addCallback(function(aResult) { is(MochiKit.Base.serializeJSON(aResult), "[{\"Title\":\"Gmail\", \"Group\":\"General\", \"UserName\":\"joe.clipperz\", \"URL\":\"http://www.gmail.com\", \"Password\":\"NHy08ZCMYsqUeLQCawR7\"}, {\"Title\":\"del.icio.us\", \"Group\":\"General\", \"UserName\":\"joe69\", \"URL\":\"http://del.icio.us\", \"Password\":\"tS1cIEeqp5y0wkU\"}, {\"Title\":\"Amazon\", \"Group\":\"General\", \"UserName\":\"jclipperz\", \"URL\":\"http://www.amazon.com\", \"Password\":\"wvpkqNPIsqlI5g6XE9Tz\"}, {\"Title\":\"Paypal\", \"Group\":\"General\", \"UserName\":\"joeclipperz\", \"URL\":\"http://www.paypal.com\", \"Password\":\"24T4wIcvHnM28T3L\"}, {\"Title\":\"Technorati\", \"Group\":\"General\", \"UserName\":\"jclipperz\", \"URL\":\"http://www.technorati.com\", \"Password\":\"UcVeNqF\"}, {\"Title\":\"American Airlines\", \"Group\":\"General\", \"UserName\":\"joe.clipperz\", \"URL\":\"http://www.aa.com\", \"Password\":\"AtrYbmi7lmSjR\"}]", "first test"); });
+ deferredResult.addErrback(function(anError) { is("ERROR", anError) });
+
+ deferredResult.addCallback(function(aResult) { return "[Gmail]\nGroup: General\nUserName: joe.clipperz\nURL: http://www.gmail.com\nPassword: NHy08ZCMYsqUeLQCawR7\nNotes: Personal account\n\n[del.icio.us]\nGroup: General\nUserName: joe69\nURL: http://del.icio.us\nPassword: tS1cIEeqp5y0wkU\nNotes: social bookmarking site\n\n[Amazon]\nGroup: General\nUserName: jclipperz\nURL: http://www.amazon.com\nPassword: wvpkqNPIsqlI5g6XE9Tz\nNotes: The US online store\n\n[Paypal]\nGroup: General\nUserName: joeclipperz\nURL: http://www.paypal.com\nPassword: 24T4wIcvHnM28T3L\nNotes: Linked to my savings account\n\n[Technorati]\nGroup: General\nUserName: jclipperz\nURL: http://www.technorati.com\nPassword: UcVeNqF\nNotes: Blog ranking and searching\n\n[American Airlines]\nGroup: General\nUserName: joe.clipperz\nURL: http://www.aa.com\nPassword: AtrYbmi7lmSjR\nNotes: Adavantages card n. 795495\n" });
+ deferredResult.addCallback(MochiKit.Base.method(keePassProcessor, 'deferredParse'));
+ deferredResult.addCallback(function(aResult) { is(MochiKit.Base.serializeJSON(aResult), "[{\"Title\":\"Gmail\", \"Group\":\"General\", \"UserName\":\"joe.clipperz\", \"URL\":\"http://www.gmail.com\", \"Password\":\"NHy08ZCMYsqUeLQCawR7\", \"Notes\":\"Personal account\"}, {\"Title\":\"del.icio.us\", \"Group\":\"General\", \"UserName\":\"joe69\", \"URL\":\"http://del.icio.us\", \"Password\":\"tS1cIEeqp5y0wkU\", \"Notes\":\"social bookmarking site\"}, {\"Title\":\"Amazon\", \"Group\":\"General\", \"UserName\":\"jclipperz\", \"URL\":\"http://www.amazon.com\", \"Password\":\"wvpkqNPIsqlI5g6XE9Tz\", \"Notes\":\"The US online store\"}, {\"Title\":\"Paypal\", \"Group\":\"General\", \"UserName\":\"joeclipperz\", \"URL\":\"http://www.paypal.com\", \"Password\":\"24T4wIcvHnM28T3L\", \"Notes\":\"Linked to my savings account\"}, {\"Title\":\"Technorati\", \"Group\":\"General\", \"UserName\":\"jclipperz\", \"URL\":\"http://www.technorati.com\", \"Password\":\"UcVeNqF\", \"Notes\":\"Blog ranking and searching\"}, {\"Title\":\"American Airlines\", \"Group\":\"General\", \"UserName\":\"joe.clipperz\", \"URL\":\"http://www.aa.com\", \"Password\":\"AtrYbmi7lmSjR\", \"Notes\":\"Adavantages card n. 795495\"}]", "second test"); });
+ deferredResult.addErrback(function(anError) { is("ERROR", anError) });
+
+ deferredResult.addCallback(function(aResult) { return "[Gmail]\nGroup: General\nUserName: joe.clipperz\nURL: http://www.gmail.com\nPassword: NHy08ZCMYsqUeLQCawR7\nNotes: Personal account\nwith some notes stored\non multiple lines\n\n[del.icio.us]\nGroup: General\nUserName: joe69\nURL: http://del.icio.us\nPassword: tS1cIEeqp5y0wkU\nNotes: social bookmarking site\n\n[Amazon]\nGroup: General\nUserName: jclipperz\nURL: http://www.amazon.com\nPassword: wvpkqNPIsqlI5g6XE9Tz\nNotes: The US online store\n\n[Paypal]\nGroup: General\nUserName: joeclipperz\nURL: http://www.paypal.com\nPassword: 24T4wIcvHnM28T3L\nNotes: Linked to my savings account\n\n[Technorati]\nGroup: General\nUserName: jclipperz\nURL: http://www.technorati.com\nPassword: UcVeNqF\nNotes: Blog ranking and searching\n\n[American Airlines]\nGroup: General\nUserName: joe.clipperz\nURL: http://www.aa.com\nPassword: AtrYbmi7lmSjR\nNotes: Adavantages card n. 795495\n" });
+ deferredResult.addCallback(MochiKit.Base.method(keePassProcessor, 'deferredParse'));
+ deferredResult.addCallback(function(aResult) { is(MochiKit.Base.serializeJSON(aResult), "[{\"Title\":\"Gmail\", \"Group\":\"General\", \"UserName\":\"joe.clipperz\", \"URL\":\"http://www.gmail.com\", \"Password\":\"NHy08ZCMYsqUeLQCawR7\", \"Notes\":\"Personal account\\nwith some notes stored\\non multiple lines\\n\"}, {\"Title\":\"del.icio.us\", \"Group\":\"General\", \"UserName\":\"joe69\", \"URL\":\"http://del.icio.us\", \"Password\":\"tS1cIEeqp5y0wkU\", \"Notes\":\"social bookmarking site\"}, {\"Title\":\"Amazon\", \"Group\":\"General\", \"UserName\":\"jclipperz\", \"URL\":\"http://www.amazon.com\", \"Password\":\"wvpkqNPIsqlI5g6XE9Tz\", \"Notes\":\"The US online store\"}, {\"Title\":\"Paypal\", \"Group\":\"General\", \"UserName\":\"joeclipperz\", \"URL\":\"http://www.paypal.com\", \"Password\":\"24T4wIcvHnM28T3L\", \"Notes\":\"Linked to my savings account\"}, {\"Title\":\"Technorati\", \"Group\":\"General\", \"UserName\":\"jclipperz\", \"URL\":\"http://www.technorati.com\", \"Password\":\"UcVeNqF\", \"Notes\":\"Blog ranking and searching\"}, {\"Title\":\"American Airlines\", \"Group\":\"General\", \"UserName\":\"joe.clipperz\", \"URL\":\"http://www.aa.com\", \"Password\":\"AtrYbmi7lmSjR\", \"Notes\":\"Adavantages card n. 795495\"}]", "third test"); });
+ deferredResult.addErrback(function(anError) { is("ERROR", anError) });
+
+
+
+ deferredResult.addBoth(SimpleTest.finish);
+ deferredResult.callback();
+
+/*
+ var set;
+ var object1;
+ var object2;
+ var object3;
+
+ set = new Clipperz.Set();
+
+ object1 = new Object();
+ object2 = new Object();
+ object3 = new Object();
+
+ object1.label = "object 1";
+ object2.label = "object 2";
+ object3.label = "object 3";
+
+ is(set.size(), 0, "A new set should be empty");
+
+ set.add(object1);
+ is(set.size(), 1);
+ is(set.contains(object1), true);
+ is(set.contains(object2), false);
+
+ set.add(object1);
+ is(set.size(), 1, "Adding the same object twice does not change the set content");
+ is(set.contains(object1), true);
+ is(set.contains(object2), false);
+
+ set.add(object2);
+ is(set.size(), 2);
+ is(set.contains(object1), true);
+ is(set.contains(object2), true);
+ is(set.contains(object3), false);
+
+ set.remove(object1);
+ is(set.size(), 1, "Size check after removing an object");
+ is(set.contains(object1), false);
+ is(set.contains(object2), true);
+ is(set.contains(object3), false);
+
+ set.remove(object1);
+ is(set.size(), 1, "Removing twice the same object does not change the set content");
+ is(set.contains(object1), false);
+ is(set.contains(object2), true);
+ is(set.contains(object3), false);
+
+ set.empty();
+ is(set.size(), 0);
+
+ {
+ var items;
+ var populatedSet;
+
+ items = ["item1", "item2", "item3"];
+
+ populatedSet = new Clipperz.Set({'items': items});
+ is(populatedSet.size(), 3);
+ is(populatedSet.contains("item1"), true);
+ is(populatedSet.contains("item4"), false);
+
+ items.splice(0, items.length);
+ is(populatedSet.size(), 3);
+ }
+
+ {
+ var items;
+ var deletedItems;
+
+ items = ["item1", "item2", "item3"];
+
+ set = new Clipperz.Set({'items': items});
+ deletedItems = ["item1"];
+ set.remove(deletedItems);
+ is(set.size(), 2, "here I am");
+ is(set.contains("item1"), false);
+ is(set.contains("item2"), true);
+
+ set = new Clipperz.Set({'items': items});
+ deletedItems = ["item1", "item2"];
+ set.remove(deletedItems);
+ is(set.size(), 1);
+ is(set.contains("item1"), false);
+ is(set.contains("item2"), false);
+
+ set = new Clipperz.Set({'items': items});
+ deletedItems = ["item1", "item4"];
+ set.remove(deletedItems);
+ is(set.size(), 2);
+ is(set.contains("item1"), false);
+ is(set.contains("item2"), true);
+ }
+
+ {
+ var items;
+ var poppedItem;
+
+ items = ["item1", "item2", "item3"];
+ set = new Clipperz.Set({'items': items});
+
+ poppedItem = set.popAnItem();
+ ok(poppedItem != null, "test popAnItem - 1");
+ is(set.size(), 2, "test popAnItem - 2");
+
+ poppedItem = set.popAnItem();
+ ok(poppedItem != null, "test popAnItem - 3");
+ is(set.size(), 1, "test popAnItem - 4");
+
+ poppedItem = set.popAnItem();
+ ok(poppedItem != null, "test popAnItem - 5");
+ is(set.size(), 0, "test popAnItem - 6");
+
+ poppedItem = set.popAnItem();
+ ok(poppedItem == null, "test popAnItem - 7");
+ }
+*/
+
+ SimpleTest.waitForExplicitFinish();
+
+} catch (err) {
+
+ var s = "test suite failure!\n";
+ var o = {};
+ var k = null;
+ for (k in err) {
+ // ensure unique keys?!
+ if (!o[k]) {
+ s += k + ": " + err[k] + "\n";
+ o[k] = err[k];
+ }
+ }
+ ok ( false, s );
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Clipperz/Set.html b/frontend/gamma/tests/tests/Clipperz/Set.html
new file mode 100644
index 0000000..e5814bc
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Set.html
@@ -0,0 +1,54 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.Set - test</title>
+
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="../../SimpleTest/test.css">
+
+ <script type='text/javascript' src='../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Set.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../js/Clipperz/Async.js'></script>
+
+ <script type="text/javascript" src="../../SimpleTest/SimpleTest.Async.js"></script>
+</head>
+<body>
+
+<pre id="test">
+<script type="text/javascript" src="Set.test.js"></script>
+</pre>
+</body>
+</html>
+
diff --git a/frontend/gamma/tests/tests/Clipperz/Set.test.js b/frontend/gamma/tests/tests/Clipperz/Set.test.js
new file mode 100644
index 0000000..8122b07
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/Set.test.js
@@ -0,0 +1,165 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+var tests = {
+
+ //-------------------------------------------------------------------------
+
+ 'set_test': function (someTestArgs) {
+ var deferredResult;
+
+ deferredResult = new Clipperz.Async.Deferred("set_test", someTestArgs);
+ deferredResult.addCallback(function () {
+ var set;
+ var object1;
+ var object2;
+ var object3;
+
+ set = new Clipperz.Set();
+
+ object1 = new Object();
+ object2 = new Object();
+ object3 = new Object();
+
+ object1.label = "object 1";
+ object2.label = "object 2";
+ object3.label = "object 3";
+
+ is(set.size(), 0, "A new set should be empty");
+
+ set.add(object1);
+ is(set.size(), 1);
+ is(set.contains(object1), true);
+ is(set.contains(object2), false);
+
+ set.add(object1);
+ is(set.size(), 1, "Adding the same object twice does not change the set content");
+ is(set.contains(object1), true);
+ is(set.contains(object2), false);
+
+ set.add(object2);
+ is(set.size(), 2);
+ is(set.contains(object1), true);
+ is(set.contains(object2), true);
+ is(set.contains(object3), false);
+
+ set.remove(object1);
+ is(set.size(), 1, "Size check after removing an object");
+ is(set.contains(object1), false);
+ is(set.contains(object2), true);
+ is(set.contains(object3), false);
+
+ set.remove(object1);
+ is(set.size(), 1, "Removing twice the same object does not change the set content");
+ is(set.contains(object1), false);
+ is(set.contains(object2), true);
+ is(set.contains(object3), false);
+
+ set.empty();
+ is(set.size(), 0);
+
+ {
+ var items;
+ var populatedSet;
+
+ items = ["item1", "item2", "item3"];
+
+ populatedSet = new Clipperz.Set({'items': items});
+ is(populatedSet.size(), 3);
+ is(populatedSet.contains("item1"), true);
+ is(populatedSet.contains("item4"), false);
+
+ items.splice(0, items.length);
+ is(populatedSet.size(), 3);
+ }
+
+ {
+ var items;
+ var deletedItems;
+
+ items = ["item1", "item2", "item3"];
+
+ set = new Clipperz.Set({'items': items});
+ deletedItems = ["item1"];
+ set.remove(deletedItems);
+ is(set.size(), 2, "here I am");
+ is(set.contains("item1"), false);
+ is(set.contains("item2"), true);
+
+ set = new Clipperz.Set({'items': items});
+ deletedItems = ["item1", "item2"];
+ set.remove(deletedItems);
+ is(set.size(), 1);
+ is(set.contains("item1"), false);
+ is(set.contains("item2"), false);
+
+ set = new Clipperz.Set({'items': items});
+ deletedItems = ["item1", "item4"];
+ set.remove(deletedItems);
+ is(set.size(), 2);
+ is(set.contains("item1"), false);
+ is(set.contains("item2"), true);
+ }
+
+ {
+ var items;
+ var poppedItem;
+
+ items = ["item1", "item2", "item3"];
+ set = new Clipperz.Set({'items': items});
+
+ poppedItem = set.popAnItem();
+ ok(poppedItem != null, "test popAnItem - 1");
+ is(set.size(), 2, "test popAnItem - 2");
+
+ poppedItem = set.popAnItem();
+ ok(poppedItem != null, "test popAnItem - 3");
+ is(set.size(), 1, "test popAnItem - 4");
+
+ poppedItem = set.popAnItem();
+ ok(poppedItem != null, "test popAnItem - 5");
+ is(set.size(), 0, "test popAnItem - 6");
+
+ poppedItem = set.popAnItem();
+ ok(poppedItem == null, "test popAnItem - 7");
+ }
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': MochiKit.Base.noop
+};
+
+
+
+//#############################################################################
+
+SimpleTest.runDeferredTests("Clipperz.Set", tests, {trace:false});
diff --git a/frontend/gamma/tests/tests/Clipperz/index.html b/frontend/gamma/tests/tests/Clipperz/index.html
new file mode 100644
index 0000000..b4c4992
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/index.html
@@ -0,0 +1,49 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz.* - tests</title>
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/TestRunner.js"></script>
+</head>
+<body>
+<script>
+TestRunner.runTests(
+ 'Async.html',
+ 'Base.html',
+ 'ByteArray.html',
+ 'Date.html',
+ 'DOM.html',
+ 'KeePassExportProcessor.html',
+ 'RoboFormExportProcessor.html',
+ 'Set.html'
+);
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Clipperz/index_googleCode.html b/frontend/gamma/tests/tests/Clipperz/index_googleCode.html
new file mode 100644
index 0000000..6e3249c
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/index_googleCode.html
@@ -0,0 +1,50 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/TestRunner.js"></script>
+</head>
+<body>
+<script>
+TestRunner.runTests(
+ 'Base.html',
+ 'ByteArray.html',
+ 'NotificationCenter.html',
+ 'Set.html',
+ 'Crypto/AES.html',
+ 'Crypto/BigInt.html',
+ 'Crypto/PRNG.html',
+ 'Crypto/SHA.html',
+ 'Crypto/ECC.html',
+ 'Crypto/SRP.html'
+);
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Clipperz/index_testECC.html b/frontend/gamma/tests/tests/Clipperz/index_testECC.html
new file mode 100644
index 0000000..46572ab
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Clipperz/index_testECC.html
@@ -0,0 +1,50 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <script type="text/javascript" src="../../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../../SimpleTest/TestRunner.js"></script>
+</head>
+<body>
+<script>
+TestRunner.runTests(
+// 'Base.html',
+ 'ByteArray.html',
+// 'Crypto/AES.html',
+ 'Crypto/BigInt.html',
+// 'Crypto/PRNG.html',
+// 'Crypto/SHA.html',
+// 'Crypto/SRP.html',
+// 'Crypto/ECC.html',
+ 'Crypto/ECC.BinaryField.FiniteField.html',
+ 'Crypto/ECC.BinaryField.Value.html'
+);
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Components/CardDialogEditing/CardDialogEditing_test.js b/frontend/gamma/tests/tests/Components/CardDialogEditing/CardDialogEditing_test.js
new file mode 100644
index 0000000..21b6af6
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/CardDialogEditing/CardDialogEditing_test.js
@@ -0,0 +1,238 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.Tests.CardDialogEditing');
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+Clipperz.PM.Strings.Languages.initSetup();
+
+Clipperz.Tests.CardDialogEditing.Tester = function(args) {
+ args = args || {};
+
+ Clipperz.Tests.CardDialogEditing.Tester.superclass.constructor.call(this, args);
+//# this._user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ this._user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.Tests.CardDialogEditing.Tester, Object, {
+
+ 'toString': function() {
+ return "Clipperz.Tests.CardDialogEditing.Tester";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'user': function () {
+ return this._user;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'run': function () {
+ var deferredResult;
+ var proxy;
+ var cardDialogController;
+ var cardDialogComponent;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+
+ deferredResult = new Clipperz.Async.Deferred("CardDialogEditing_test.init", {trace:false});
+//# deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data_newVersion']);
+ deferredResult.addMethod(this.user(), 'login');
+//# deferredResult.addMethod(this.user(), 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+
+// deferredResult.addMethod(this.user(), 'getRecord', '062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80'); // Linkedin
+// deferredResult.addMethod(this.user(), 'getRecord', '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d'); // Example Attack
+ deferredResult.addMethod(this.user(), 'getRecord', '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551'); // Amazon
+// deferredResult.addMethod(this.user(), 'getRecord', '507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a'); // MyBlogLog
+// deferredResult.addMethod(this.user(), 'getRecord', '6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728'); // Del.icio.us
+// deferredResult.addMethod(this.user(), 'getRecord', '6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a'); // Microsoft Office Key
+// deferredResult.addMethod(this.user(), 'getRecord', '6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18'); // The NewYork Times
+// deferredResult.addMethod(this.user(), 'getRecord', '7bb69b6366a8012f181c01e368ba18d4f7a82bcabb4959189736ad124c4bbfbb'); // Web Password
+// deferredResult.addMethod(this.user(), 'getRecord', '8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39'); // Jaiku
+// deferredResult.addMethod(this.user(), 'getRecord', '9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291'); // Home Burglar Alarm
+// deferredResult.addMethod(this.user(), 'getRecord', 'ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c'); // MySpace
+// deferredResult.addMethod(this.user(), 'getRecord', 'd620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045'); // American Airlines
+// deferredResult.addMethod(this.user(), 'getRecord', 'de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4'); // Luftansa
+// deferredResult.addMethod(this.user(), 'getRecord', 'eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5'); // Google Account
+// deferredResult.addMethod(this.user(), 'getRecord', 'f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732'); // Expedia
+// deferredResult.addMethod(this.user(), 'getRecord', 'fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6'); // Bloglines
+
+// deferredResult.addMethod(this.user(), 'getRecord', '5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4'); // WEB PASSWORD (0)
+// deferredResult.addMethod(this.user(), 'getRecord', '36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113'); // DIGG (1)
+// deferredResult.addMethod(this.user(), 'getRecord', 'c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065'); // SAP (2)
+// deferredResult.addMethod(this.user(), 'getRecord', 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d'); // YAHOO (4)
+
+// deferredResult.addMethod(this.user(), 'createNewRecord');
+
+/*
+ deferredResult.addCallback(function (aRecord) {
+ return Clipperz.Async.callbacks("CardDialogEditing_test.init - setup new record", [
+ MochiKit.Base.method(aRecord, 'setLabel', "Clipperz staging site"),
+ MochiKit.Base.method(aRecord, 'addField', {'label':"URL", 'value':"http://d6.clipperz.com", 'isHidden':false}),
+ MochiKit.Base.method(aRecord, 'addField', {'label':"USERNAME", 'value':"staging", 'isHidden':false}),
+ MochiKit.Base.method(aRecord, 'addField', {'label':"PASSWORD", 'value':"drupal", 'isHidden':true}),
+
+ MochiKit.Base.method(aRecord, 'createNewDirectLogin'),
+ function (aDirectLogin) {
+ return Clipperz.Async.callbacks("CardDialogEditing_test.init - setup new record [directLogin]", [
+ MochiKit.Base.method(aDirectLogin, 'setLabel', 'Clipperz staging site'),
+ MochiKit.Base.method(aDirectLogin, 'setFavicon', 'http://www.apple.com/favicon.ico'),
+ MochiKit.Base.method(aDirectLogin, 'setBookmarkletConfiguration', '{ "page":{"title":"HTTP authentication"},\n "form":{"attributes": {\n "action":"",\n "type":"http_auth"\n }, "inputs": [\n {"type":"text","name":"url","value":""},\n {"type":"text","name":"username","value":""},\n {"type":"password","name":"password","value":""}\n ]}, "version":"0.2.3"}'),
+
+ MochiKit.Base.method(aDirectLogin, 'bindFormFieldWithLabelToRecordFieldWithLabel', 'url', 'URL'),
+ MochiKit.Base.method(aDirectLogin, 'bindFormFieldWithLabelToRecordFieldWithLabel', 'username', 'USERNAME'),
+ MochiKit.Base.method(aDirectLogin, 'bindFormFieldWithLabelToRecordFieldWithLabel', 'password', 'PASSWORD')
+ ], {trace:false});
+ },
+ MochiKit.Base.partial(MochiKit.Async.succeed, aRecord)
+ ], {trace:false});
+ });
+
+// deferredResult.addMethod(this.user(), 'createNewRecord');
+ deferredResult.addCallback(function (aRecord) {
+ return Clipperz.Async.callbacks("CardDialogEditing_test.init - setup another record", [
+ MochiKit.Base.method(aRecord, 'setLabel', "Twitter site"),
+ MochiKit.Base.method(aRecord, 'addField', {'label':"twitter_url", 'value':"http://www.twitter.com", 'isHidden':false}),
+ MochiKit.Base.method(aRecord, 'addField', {'label':"twitter_username", 'value':"staging", 'isHidden':false}),
+ MochiKit.Base.method(aRecord, 'addField', {'label':"twitter_password", 'value':"drupal", 'isHidden':true}),
+
+ MochiKit.Base.method(aRecord, 'createNewDirectLogin'),
+ function (aDirectLogin) {
+ return Clipperz.Async.callbacks("CardDialogEditing_test.init - setup another record [directLogin]", [
+ MochiKit.Base.method(aDirectLogin, 'setLabel', 'Twitter'),
+ MochiKit.Base.method(aDirectLogin, 'setFavicon', 'http://www.twitter.com/favicon.ico'),
+ MochiKit.Base.method(aDirectLogin, 'setBookmarkletConfiguration', '{"page": {"title": "Twitter"},\n"form": {"attributes": {"action": "https://twitter.com/sessions",\n"method": "post"},\n"inputs": [{"type": "hidden",\n"name": "authenticity_token",\n"value": "b78a9460629980ed4c705fe94e6c4f37bfc32fed"},\n{"type": "text",\n"name": "session[username_or_email]",\n"value": ""},\n{"type": "password",\n"name": "session[password]",\n"value": ""},\n{"type": "checkbox",\n"name": "remember_me",\n"value": "1"},\n{"type": "hidden",\n"name": "q",\n"value": ""}]},\n"version": "0.2.3"}'),
+
+ MochiKit.Base.method(aDirectLogin, 'bindFormFieldWithLabelToRecordFieldWithLabel', 'session[username_or_email]', 'twitter_username'),
+ MochiKit.Base.method(aDirectLogin, 'bindFormFieldWithLabelToRecordFieldWithLabel', 'session[password]', 'twitter_password'),
+
+ MochiKit.Base.method(aDirectLogin, 'formValues'),
+ MochiKit.Base.itemgetter('remember_me'),
+ MochiKit.Base.methodcaller('setValue', 1)
+
+ ], {trace:false});
+ },
+ MochiKit.Base.partial(MochiKit.Async.succeed, aRecord)
+ ], {trace:false});
+ });
+
+// deferredResult.addMethod(this.user(), 'createNewRecord');
+ deferredResult.addCallback(function (aRecord) {
+ return Clipperz.Async.callbacks("CardDialogEditing_test.init - setup third record", [
+ MochiKit.Base.method(aRecord, 'setLabel', "R@cine"),
+ MochiKit.Base.method(aRecord, 'addField', {'label':"R@cine_username", 'value':"joe", 'isHidden':false}),
+ MochiKit.Base.method(aRecord, 'addField', {'label':"R@cine_password", 'value':"clipperz", 'isHidden':true}),
+
+ MochiKit.Base.method(aRecord, 'createNewDirectLogin'),
+ function (aDirectLogin) {
+ return Clipperz.Async.callbacks("CardDialogEditing_test.init - setup third record [directLogin]", [
+ MochiKit.Base.method(aDirectLogin, 'setLabel', 'R@cine'),
+ MochiKit.Base.method(aDirectLogin, 'setFavicon', 'http://www.racine.ra.it/horde/imp/graphics/favicon.ico'),
+ MochiKit.Base.method(aDirectLogin, 'setBookmarkletConfiguration', '{"page": {"title": "IMP :: Welcome to Horde"},\n"form": {"attributes": {"action": "http://www.racine.ra.it/horde/imp/redirect.php",\n"method": "post"},\n"inputs": [{"type": "hidden",\n"name": "actionID",\n"value": "105"},\n{"type": "hidden",\n"name": "url",\n"value": ""},\n{"type": "hidden",\n"name": "mailbox",\n"value": "INBOX"},\n{"type": "text",\n"name": "imapuser",\n"value": ""},\n{"type": "password",\n"name": "pass",\n"value": ""},\n{"type": "hidden",\n"name": "server",\n"value": "localhost"},\n{"type": "hidden",\n"name": "port",\n"value": "143"},\n{"type": "hidden",\n"name": "namespace",\n"value": ""},\n{"type": "hidden",\n"name": "maildomain",\n"value": "racine.ra.it"},\n{"type": "hidden",\n"name": "protocol",\n"value": "imap/notls"},\n{"type": "hidden",\n"name": "realm",\n"value": "racine.ra.it"},\n{"type": "hidden",\n"name": "folders",\n"value": "mail/"},\n{"type": "select",\n"name": "new_lang",\n"options": [{"selected": false,\n"label": "Bulgarian",\n"value": "bg_BG"},\n{"selected": false,\n"label": "Chinese (Simplified)",\n"value": "zh_CN"},\n{"selected": false,\n"label": "Chinese (Traditional)",\n"value": "zh_TW"},\n{"selected": false,\n"label": "Czech",\n"value": "cs_CZ"},\n{"selected": false,\n"label": "Dansk",\n"value": "da_DK"},\n{"selected": false,\n"label": "Deutsch",\n"value": "de_DE"},\n{"selected": false,\n"label": "English (GB)",\n"value": "en_GB"},\n{"selected": true,\n"label": "English (US)",\n"value": "en_US"},\n{"selected": false,\n"label": "Español",\n"value": "es_ES"},\n{"selected": false,\n"label": "Eesti",\n"value": "et_EE"},\n{"selected": false,\n"label": "Français",\n"value": "fr_FR"},\n{"selected": false,\n"label": "Greek",\n"value": "el_GR"},\n{"selected": false,\n"label": "Italiano",\n"value": "it_IT"},\n{"selected": false,\n"label": "Japanese",\n"value": "ja_JP"},\n{"selected": false,\n"label": "Korean",\n"value": "ko_KR"},\n{"selected": false,\n"label": "Latviešu",\n"value": "lv_LV"},\n{"selected": false,\n"label": "Lietuviskas",\n"value": "lt_LT"},\n{"selected": false,\n"label": "Magyar",\n"value": "hu_HU"},\n{"selected": false,\n"label": "Nederlands",\n"value": "nl_NL"},\n{"selected": false,\n"label": "Norsk bokmål",\n"value": "nb_NO"},\n{"selected": false,\n"label": "Norsk nynorsk",\n"value": "nn_NO"},\n{"selected": false,\n"label": "Polski",\n"value": "pl_PL"},\n{"selected": false,\n"label": "Português",\n"value": "pt_PT"},\n{"selected": false,\n"label": "Português Brasileiro",\n"value": "pt_BR"},\n{"selected": false,\n"label": "Romana",\n"value": "ro_RO"},\n{"selected": false,\n"label": "Russian (Windows)",\n"value": "ru_RU"},\n{"selected": false,\n"label": "Russian (KOI8-R)",\n"value": "ru_RU.KOI8-R"},\n{"selected": false,\n"label": "Slovak",\n"value": "sk_SK"},\n{"selected": false,\n"label": "Slovenscina",\n"value": "sl_SI"},\n{"selected": false,\n"label": "Suomi",\n"value": "fi_FI"},\n{"selected": false,\n"label": "Svenska",\n"value": "sv_SE"},\n{"selected": false,\n"label": "Ukranian",\n"value": "uk_UA"}]},\n{"type": "submit",\n"name": "button",\n"value": "Log in"}]},\n"version": "0.2.3"}'),
+
+ MochiKit.Base.method(aDirectLogin, 'bindFormFieldWithLabelToRecordFieldWithLabel', 'imapuser', 'R@cine_username'),
+ MochiKit.Base.method(aDirectLogin, 'bindFormFieldWithLabelToRecordFieldWithLabel', 'pass', 'R@cine_password'),
+
+ MochiKit.Base.method(aDirectLogin, 'formValues'),
+ MochiKit.Base.itemgetter('new_lang'),
+ MochiKit.Base.methodcaller('setValue', 'en_US')
+
+ ], {trace:false});
+ },
+ MochiKit.Base.partial(MochiKit.Async.succeed, aRecord)
+ ], {trace:false});
+ });
+*/
+
+ deferredResult.addCallback(function (aRecord) {
+ return Clipperz.Async.callbacks("CardDialogEditing_test.init - setup Kiva", [
+ MochiKit.Base.method(aRecord, 'setLabel', "KIVA"),
+ MochiKit.Base.method(aRecord, 'addField', {'label':"kiva_email", 'value':"giulio.cesare@solaroli.it", 'isHidden':false}),
+ MochiKit.Base.method(aRecord, 'addField', {'label':"kiva_password", 'value':"G0ELE0ngyTZf", 'isHidden':true}),
+
+ MochiKit.Base.method(aRecord, 'createNewDirectLogin'),
+ function (aDirectLogin) {
+ return Clipperz.Async.callbacks("CardDialogEditing_test.init - setup Kiva [directLogin]", [
+ MochiKit.Base.method(aDirectLogin, 'setLabel', 'Kiva'),
+ MochiKit.Base.method(aDirectLogin, 'setFavicon', 'http://www.kiva.org/favicon.ico'),
+ MochiKit.Base.method(aDirectLogin, 'setBookmarkletConfiguration', '{\n "page": {\n "title": "kiva.org"\n },\n "form": {\n "attributes": {\n "action": "https://www.kiva.org/app.php?page=login&action=doLogin",\n "method": "post"\n },\n "inputs": [\n {\n "type": "text",\n "name": "email",\n "value": ""\n },\n {\n "type": "password",\n "name": "password",\n "value": ""\n },\n {\n "type": "submit",\n "name": "submit",\n "value": "Login >>"\n },\n {\n "type": "hidden",\n "name": "currURL",\n "value": "https://www.kiva.org/app.php?page=login"\n }\n ]\n },\n "version": "0.2.3"\n}'),
+
+ MochiKit.Base.method(aDirectLogin, 'bindFormFieldWithLabelToRecordFieldWithLabel', 'email', 'kiva_email'),
+ MochiKit.Base.method(aDirectLogin, 'bindFormFieldWithLabelToRecordFieldWithLabel', 'password', 'kiva_password')
+ ], {trace:false});
+ },
+ MochiKit.Base.partial(MochiKit.Async.succeed, aRecord)
+ ], {trace:false});
+ });
+
+ deferredResult.addCallback(MochiKit.Base.bind(function (aRecord) {
+ cardDialogController = new Clipperz.PM.UI.Web.Controllers.CardDialogController({record:aRecord, delegate:this});
+ cardDialogController.run();
+ }, this));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'saveChanges': function () {
+ return this.user().saveChanges();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hasPendingChanges': function () {
+ return this.user().hasPendingChanges();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'revertChanges': function () {
+ return this.user().revertChanges();
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
+
+
+init = function () {
+ var tester;
+
+ tester = new Clipperz.Tests.CardDialogEditing.Tester();
+ tester.run();
+};
+
+MochiKit.DOM.addLoadEvent(init);
diff --git a/frontend/gamma/tests/tests/Components/CardDialogEditing/User.data.js b/frontend/gamma/tests/tests/Components/CardDialogEditing/User.data.js
new file mode 100644
index 0000000..8065144
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/CardDialogEditing/User.data.js
@@ -0,0 +1,1881 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+testData = {
+
+ //-------------------------------------------------------------------------
+
+ 'simpleLogin_001': {
+ 'users': [
+ {
+ 'username': "joe",
+ 'passphrase': "eoj",
+ 'version': "0.2",
+ 'connectionVersion': "0.2",
+ 'records': {
+ 'record 1': {
+ 'notes': "Some notes here",
+ 'fields': [
+ { 'name': "username", 'value': "joe", 'type': "text" },
+ { 'name': "password", 'value': "1234", 'type': "password" }
+ ],
+ 'directLogins': {
+ "record 1 direct login": {
+ 'configuration': "",
+ 'bindings': [
+ ],
+ 'favicon': "http://www.example.com/favicon.ico"
+ }
+ }
+ }
+ },
+ 'otp': [
+ "12345678 90abcdef 12345678 90abcdef",
+ "fedcba09 87654321 fedcba09 87654321"
+ ]
+ }
+ ]
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'joe_clipperz_offline_copy_data': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ 'f527cdd90d0d47f8524b4e165398ad1455eba515d04abd101d1e93b3c6ae0674': {
+ s: '186f0c40bf73f2af236eaa6c429df225efa933050c9aae65240e93b7b362e3ee',
+ v: 'ac61a6e325ecf329926a86084f591d8852d0ad3e4a6080f2adc901b82395ecaf',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5":"0","13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551":"1","062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80":"2","ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c":"3","507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a":"4","d5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d":"5","de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4":"6","d620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045":"7","f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732":"8","36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113":"9","fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6":"10","6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18":"11","9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291":"12","6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a":"13","6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728":"14","8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39":"15","084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d":"16","7bb69b6366a8012f181c01e368ba18d4f7a82bcabb4959189736ad124c4bbfbb":"17","5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4":"18","c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065":"19"},"data":"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"},"directLogins":{"index":{"61e87fdc4f1d9112e3b30c1f6812d095dcdb24f014c83319091eb6c9899ec348":"0","989593d4c48929f0c8f1581aa96969c622807e99619ed4732026e967530a68ad":"1","9f7979368fa29f66c44bd97ecaf6c545abc800b1c7bb21b7655a68e1514c3906":"2","dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496":"3","aa18149164302d5dbe7e2d3724565b9550e00887b49978559783b2e38c625584":"4","1f9bfd677b531a03168d3f8bd8afabb5357244a7bc355dff50bd6c0a072114a6":"5","a48e38845713462ecc9f827149eeaae87da882031f98ef8ebbf9ee9537b63468":"6","6f7bbc4e42ea462b5246e6f51c3f86056bec50601ce2de6067c8c1d26f21c07f":"7","2df54059e78f5771f23bd285cce19595b38331b73d67020424d9a1b2257db09c":"8","065cd0c270e5e8ce50e4ea8e3828dccdae18c01ab030813d756a87d03fe68784":"9","ddbc8d01300a4f10631cbde09e1246332eade3a877a2205209f9eb9e5bc9da0b":"10","9b7a30e667afc9f76ba77600658b2c13bff52432d444261d39bf3d069a160afe":"11","9fd2929cde3d32d9cbc5f1d787f2f64729a5e12a14410556b31c0c099762c46a":"12","f695fc36ac56bead80c0d20a88e01e382819c18dc268f1679551b7c83db7cb14":"13","f22dc41ffabef4b3bc8f7af804fec975bd50718098322a673cbe4aaff9464ae1":"14","03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c":"15","a7b32e72502804bf2946a2a8856139cbbb759c5777e6b3e673db1fdf7e3bd06e":"16","cb9ae0bba1957075ccdbfd3b3481704d62087687a2ac7c411a4f07d444bde0f7":"17","7e1d069b7fa57c03bd7bf48807520feb953157834503aaff8c9d493f37dea69d":"18","24404059cabc63b2dbff0f42ba57183108b8189ef53ab62fa25141a1caea824b":"19","33cf9758477460a8056deef0295a1ebe65b39b392c361ceb920a83edacfe5d78":"20","e9a16316f330e3d150f6ffd194f6fd8acd1426757b097de4b88ca0db875202e4":"21"},"data":"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"},"preferences":{"data":"EZMrwxNFFd1sMGycoYE7IrlGGrfLixLUnLZmWMkFysfISe2ay3ueO0PGCApuKqh9hA=="},"oneTimePasswords":{"data":"jufmL1KVY0YBl8MSaL413hGtw12I/+sFnumcfeVku9RRMBmXaXCfE/vYnraxZyPxJxVS3qFRWDKsSGR3pScdACSwlBD+mzjifRn2SCfXWutD1/oJiqiMvq3YFzwyZJiXx+oS5u8DOTieQT9HZYt0pUmAod9QHiq2NAkueVjvRkZI1saRlWGtNXCaJIHwpuFJpHBDSD//6D9DYeTdVUeFEbej+4oNYpBCkyE1G2OL6q50YRBYp9yARRiy9juKHRWFvZiSeMGEJQS0f2gaP+xZkb9Z4qrfDgAZ1F7oDbPksr2SOYlSsm0bqa6c+7Wtopdo63Urf7Ze3Wg9n8TGBk6H88boseR8e3sHudlmtO1oLxcB9p3z/NTceF6SvWyJWTxHeMe6O72dZVmSnZlXhD/IJamRt13HLk3g05d8oXfrXM3iMhIGQ+EsXMxZfKdXlZpyYtjWD5tcQTKz7M5Qo3SFmdkwDu4jH5ke+bD8CeluDcMaHF6KHfdV8nEsmsjGwrH6lqSCT/9kBO5ETqUJKloOhJpFpNS/EN7nxjXF/QbqnUmWV4wngdyYmk9goNZNfZv7C2ouiyys55/QEfGsIsvEPPSfO670oJuncTyfFngFj2tdh2JpJ5vytuoRNLOm7XPM3hDCvZCOpUnjbm+jt4AvdOGU7ID8a2mtZFjb2noP5emAxTg6MO6f3+44eTkUcbCDskO5fe6jd0pTdODk21Ilp7WUjFwxEdJG8tRrGYpLooProJExamL7WShm/S/nhJL4+euW+1UIDjcZJA+a7aGdMSC63qBvrEsNyf57SDBk/o2eNJHs2sndCzgvK42IKGKcipq9D1Gyos9JQsA3My9ARMt68V/5FfzOkgPO6mblOsQMoTyQj/OCLzITEBfqA5IufhljSEkD3CLkfkeVwVf1NB2SsTPXJFChnynfsK7cMFy0O2XBNByCRTQDqBDBYo673tI1KTGnT4gLSAwCt96lq8UkEdt51jjkAJcvBXkbswuw3hvhtzLJ302hkN9CIHJrEN0oss5mWlxIxYrCyqE3ABME3FCR9r+V7exuIaQn6mdJTkMcRbYmVQQkexsROh2cdx8I/tuMN4ECWEAL948k9vEPZfgaQirWnrTtHoxLzNAUBDSQfzYXd8yr0T4vAHLnXaUalWPgLamJJ3eR+LDFcDQVvFkaomsF3RpOIS5fswTBFuRKGKEBSIINc9AyC4DtkSmDMTF2S0TgpnGdK94ZS8C/PM8WEsX738echa5qZG5qG0f+koOUUrbaORcDqaktCuDmsgFTYiUv1JxFskTvS/t/EM2Y0MEKVLZBsoG+4WXz4XEE0VJFoI9glaYll96WH/iMbaVXRnDwjyE62CAk/8DXIf//MJQVyO6ElFsvCrDfH03yLpCJhqwHv+mD5sRctVaq6Cp5Ts3bzdFeiLCX9rhSaqdG5AuMk4dCInlywxrsOvBfNaDBjX7NGCULri6px2T53FNiH6ineVjr9TfgY2uoMyevLiQsGd3GHS4wnxiUfIyz7/Yav5an4o82cHhMVOLvfKwF8C2dJQDg9woJ3ju1ha66UA2XGScJVd93w3OWco78+giXBE96R3CebxgaWQ5Zif6nI+FJnw6OipaRgd7EyrLrQTWadvTiYLfDknlsxFZd4XVs33/3xxF3RyoVsIFO7cpEX/BLVB69v+1TJvLdiyGwSl5FUKbrcrXycZ67uTKtHyAI/vrzwwoQxYV8e32xW86blEjH4pq/Zrijm1wGw7IrD9fYVgEO7nnWpE/ac85LrDaJpGOdZ+slcVWM6THHR9boKJGLtuc8V81gDVNtZ/f4Hx5YXZWKIIfpe57BybWejdQ8ZACWK+mXOGczyXJ88B4nIvaKnRlhSszQryAZzSqJry2k3t1v73BzL48TZWJ6yu1rFmqAUk2V5DCA4XnyHfPuiG8hZfTuu1YXQ+iBgbyDipTwozQqyTv3SxLBPTFxKZLuabMn7ZTo/kLXGfVO/2va58bv6kzW6WjwZ0D481N1Nyd1kZUw1lyxXklcAzZqaHUiIsy+/5DgV/qULYFqEBMNMA7QvBfRN4VZRlnNiemgzkBQXj+JGJOWZMz5cvss291rj1fAe91s10nkZoaddDrvfgfjTq6n9XLSyGSmnrIDMLVc9+YuDtuaQ4gwuiLG2X57Jzrc/Xy7jdZ82G1j+cfT/8Pvb40i1K9aid0Z3xl/tm7jBAqQ91Ehkbo6c8jUVPaQsRcfTumtsNf+Xa5PJmQtEGEPCUlGN6F7eFB5eOLXQFdsLRL1x+SzhS7k3aDri9sTMwYQij26AexwwzAPqcOOkkfbYf0lov5Gxx0LhsZAetDZCRFlxjDRDS8jE8dKBBXkWFazF8K2rdQXKNlclwezCEDBwUWhoJs/H5ndJ38MpSPfKo1YsVvlxi4QFyOTDPJIstCCvYnCjj1r7SrkRrbcuevITRTxD4FKgPCdsYFlGfhS1zWb23DWYWo6fPQ1/zlnN01gZStxsZKepB3NnxbTSjBgTSmzG6RzZajv6BtqivtvOa1hI2KZQtVGCDU2+NGmfbJ5TTJehYiTEPeBF9TfLRP9rktQTUngj2ohv+1TDL0jL3YWiSA9TJzYonsincEVy1aRUeGVazWF2Rrq2o4hCBp12BfuMGHOdVkg9rMXdusyl2y75YyEkcBNMz4zi8i1lVhjUg16rCR48uKJ9QO2KBbjoGTx13uxIXTR8ufXx6mW7iW3qVx+6k7BQGKlMo1G64O8HQ2UrboS/tCqlP0W+7XB2C3EaZMqfKeYcuzM4MLkM6CT2GKYmJPyevXLKE749BM8zRQUcrWieAxmyD+g0QQ4T1fl0RTNEFB1/0BIg3fQQHCLGUTahXwt0EluG9iNPVgmFwwBHybH6gmIEZ4xnD8I7QPwgYY3JF407NdLkHjOuXrP+GODGEvX49MMaUigUUO2fkdw9EJbaidhx6j1EsFpQrz4Lt/5sAu5c9B/365TXtnNnmaPkaFj1q+3ezVXUroimRqxZ9BMaTm7J1hjubO+Dxjb2QlR/UApvQ0ty8aZpmIrMi0xjfoodIMiH6IYdw3VRZSqup7irWWpnJhef2qqtcpoxdiYZaFyf5u2XpZqEnAJpTupqOg+qJN/7aQt6ZmP7POFPwUwzwAsfTYk2EwMlTVAXrawZZEYu2JZ4kIjazo1LgyuuWTieEuONnye8Hr9p70RjwWUdlErlPSCKKn6JRdsM2no13F3151cfgx8I02J9vDuiNa3vfJfmRnBOly5jq6Wlnm2rJN6YYQHwbikoq3lJvkX5ZANDRKFlMWKK42+fXLBuofAZShFt6xvlY384aYsv3EcR42GOLrgYPQy0a7lr/FS4mM2ErNwNYnCz/xTuPBjgXXplbAnyA3jpKdPN1EfUM1oA4kZjECmkXZOuyEQxrndS9eOGbPM6S131zpdWEw9dWSZdkSI34+OkLfAKf6W6z4G4Z+cMRrkYLHs+BavJOum4XTjyyXHIKhQiqz9mgEf+ulodXi+LNsbq1eCcGPWrGg+GNwN1SjJHZm78gidyrlEF6xuPCaZRvGQtk59nuJULOZWkC3Ns/EcFiAql8cu37Lp842fsHHeCVOq0e8ZII4TPg9HKPwDD4HLSg4frBzyeZwK0nN30C5ATCxWdL4Q60cKtZyIEM7Kn1a/vifsAbe019Ui3ovTOCYiTCAdOLaAL/NdpgWA/fDNOsTlPvnEYkq+4+bV3Wyye9ddxICD4TnC2yvXvjw4C/WnYYceJy5R4KamIJueEGIHGp22/0DSF3H4ji3QoUDiFB/H+CA8A2q9LO9q0NYcf2P5q2MfdJGu4bd49g68mltj35pRnGQaafflXY9VmMfrlAbBYfUnsKOb3DOUpq8asveE41/6WkGcXFIuSABcbBf0cHIfBn41wRWQhoCm/JL8pfqEZC/paBdFBRW4FjKkxhbg4BPvBL0aQyGGkU8eH8tr8nm4YN1HMFF/s3s8+9FPoBxPuXLoGSg7Rvdz+g=="},"version":"0.1"}',
+ statistics: 'SfGy/4mpXQdDOv+Bcfie4Yt/',
+ userDetailsVersion: '0.3',
+ records: {
+ '062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80': {
+ data: '7sgxSQlqR+wh3g06M2+sWp7raQxjjQ9jLIz2OcEB7SckuQcXNrhMlDCbL6ncSljtzgqhioWrOB409kIG8lc7h6ekghOE/Mhi7rVwAiRfNGB7r3mYxpEXRe96O2RG7E+NcSp8ezl+5gJ9D0o1abXPeFQYGcr95hUioCfyY+xrxY8TJVwdb9nHkYvBdKV7rCl1dTxgsKWK3nlo1T7e5uyiz5YUAE6BrCtTFAqtprLI/xOpRti9C+llohS7D6s8hkCBPZfp3chKFDrgpsCBFLhXN8jrBKSjHi1PJdRQzpJsgrxyeBj0dZx3gTsYOXqrYgdIzFUo7K1Tqb30yNprBiDMr7j0YYXiSvEb7OuOIP+HTXGN+yt09bk9LggyY6Fh0e+tenjQQ3soySN/XznOBpEjXbzXoz6fR1MXVnE9GgaX99LVNqwWfq2rIBdSE/FfspRiWP3BY5jIrEkNeRclS05U1zw3K3wxOL+cB9r2IynSXnK8QcrDNNRZ0W3PhsSFfByUXuviLSEOPuJa1mYP29L9Lj/WyHL1Gyl8xLbt2H41S6+wvIleKMuc7teH6wPXbnYphvbwBowoI6HZTEFkz3dQKhhY6VF/81iCXsuaz6BjyrzFX6SkQ4S3lN1tv4opQMJFvnmHb6EkXqVWfeIXzJIJO+owL4vDOf4okpAD+HPjjlVXhq6fvyM5UBIK9+tzJW78X/zifrQOfWRIhwjVsfUdZWmZ/S35vnHWNuXkM8GBYrDysqxanDtah3U8XLAiIhFtBOzpzr6qGaNDOKKgG3K8QXT4bYHOq1rQVUwzQuKhlCyStrRMQrC5Ry251xmLy6dKfppRarVeGDtzB/30BbtFNdZmzMNG2g+Jj5tFCrEtCMvMiQEWZHMU3tGMFxDef/KKdv1fFTJC16jmaUiCHUZmNjB3EO9R6xPVcMlAVKf57n3efrpRk/GTmm9JhAFkuF/wsveH4JjPpDUdkHYFu5tHbb30sbga3ufBAXbQL4ck10S24akU/cKraFGLvuKGaR2U0i6ih911TBSf3pAfZ3RFbBhVIl+6rSknC5+IXoBR7MRstBPW/xC9pQVjN5Qyn0g3aUjUSI+q4jcTuvMl32NtTJbWRMGhfkrpVzypZTyPnIh6XJkyBghlUARXw23MlbjiZxmY4ScDmcWZRZJWIknHlqjDKFDKNnwrfnEI9qWyMDno+jA/DEQz0mnpdZYEsoz1/qAmAeDt89vx',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009',
+ currentVersion: '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3',
+ versions: {
+ '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3': {
+ header: '####',
+ data: 'GCNNIhDQjMJQZGVSf+95fPtU6eOnFWVhuGm86r8WZGVR2Gf2EjbG1OJ0ZIGpZ/AXgirCMpo5AFxJe0Bay8IYg+xmBqMFhwFxzAgJBYCIts+raSaNRipuY8dTEqDxAqD1cChcG8EhSoiFgQ0fG0I7nNEUDJi0pIt4/ygBcwvAhuAenEp9ZW+oQA0+YysPQRqkz3IieFaOoSEbe5/SqpUilV4q1gTVyzNXvrxzxx+rlvEyGFgFN+vgtUZ1NrwlPk4gVksTpylvv6CFaMGEWKhgMG6efo0rJckKosaJTu1pldJdnmMK4EKNMLOd+jZ6pEhEhYyadrA4+zYU5TlmZA6ASzTaps8piSwZodoi9qY0ch2StK4mAbzeEGe2HdfHuAU9Tyq3Ppk3+VfNdKgpQfYrQOiSlXbKzK636tzXTN/gyrfOTHjBrRl117ywibgSX63ayAYNfcLpKotC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ }
+ }
+ },
+ '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d': {
+ data: 'fGzBu1On7e/6rAoSB1a4fq/CkS8Be/T8UP5cQ93asBTWndSYu2lW4DQ4SXQXSindIi3OnNx/f6SNv/extb7OrMLREF92wXI045ipPwy+DIICb+cQNMJ82Sh4cXaIcAWcyrm+MYri3qq9LBKbpwkILcebZidJ86lmKYHJozUezmfbMcwNCljHs/gYkHVzVcuw9L52Ugc6wC7sjsshh+UH6i4/2Frlrophtx+b1vervNd8eoYiKnedHVXVfW7UJcQoF27eHFgzwYnGvRW0KNXFFhqmPb61TSkIvNdCCvBKDP4SXrWvGgzU89wipvWdUPpQ+fCT6Mp3hPRrbJxwMunmjujZOzBld/HkjnXoiNfBb5akA280WvdyzWYATrjV1ZFx8yQY8G0+lRt/MxjKDc38w4y+Rf5WeRbXboJMvFatwooHUggk6qSRmZVvgOmFmNuDRnRYIFzqK3JclhJeVasnqhR6RiGSowc1Ffr1HhcZCMnXpQABGBkZcHD/zw6YjHRyh9Plw7XAm0xb16HMDtiwt7WLJpxLH/HP99j/A2hvMGWiUiFCaYv7AzyEPTmYbN32D1IsAEE/GC3FG0HypGTBolP8wpAfTRdlvWpJz8oRRdwuLV3Pgpu+kXh5sQyeZI6tnuMPQFmRDcMN1oo3E5V5V585nVMnKTFcXhBzD4UnoV+DQNkG/+iSPybQzz/EZmucEqGEYyjI3kl4MAX8UMEUxE4JO0fF8MzyBI13nxknowAceEammx1dGVaJCoIOdhadaPVPyOzXM1Vp1erVm5k4TsxSx1pll+GOm6hVoNHIuQLDueaMEpRxMhfwc8cDyXURqRGPTgTc0bint5xVjo10fnpX1gcdc/AWL6y3tXM80NW+uFJ4GI7VzyzfcMRzTiRaGi19z8MIx8PbIVGh2sw4FhgGujNsPrpuESvUVT+17M0+v8oEoABNlcizTMFs/sA1uqlPumFASltzmViAzClOsDuCh069hFLjdk/Ex5jy4vPYlwOT8Uq9DJC9ZWuZgiI1DrhWN/8QGAEGxxbvnSZPNCQ9kpD5p+iabinLLWOAirVNgKwIRJRyAu/uR9xKd7J9Wxq8q/ii+y5lGilbo2g24wbDwrkXYVhqp/4J0g+p8Wv1NBjCTSCqV39WEizUCRHo3ee9HnQnBJQDOyTBRuz2odTJtJ5tLYjWXZRdFzFSJrEq+Z1z3oq7LnhZy3YWaFXPeKmBCemMthtNt0nL',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ updateDate: 'Mon Oct 27 08:58:49 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:39 CET 2009',
+ currentVersion: '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac',
+ versions: {
+ '0ae362285f103722abbd046eee2b7d10aeae6a1d05cbaf2081392ce9df882bcf': {
+ header: '####',
+ data: 'sG6TUmPSEPFpiJ5YdtghWHmHbvUK63tZCZ+Q5iz2ALas//jN+lZCBhZcjEwPEJskBkK2R0MyAh14wWGh2bBHMjsokgTe+L+x+0c/Zi0epE/IC9gtOBhsTe/hZ2e2xOGF/SbzET3DAAYXvxduZ36f7SvvFnrkkKvpj8wGSdTFcBmzqMb9DL2bRyRCLGLMzE3F1a0q5CufCIRz2TgHm+Uw+kfvvwC7ig/F/5iLW90Ypz3vmEtMEFYFHZ9a8Oh0rsXGfevbMhFqALoywzihQEe/NiB8dwn7GEdYKSQ35rhvZh29ULWOZinqmg0ONe0HYaxx7DbKsVoue57S0CIUlgHLajzHfLfqQg2sFI0OT8TnHsGg0YZ6mM2EdKmEjJiER0cP',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:00:31 CEST 2008',
+ updateDate: 'Fri Oct 17 17:00:31 CEST 2008',
+ accessDate: 'Fri Oct 17 17:00:31 CEST 2008'
+ },
+ '10f45664bbd979a92f37886f1ecc6e52e49798b16dc997aecd37259ad9b2090e': {
+ header: '####',
+ data: 'RdKVaV/WWWchrCse3KtcXd47Bfm6IAwjqVUpaxoed3HeunI42AAm7xYYSjeK8edHpbNRJbhobBAX5OZtWIp/HmgkobKM8CIiWxrWz89FqyrbnPD7+fXdtgF2yTax/0sC1l0ibncdOuJKX6U829oPlXCpXIOjlomc4wEEAD/5V6FbORvdZ9IE/ME3LsG2y02cT2tIpx6+R6wC/PKXhZA2UDsTE6R2Op2BtIzpVORZLXsdyAp/4wvWQxq90i9cEpbsVQsMB10JVyNHNsRTFhIlHi9MVCaMxQvcrwRElMj/Y9x3RbsFzSGKqFLqdg7Fn/U+KYkpYtsgHv9hraPIb9lV5FH16+iItU/HBM6FGezIj1ZkoQ+dgjPfSjTZzgzDYwyb',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ updateDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ accessDate: 'Fri Oct 17 16:54:23 CEST 2008'
+ },
+ '2fa7b67e569d5e268d2b70b3d4d3a960d7e437e1937bcb324b67d0b9441db8ba': {
+ header: '####',
+ data: 'dpnI2qKjk0+bfyKktw4ZCWf+rWZ12hO5bda39CwD29JH7KtdpLCLe2LoLd+KKF2wOdpDsoI2iTiwRgFpt77e7DoWJABxq/0aaRCVN9XpqZo08iHiYhJyNlIszO8CdEhX+M3AeZqzTnd6fs91VfIEWggvku2Z+jwr0CbclY6FnOcNnS+1fj+W79Z9XC383GOm2ujjfo3SX/fyNQSw8aX+7AgJIRGR9uHK7M1cVfsNNTbmDb/HDgLlYZ1Pqm/9poHpmS7G4HUoRM2/WjI0R6F48dy5s8vZRi11SCnlnj5oRykScJj6wh2DltbCyesiaTpAjP6MQjTXsZzKpaosaQcQClZw+w6hDD2cA54IaBIv2j5KAHyhxDh2ERdwbdnCsDKPz4+zP+fmKfW295d4OY0l1NCSdcY+75HWTmBWRAooZeDTo7AE8m5sRwxewE0Y8J2MLUYsrs7Rl4kbZCiRRHU7cs+us3fq2DVn2OLGEbkRrK3kA9swT9W8ABqINoA79+DmDaIr6TGxe5AlHkCAl5sYAN4g42UX1NKhl4fWI1Scj9O1Ixds/1UUvqzavld0mE2cR9yt6LntjE5sQSAaexvymAJbU5IIM5NTk7NlY7G3PEvAPjcUsL9SGw==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:00:13 CEST 2008',
+ updateDate: 'Fri Oct 17 17:00:13 CEST 2008',
+ accessDate: 'Fri Oct 17 17:00:13 CEST 2008'
+ },
+ '5a17723c34226d8cd663f91b11bfa14979e694e461818113ec8abf7194b46b6b': {
+ header: '####',
+ data: 'yRTvhkoY9zDRBwFYf0G5U8zhfS1XWIUfwes6ADNnFyOrHOr7JZvZZHSgkOPnsmN/f5ngcvFaIV9X3TNTmmPLzD/ewgGVMR+ofMLyOIMGhxUDzosSd1+HKqwDZWneZ6xNsci87W8UCfJgoEGrkAtAwktqyS04pcAas74XiRGBWNcv5mHZONwGPckYUnnaVG02Zf+qif6Pp7ugdvXrgncO5oi2AMSoR8GQxMP+tX53YzLwOpabA32PDT6o+aDPwMstJNQjWCXjeYLDIlb0GjL2zgjglX5CfdGw8vNT5hwGEK2D1FkvHkw79m++9sOWd5w9WdGgtS4mrTZP3JHWC1sPqvsIpq6PsrzRrbfCFH7C4X/ya5ciOIZTCNl4dEGAif94zgN74ueY5BF31PNFtaRaQ1waKkbsrU63MrbQbBar9b0hDZoser3BdgDGb1Ecc2GbJM1HbDITttmFDrzy/Ugh2kistHx7Dci8IGgfT7K94TntRFc5R6suEqYRrmOn57YJTZYrwSgbeTqAt/KOE+gL9LawiLJ0IdSC2RQnO3yu/aOEThHxpdLIKiVJoiEQXYVnq2UpnO79GNtplNnUe1hETQ/JT0o5X1bbENyInUsFjPuitAfChXofkAysIhDOHAdifc0Y+pxOHbQLkL65ZOsEDXWSlwMcduMNdQm4LVx26GLIV6yVsaDN+hGta2CxUuSvEIMM6T5xhaPfJ4K57LVw9MbOjRXpmFQz3QgEr8ZZdUxgE+Kj6CtmsjvzXtCQ3Bv/SccTLJSR/LQ8XRdIcPoOlDDy5jSQDF/8lxkgV1V7M3+SI1iWESPT8My5C+RH32F2MNZzthYq5hIFUB3wsM/AaQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:59:31 CEST 2008',
+ updateDate: 'Fri Oct 17 16:59:31 CEST 2008',
+ accessDate: 'Fri Oct 17 16:59:31 CEST 2008'
+ },
+ '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac': {
+ header: '####',
+ data: 'RgIWPbNN3sPkIPBE6lfvf9/EoDFLemTZe0Qh/1wZLrKxLRNzFpUk9+NmeGUp5f1hM3XjXw4cXRvP6GrWq69mz9zGja+1TA6RoW3dFMpSQkbONcrSD1mIjxV2zIvzA/Pangz0ZixbEeHCfwXLvgnevbTXXFjkti3kLHQlk2pJpM3zMl+rMJtcsefszuJ/0tE/bO7sBcFqcYgKAht2OyDQORBAGiW1kI9USKM5OOfJJIZDQ0gDhRgl2U92l3kIOO8hdnj32oRedwfKFmdSRkuMY7ykU0bMuVEVkLi/FWmhHxi66C2ovAztVtMd1IiyoNcHc4UH942GC4pT1A8YQpIHxBAJbrQVhpl9LfFkmJ7xUc6Xs5j0Nv8+z2JGCnJI/D4nDJqYW+iCYtRWu6vUmbg0vGfaYWQFGRZRk8zWfHzHXBvHU8p0QsIjYgCLKiUaU2SRRD2P7JCjeTUrm3I1OI593iPsEH9J2PHCM9OMQ8/Fsdgd7lWgH6P9jLdGUwtb1hGaq8mg3JGrHFXcrVkUEBfeR7xljeSHD7j4YahYrua9EeR8nvq6CNaOr406AWyHse9SXhaOxt8qXRLoELpyQPsaLgafUpsdLjJqHz7J76Rp77NSOtXGplKjAtU1xj+d/agaAKYCjvUJC8/APJI2890Pn7VSXr/TPc5biPEIopyVYEHFqaT4e5nZW1Ku1HXC9gwUwUI9rITG4GzIH1WMEm7oFLNUaSMrdK/UTdTJZ66ENE3B9v9cTUpR0NTkbI+iGKDnc8GHPRlr2ZJwN4KFTxi+o/kkEOBjvRHR55nRh2+dke75LS/fzHQZw5wlyqBv5ZeUZfRA7QHfkj9acR0fJSqqNX25AUzZQnRL3oVpOxFWCMU7QVf5VpnRm9OIOd/5F5EoY7Be4doM/UV9U40F3E6XPZQ8S0GKQzrDjc7jKyGPLNPLUWTmGB39mTNDHZQHh5Xv5Q==',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 08:58:49 CET 2008',
+ updateDate: 'Mon Oct 27 08:58:49 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:39 CET 2009'
+ },
+ 'b57a2d2ffafa8029123362071c09709bb9192f06a17140440f0e41d22143148f': {
+ header: '####',
+ data: 'PQ53T2Vo2D8PoLI1qNX//jLaVZFTDTYk6geT9+4RoThTxvlJ+beDPnQzgYhd9iASaF9GQEEL8JxsBnNpEPa6JPOY4ndFLmDLyFDKXMprxq1UIbzFV6kFoYAk3uCCCa3UCDzdr1KXB2CiiF9HrilaA+xkm8krAvH8I5kZD+j23gByz5cAFvXg7A77KEURpjujURL65DW5M+ceIjo6OXaPW9VO03xhqGt/M47ayObpoEGJZn+X9C8s0SE5wOXHbn38YZlRI480OMvtDAxbEYUeQKMmzu6lO4Nw5hhOUjoPSLr/i3tmDx3nPcDwnSafx6jyA4y31eW6yazqTEOP5I5ArC5mUrF7mAAiFvbHIsMoF8PLj6MONlRIOZgbf9HzCpFdt8xBrX/TXp3LaSAj2XTWgSTFI2cgmU3qqPyibvIfUsB5cVHQCXi692JpC+B85axJ0FLyMl5w3vq0txlPkf6q+dadPYDaLHGZEmDjkWScA1GM5xPJHWFwqGE7ejgXKG0sMYsMKWYk+F2LEUmMHtEvSlpgJBntvcQ1ZjYQxeu4hg5txu1ykkif6fXgkXF6wn6qu+5caeJeNhWtAB4q7WVD47111woYMdkmX7AnDTXSAQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:57:17 CEST 2008',
+ updateDate: 'Fri Oct 17 16:57:17 CEST 2008',
+ accessDate: 'Fri Oct 17 16:57:17 CEST 2008'
+ },
+ 'b713e0a1e2664ac7bfa7ba887329ea023204d10298973e322983b82b222debf6': {
+ header: '####',
+ data: 'H3gIieYrH7Oy8LEWCZpl9vGp9qYdHNCoBNGijYqlcfXt+1JYvPj1abPp12xLNrDUHfaOZklU2Ip4tOf0CDNhgAan7LYyPqFoy9ss2f9/5RLcbjwiIwSduySIL322HTAwqlzlBt/qaJdHHPUrczmu0fb7fT+0dO4gCL/e/IjcHLefUUgNPAbpHG0Nv0+4lNwKZkIQM3tLRtfJyFBIgWKcMcP1XMic33kr24rwybR8Pb0CHZrOOvvUiGqyoED3ZTZf1twUDVNXO7MWCAC5dBc6/Mk/vSmbbGhppXAH02N0g8G5qzZfp3UVikls55VNhRYLHByVsgpkbIrKXyZnBPTwzm7qefpYAXDOgO+164L66/Art2FYGqZQRZLuh5r8oF38',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:58:00 CEST 2008',
+ updateDate: 'Fri Oct 17 16:58:00 CEST 2008',
+ accessDate: 'Fri Oct 17 16:58:00 CEST 2008'
+ },
+ 'c4cea1cd88a86b05f48a99896a37967c3456228283a0406331ca9f67c6f29f97': {
+ header: '####',
+ data: '1znWPwc9JwCe7iOFiUd2iGm4xJd+824B4VRqEtzCQkW46tg25RWfo7XagvK46USB7t6pC8WMLU0M/EC47KucsfpWUqHGbseoXT/8g8E8GoLnIsk9qFyJG7LGd1sUvqBgszLZwjWWG3t9zifmpW5nY9GialBYNmeSLS3bg5xDH+eCEilUUfDe7zGuVSuu/XkHacv/DYUst97e+6u44F7H8Kv8dTywJZpqbmveNPeWfCej2aBXdVV616J5lIRaj2uIYuQYG7blYJh9KZ7yLStdPndl6h65hIJpfWo0PM8nLJuo0lWNHz7misrutnmxJEjkwVIZ5YAmqp1Zz3VC8zw4IxkXrC/sPmp4PaNXgKz9ZJRaY2KV69WmHf7BUQ3QneGngbT0tN526SS5qDFwTGiuIlnYGWvTB2jVrbns68n/d8Fps8sSWfJBvvXJUEkaZB+1WqNilOPGXvyJ5k2O/iucFbRlxwlEHDny+AgsbtXZdp8cHQ4C/O4G0mnUMZuS38gn6e2kQ55mUhxKeORM+J6Rx1y4Iiu9KKNbxyS5eBpAlFB4xS/o35CS4g309vyOEhi37F24bpp4pM0xEPG4mcc/IyChHzaHUGEp1IX1ZO/r3ut9RIN2QWrGLUlZV/9rFKpLLAy6BkY/g8VYNrV8PztOL3rqy/qwqNZouONwPw8w8SA=',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:01:59 CEST 2008',
+ updateDate: 'Fri Oct 17 17:01:59 CEST 2008',
+ accessDate: 'Mon Oct 27 08:57:58 CET 2008'
+ }
+ }
+ },
+ '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:53:11 CET 2007',
+ updateDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:25 CET 2009',
+ currentVersion: '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854',
+ versions: {
+ '106a1116d22c2395906a346da4d830c7afbd2da9a46210d0b7a11de238016783': {
+ header: '####',
+ data: 'jgDUvByveAFnchBQKhiHGYDNDtj/7Aja2RePMer0FCOkkEu5GRAiLkxA3/DD3eiU+g+mCxnjnOaEIYL1O5o0+JP08XapsblZHTRKfveeFfs6sWwuqEHGYULBaXx4XSfK2B12HgpBwa5aD49489AkuyXi7t/aAXcKKJcLB1sC61DI3NsmajUaXHBi31Sp7nKAUpMuiWyguW0JVfH6KUPqyldVDBTBqHAis37c1qoR6aFHFfGgAfb35+syfmPRgemujMRkj2XO6dbt9zAYlHVSYFp9393rwPZoyBfXMMdDtSTmq7H9qbmx31GecHZlFN3NymtPPDYUbQ9mpPVRbxE9NjtiPrI5eGFvb++OdOx75PKjYjCAPWWFZ+4aryNn+h+yqab7pAuoG03ACVVrAFIOn09g1ssol/vqvalulEf3hAIviedyiNAC9D0UDHtzUwyIiELvR9qouXLZ',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:13:41 CEST 2007',
+ updateDate: 'Tue Apr 17 19:13:41 CEST 2007',
+ accessDate: 'Tue Apr 17 19:13:41 CEST 2007'
+ },
+ '111a8a4b6b912b808a93cf5e8785ca223112628d05f0bfc5dfe1eb40cb72ed8a': {
+ header: '####',
+ data: 't524etHmXljCnLC+IM+WPD8Q5VE7wDsSHVNZzFU4hQzk119t/N/vhtfHYz5HgNstU5T8c7h7RHKvFk5f+4ZwgNgDqSH7H2PrH+7/bV8+uuqbe+/3GYOvELjTF7v3xMyYs1B7ruHpT+291HVNZqxajqCl/+9nbG0e5feqNsTXWUTdLzF0szJuCTNr2I+fhxAO0LRVaf8h+MBPYyuBDnfFDuKm899IsgF9YoYRvjaYO69DkElvf4VP2jrXIJsRnGIUfUaIS/wQ54+X4JBZM/9M09MVOw1SVe+cwG+P3xyPUkqnSb77ECo86C0MktzeYFmPnPv2SM2KFA6slctXsyudoaNlReh1k+6no5J5BjaawTfqYjYrAtWSPsuhxYVsZym/X2CVbkz4rMSn+J5Uio9N5uZ6AqgCKdhAJlwzVb3fIIJwvFpVpy/0LMskb7aG2i4eAxwzx1H6rD3Y',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:53:11 CET 2007',
+ updateDate: 'Wed Mar 14 14:53:11 CET 2007',
+ accessDate: 'Wed Mar 14 15:24:35 CET 2007'
+ },
+ '144d6eff3eb5f1cb70c8906741d88018cdeeae3a618ac4066598ad6b04242364': {
+ header: '####',
+ data: 'NPgSZF0eSOzy0/Ns+15Nz4bjSwh4o7fWYgKgwXLRFrF8y3EdbiOH7AiEmmPrCpT1raeYLWCcDIrRTz+/9uvIrz6kK6BjU2emr8YdyLai+PTCRY0SafWS3QiYixX6DJiKIt0SC2F6dfmSHwNsbfTHilFhVXn6wXTJpWvC+sRzw+h42cYpQp0BoLSuFV7vPz/+wtuQdl28BiBgLzGsrtPud0tPcfldGox6Ia/1SrOPcqUr0tnFlNQiUvPU7N0JZgRNyr1PfpAEhmYRI7aEJidsZ36vGQpE0ZQMmQE/9tLS/InALRZT1YXfMsytf0o3y4QlgJrvRgBL7fGiQOZJpU7igLk15xAwU+OLIaYIbr2xlKDJvndHOcrFoYKry9/A/aZSnEYv79wsaf64bBgIVD2WJGLuSFFmzlFnbg/O4kGTin3A8XBpvFA9V6iCMvnEMkrqxD3Qgf7WhxFE1A==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:33:00 CET 2007',
+ updateDate: 'Wed Mar 14 15:33:00 CET 2007',
+ accessDate: 'Tue Apr 17 19:12:56 CEST 2007'
+ },
+ '1f1bdb7a21440ac20c6d913d676aa30dc360252d27059e77df51a1be36b2e263': {
+ header: '####',
+ data: 'TaOHH6IoHPKLLoyLyvsBszgsPPcDs6CiLVXzXuXjFSTrhPxzUw9suSsisgDRRs0ncjZ6BCyqoCxMnw6QVvGN4viUwYVR8AWdCg0NMQZ+LkNfq/2WN0M3KyASI8sIdMCwTb57NzOn9soB1HmmmETZfjr7HpY2cc+lS5/4f5rxI8XTEK60lLed+aEuJamAjeZUdgIyu30mMKKjxPfY3Y9iWMwn1OD0zF0mAW+hyEoMhhK7EYlWKCy+4qN0QM+yNFXQyERb04o2n4XrM+qr9df1GtbQMH8igK5VzXIrKjdHjKoLo9G7D7mfx6mRLsmoAJuE0R8gyzotgdBpOgWasHJ82iWEa1dLRKBHJ1d0Lnumv22tvYfasx2DIR5Tmx3kIQ3hFieLSXq48cYMiaZH/IbLiapIOlMgtWDow8JuySBLei/8FAV8jCxSc1Ui/SjbuK/kCvywaSOhDVIxGw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:26:35 CET 2007',
+ updateDate: 'Wed Mar 14 15:26:35 CET 2007',
+ accessDate: 'Wed Mar 14 15:26:35 CET 2007'
+ },
+ '70720f026f37b571e9765d27c51d3d60c7be0293c3266f1f987c8de9c6b5c416': {
+ header: '####',
+ data: 'NYaYljcgfzrlN1DVgrbyj4AeVhXGjXPho3IQwEKD3ZOx/yEZxldCNSyFsrk7PoRB8Q1T/6VV4CGa4HLRSB7QVCrtVqWyu4KbbmFoX8NIQ0H3xv+TSo3S/b3dldUeyW32ScaGbspaf8nFf0CffsgpGusd+kHdiE3gSLJvH9y5j47KgpyyX4TteVzqgez4dcXIs5tdzJq2eUlknwU4651QeKIuRSmRaDRhhOP4yRgUo/qXMlTJFmHviCh+IumvBdmDoPe3Vc1vZ1r8PxpDJLvDoB8GTDE42NhqHfVrew9ym1xlTD9wswwIEikfOyTq3JM857qPOHRqSqthEvr4WHbm1VW5PReIyse0lugGyOzqtCnADp9NvNI440VjaTd4NBQqF7XrRm56+1u1uTdfYGFV5BRiH1KmrM1sxXQ6PlOF9Lou45ALo20xxvJOLKG0RKLMr8gmVT2bNtOSJw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:30:09 CET 2007',
+ updateDate: 'Wed Mar 14 15:30:09 CET 2007',
+ accessDate: 'Wed Mar 14 15:30:09 CET 2007'
+ },
+ '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854': {
+ header: '####',
+ data: 'xI3WXddQLFtLVzxJaZWQaw8wAgSuXLjLnyoNXnFuLecTH0BzU36PatglVh2HK3LM8aDLzzbHILdlLNnJ9CY+YnhmGh8hswF9oKTgq0Wsesgdc20QhSMNFFjmMljY1LSXmcAYK04Q5mIzi6Pe/04DRdj+e4zbe5QI4vEBhp/ohEpxZnNqc4BoX6J0eVf6LA1pwrKWvxzMxorWsJrrr+mn3svdlF437n+MMr89k5sQJogufes2GZ9tTvVZ4247ITxXqxgAhwXtbuIs/A5UqqnNdsxlHfpLKG5KjxB6F0h7TtFA3gkZCve5UmAibBnoBCFaIVWQyVq+VO9iqDm3DeXsK2pepvgIvpSID8Poy+uwN7T95mivAsHG5p7MtgN9KwQzNW3Iu+BfO9FlPBMngSk8L29So2CIXe6lEsXSGEi5Yrgyo6hZi6IkGCXwIQ7TCEMnlQEGyKnnAVik',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ updateDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:25 CET 2009'
+ },
+ '9588b523f39cdfc14efa1e15ea7716c2d8eac45d8efd7bfeb19d716f9df72d66': {
+ header: '####',
+ data: 'q6DKkxhgDFs1XkqOYf6dvojPF+yhJbniTLFpSOS+I1sum3EZIJfYxJXyi2Jx3KOVNBMILw1+vrSLe/fh5SSWj8ZBoeppkPPLjyRNdiUyd4IfcRM5OSv2YcTxCubKCH2kIMFAzY/29A6ZGPG+AN8/kxkEHc1fxKaNcj2Cs8qejNR8yK1iKT1Ut9VfEee+Eqy2Ohgdq8wL/xAD5mUzdqHeQl8BY16pXGIYncLxMzR+EJ8E5jJTuGv3O41UbO31lvBSfCt2pfz2MrtsuqNoI8LBHJkcR6t17Bj+rHZUniHlyxSW/1rQJ1NnwpPgUJ1fhfQJZM8Faoif+0bvWFY4xWs/tCCD7oEvf0xM0I3FfcJLbYX8M+wyO08t9BmGdEjnr3VUcuS9qKaJRpdpMP7aQf+vJvioeQDXdOJ6Ceo3BDFc6JdNta1Qc+agGzN2KPbIPrLDL+08hWl61yu3GQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:27:35 CET 2007',
+ updateDate: 'Wed Mar 14 15:27:35 CET 2007',
+ accessDate: 'Wed Mar 14 15:27:35 CET 2007'
+ },
+ 'e5b71df0d4d79a195c7ec3288dd7738069837a7c4da3bccc1ebc05d8e4f19d79': {
+ header: '####',
+ data: '1NvK9Y5r0Q880BfB1W5IqdOR77mmqQU0d1GL1XUeQT75R2EgYE9rK1X1jLygCXboPhxzegEe7TDhUsn5XcHN0LkXcLYz8gD/7+He2HiTFxoHd2oQbI3ceBxDJ7+5kWA6Aiqy42QSCuA+TWIQcDVthSyFU7nNdqNxeBYeXiI4jgwcH3xvm0+pBf1OYLtywjUK1JwntP6o68b1LMQJFinDG+sqRcm25ggaZyxDtoLh1IBdSpmXk0papRnyyTGNgsws78dLxnH0Iqxb7FhqYfgLDIvN3i7+IALI0lF0EuTS0hSPlr/1fTz1/6bVt++wI9GpUsrdafUJJMPerXoCK+gAP8EMneLq4f5487HIkwWh1qON6Hvpg+tB95NOSJpqE72VpVxN4+wTQWyDMhfjqXBuQ1wKvTsD/mUsdinU0Wb/YT/zIWBNZPdqur0rjOC+mrOtSdlYSCH89Jj2',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:15:09 CEST 2007',
+ updateDate: 'Tue Apr 17 19:15:09 CEST 2007',
+ accessDate: 'Tue Apr 17 19:17:01 CEST 2007'
+ }
+ }
+ },
+ '36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113': {
+ data: '6fhueIibbxKRA7Mtb9TPcWiUKajnikM3D7PbOROBkE39Vw9E/nG8KrtJlwwPQeOGCFhssO/KX3ymYehCR8rfaEL1f9pfdh5x69mSxKRlOmtEknWqUgPzcb1yPenRbQagERadh0LF4zu91M4WjXK9qynEHoxI/pBhwQb1IsnhwtXl4ELtajudv+2Hv3p75v4XOXFsGQMsHPY+Zw7dkFFA8EXhvuxjiGvnxCUkFwNICFRdHTEovkW3VSerLdrYo5lDgjY6ebr/g7wDGuu4RLfUK4+HpzFwZ0+aOrjpFq2ePg2xObvkkMNNjZ2PcR6Cue0sf+aNqzIHIlFPpY2Hmrob8+bwxocKA6aagBu7z5GiUmZNXGE/Vtr/WWBV2+xIJyzXZPet0MLmSnGiALjPJveeKnnFdDtA929ydcAb8efc0/snfU/uDoXDiO5SWEQ8DDNjj1bSo7VPTtvZyFormE1KjqimqSwaUJzbIS4CxPnoDezaBtQmlG4z8mc8jXq1HfPu7s9PUzcbG30gbF0ch2pDj4h47AhE0ZoeiV+VYZTaYateSifQXKBQKjPcuh9PQyDI0HVua3itbbwxXpRubEM4fbvlcd+7gu+Zq03slYICD07fP0I6XGrRHVTfYpDbEb4GJBvRIeZLwRTQzOeFbPLpBU9Lv3zXxfHfcHy9oK+giIxefPdY1ZR2ZFPKOO0xYJsTr0vmTuXeXzy56bKl+yP2lFst5l9QG8j2JcQEotDV1KQS6mbcLjfIpEnltu5fc2t10Q25Noh+F3kF+LcMIYsDjwanojYlOC93mZl01hmSJdimRTk9otjlRTyC7NWwiyy7fe5IyVi7ACNPZyeUYJUPtKWcPbT73Vtf8W3/+HdhmyYNyMQ9PDCBb9WKMon+qW2+ZVH5yv/KqMHRY1fflAfxpHNhrCkwqcAAGw+G/cetbvQjpkfVT2/u/uLupMsITN2Tgvr/8D2IMm3cyDBUCshrp0AfzARRygHFK4x/0uLfCtQSNjw6zMK8mn80R5aS5bZi5gRS8JBMZ4Q0iG4kBlLpIYtsXSBwl8faljjdl/4XvNNWWrdGJn2k0eM4cESlOFFk4s3Yu0Zspo17nKAHINjHAiP3VlhuKSnk5C9hMU5i3vZO8anQmx9UEwUgQVm22azCjyNtUl6jVPYSNsal7A==',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 18:39:35 CET 2007',
+ updateDate: 'Mon Oct 27 09:16:14 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:35 CET 2009',
+ currentVersion: 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463',
+ versions: {
+ '381201fd3b67549bd6630841e8902be1499f3ff0c3514dd464ad9679f22f3561': {
+ header: '####',
+ data: 'DgjIW4YcJAYnckuEUzBFkfEC841LuanGopPgp+YkyMn3xuzdpGq/ObLFMVQaeAuyErh1B0REHPbq0E/SRUZbeXLXWN720GU4GXvY5bnen2h7pHvl/H4yz+kvyKh3EHJmmBjuz8s0kclFJQB48lter+G93TEmUaFke9c9m0IkKlgzwZ/PQKZyIyfZA09KFaozdSxdFRbswZj2Vq8Df2PQsKLapZWX1wYQ3lXOcyvNdTULy9MCXwPwX6te6hTLWxQOiSPsvB8LItlhQUsSbrJcJEvWPlBupPu5SeI25zDnqKDETPep63Ks2GWf45nXZzYYmQMzL0l2cenYFxlE18TcOd1Ms24TQ/iDKMhi60zZoo13qjVT5AKZ80KNu46t08qbACxjv/LeK2aM5TNycTFixGskPywpnb6MCo8ibRe5rs1WcTJRMD04sNoiuriivO2fiyo4rxjfdyfueMlOz+Zeztk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:39:55 CET 2007',
+ updateDate: 'Wed Mar 14 18:39:55 CET 2007',
+ accessDate: 'Mon Oct 27 09:07:56 CET 2008'
+ },
+ '99dc86ebeb20a3db0c5393d6d94bc1150187b04316a876970dbbcf517b55d6f2': {
+ header: '####',
+ data: 'AJwqCWNKC9z8DC4TUI0hWnqHvQ40Y/x+jXylnVAkyO2QYQcqg51odLFSfgP0GiGEGPYwDc+kUxRrfO+ITgTNm+hHi2iIWkP/ljAC+AQ56MAEKsU/USTbvl6ShZ0XTAdRpwI/oqqOhYThVs6jTm/J8+lx4tWoMtNj835py88c/9eW26pLQubr7VysLSWuIMi+iDp7zXZZz/0gxGKDe5xNq4MGIYw8/OK1iJCOsjBdrRygLlS/Mz9sRlKkwdrDsohtRG0F/NdsIoaU4FttGs/rY91SCedvHy6ovh0zXhxOO44O6MiMbP085D1jCjWJn9S1RBxjxc368MGfMJeZja87nuvgSnLS2tGDL6zFtVJMNcH/7GqQPXZv/sNEykDNWpypchCnwYUJxvBVb45FcUzagPm+SSiekWK1hrEntZkZuEhQZp7Ud9RcENpa5h7wXUJSV1vPl8xBylx9HWmxez7D9OYRqbOlCRAEDqup4ahNhYB9',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 09:09:11 CET 2008',
+ updateDate: 'Mon Oct 27 09:09:11 CET 2008',
+ accessDate: 'Mon Oct 27 09:15:58 CET 2008'
+ },
+ '9fbfcd3e7fe30d549a813f0e6c1be58ed45c3ae7305d7367bffefa097b424ee6': {
+ header: '####',
+ data: 'nZ+Lc5LWWLxnPvUrRrHhxG35PHq7GMbVENHfV1oS0Qw7/63NecssNoEbiOwFVMjAshvfUK7IjnzyvfQhNtFRbj2yzHOTWCd0eJ0O0MmvGzjpUntSDu9/G8RFeEu9jDKugwi/NhOa5legjT9pcsEAqR4s4NN/Ac6juQb6D/Z6Wd6wO0JQhT5/QPk1KllDpDeo2i/GPUKvEi/dXpik0KQcVLVylU82rf6hwEgvRQi+j0O5hnFW1E4ttxClrnPBEBv60jkNwcIpD0r+rvomDe8+398xUuB4DVDJoM+WUYfu6Sm3qI0yBfET+tJvjn8WsHhKTgZpOc2BXC7EdF99nNEg6kV5pSxV6AUA1XUz5kW+YfcSzAXzUH74OqroC0SucHe4+BtRKnbJy4h5vRfjTD+FJaj1Va02cxSR55tQhxm/k67z0QeyB98dnU1l/pPHwBlIWa1eR74gswNSeQ2jrzu5JeQ=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:39:35 CET 2007',
+ updateDate: 'Wed Mar 14 18:39:35 CET 2007',
+ accessDate: 'Wed Mar 14 18:39:35 CET 2007'
+ },
+ 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463': {
+ header: '####',
+ data: 'm3yhZu81UAjCY6U2Knrgg8mK+LX35Y/iZgIEm8MuRDAlg6UUz9Z1Anu63COFV08YyYQRuBzTgR9YQ8wrUD1S9FG2ZmtCDemqvd+5OUMgdn4sK7G3CuzAc5osOa5neU2m4y19WuobkGnhO78ko7pVVjO42q0DeMT92uFL6KE/2UCkWlq5SdFyS5qXEJEWs2IO5C8nVpdlO/eZ36Pl2+v+afl3QQMTthCVIUR4/zVP2ajbO48yjDXhYxzskFjtXMYLApEn0wO0dcifcsYhPkozz6Locrt/R6IZXnfZfuW5XXHbqhutoJFPK6L6t0Ib3B2r1TNkPaMsVs2g5V1g3ENRd0IlbG/uBk2o5tgeu6gOYlA1scEiL+/ad9ZxiqYB2ENCGZ8DXA4VNMnzxVPbO96OIUCb9suV0fldGOg=',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 09:16:14 CET 2008',
+ updateDate: 'Mon Oct 27 09:16:14 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:35 CET 2009'
+ }
+ }
+ },
+ '507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a': {
+ data: 'ncSFmp/+n1pYUKi2fwhMCevSwFYO5irdcpOlSxC6YPOKYavK4iUbtBsilYWd0hpvUHW2ItaDwiyNFxs2Lwegex6dawKrpMYkPBcaZQDa746yACGgCkhz4MAGnUn5HCmz6xhpCVXMMKe3w2nEOjRB+pOMOeJt2n7aw0hCJ9tQ9JTFNrZOxeXrqoexrd210Rmr9FnKhLIvhNTN1/vXRqP0ys10omJ2mowzF4KoEVmz3ET6pS2d7tGjt9M/OYsH/ETWWc92doF5PO84g5/3HePaCo8NCqq4ul7AWJEbdnkxxmd7urJzIscPQPcoLxL7GfG5LhHTFyHlfFz9dNlccfA+OPftjyfjXTjLYZzbxxbi/nAB9Esqj5AoHfqaJM1ZOrZ+qAvm8Am3+HAXrqtiybDITrCLmGH9ukWDsx7R3lYTlvjArwORBUH+4w4/uYGscVm9kOYj/Rmz/ZMH9JibYFcPcOnr3rWXPFUL/XsXTrm9lzOvPyEYJmkENzd54AHC4Lr5vHpeuipWFLiJOrtn2WcgDG/DdLaYGKsmISXj74XDtP6Ee5lKOtbwwcmVNrl11UCQBEFHNybhXvpil5laKddOauLJDKtaDL/mKYPbr5YSk7HPCzRyE7HM2dC1MpBHuJ8g+hDkgU3wQcxYduKLRpuC0uOqrODigGWhVrdiKdZanlWUq9EkE3eH+E2A/CA8mHl7UNaH89XSvgV7uZyOmK7iZ+1kd9OzhBLQdJnK9qqP467Y14KsTt1E1+tqlqVAuK79QMnllaR0e3ztBRAQsyf5SD0KuSGXWz+z9/RjbhamW1s0UFRGh3voQMypU5RcYfYUA5KVg0BiVKFaiZBZKLo213hKbrgE2KoqVDEmIBFmwsu/S3EDzUY22tTB+o8ZKQiYesAUafGtnvsOLa+h6weF1ZvQVBerbD3fhb2o+d4ZyPkoRAsop+5it0QxsWuZL+J2oWybaikxIP/1ZM2ow4QZLaAVqihyHxqhF5UxZ9zrWxfp34BIPzzU9esSifrD0gXZ3mwutaCukZoijnGODJZtFOy9Rl1gyS1IbpyRbwz5O/YRl4BsD2aOk4InajT13Sa1BLPblQcrau13aeg/IzQhcUJ6n7enkrqiJFTP8N1aFAuYv8ilu0V2ymIuCLUtc4cbo7KyA+gnHhZA+DjjrhG/izOyWtQY/WtDsqvo/6ILwFk37JDjHfkchPEVcdl9qT7goG/4zTGX+lx8UTKKZJjJhLjA',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:01:24 CET 2007',
+ updateDate: 'Wed Mar 14 16:01:24 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:11 CET 2009',
+ currentVersion: '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b',
+ versions: {
+ '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b': {
+ header: '####',
+ data: 'sgq3FGcsnlbhTLetMa3TQQE6uFZv/JL6Awha1066IimKoAtQGbAr6E1+mxRmvJle91sL7oRfi6suvDanYHfAI+rrG6qCOtESn70ssS+aGFyO3XwFgypzG/Qa34bjxJ16Aqd93H8IdhzdtOxs2Qmou3CjyxbT7Cq+YW/fAo1WfctL4yE4GBNPWC5lfebxSmINlBY+zTjhv9Pf2aK6vL4p3obHl+zhz0YdKAMBwbDyCLa9tYvhGBnq/W6lFUsyZCPVJJP3bQCQww0TNCcLJLm+SYVSiC0NwCQJq+yNqDkWTvv41p5EDB06eOQ2VqC7l4i/JLE/ql9h9Z++gck74/Qs3ppdVdG7sTzWyPya4v3RW2OTc1awFRZipAX5Zd7I97dyw6Yym4y+/9UT8z8iMDYykQ4+QnOhksDIE9a8q6agDF/rbZ/BCRcMWbFylGTdudk26mu0GdPiuLDu',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:01:24 CET 2007',
+ updateDate: 'Wed Mar 14 16:01:24 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:11 CET 2009'
+ }
+ }
+ },
+ '5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4': {
+ data: 'Xs+z3VzIqsWa7dGBqepwq75lTsx3yemNhTdRYYDDc3Kzpycyp961SgnKXHjE51266mfmj85ASFi/FKCOwk17lbD5UT3iawtc3TdgrQ18vBhBsmOA2F4JAa4yC58bTaXbyld3c4izDp7i9+iyRaFN52NWJznN82SXuRtPdWRtAxXB1V5Tyg==',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:45:25 CET 2009',
+ updateDate: 'Mon Jan 05 17:45:25 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:21 CET 2009',
+ currentVersion: '00b3a4cd7400cfc1e7f7b369bdc3dcdaa50d6020233e131b30d755c89249ea9d',
+ versions: {
+ '00b3a4cd7400cfc1e7f7b369bdc3dcdaa50d6020233e131b30d755c89249ea9d': {
+ header: '####',
+ data: 'uGAV9pZTjrTwBy24TX/OUQwGmgzTnXv1JBIxdGkeoLCUhP9tAjbpUVylrUI5+VRrFYkXYyZ0o2HEgKrun2f3PODTxlmAbfkUldOV5tyV/EUxN0vYSBtgsMpqQm3bOKRIAo/uzrhSE3iwMjvKOTH2jUrkmX6hmqhXWZfa4X231GovrnOjek8c7t+LUBmmIjXEr2GSc/UbBoFnni+Q7ZArwtU68xoeCjLame1e8Y9wvCO8gIfAzXQAHsDgzn1MVeiWIqiCBTs8YKCO1yaxZpkzXV0yWzX+bHyXlKWwAk7Fu9w0CuaRULZmRCQhv+MMDw8DEXciTm0R5dRiVmSCFBy8cL9qlSeSX0GlnKl8E4/TSqvhMJblwJJsgmGSZ9cEt2u0E08tHxKuoeaaT1rpAOoiqx+z7BdhqjWOQZOGM4gR3EwqvOQoNYFUaXjAdmiUzW+e+TgE1IBQ8udRFl/D2zCcqFO90Hgc7hHsTDI3aGYvi6bHADu8hFpmZtJAjOMv1JgCX4Hm4n+SsbHd0DIfkEUMeGlVO47lcGWBZNRRm7xl8luZ4sZn',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:45:25 CET 2009',
+ updateDate: 'Mon Jan 05 17:45:25 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:21 CET 2009'
+ }
+ }
+ },
+ '6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728': {
+ data: '3oUg1TD+Lu4ou06j/MddOTXDqRM+qSKD+6Iuzia1Hop1w7v/BXidqeoKJZQI2VY9oO9B70Nr3B3wDROF+ycy6Rq+FM/xqUGHKXn1lAaSc6Wgj6TLQ6eRF6YZKSPqTj7TDWyw/2pEWk4HjcT8drTrCaC02tzAXMhYWlYPQPW4fUdq4hawoHIdopUN3vafQuFjY47OhqXKav3bNao=',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ updateDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:33 CET 2009',
+ currentVersion: 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc',
+ versions: {
+ 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc': {
+ header: '####',
+ data: 'fehYRMkg/wFj2t/aWu7szbXwrCyCDpjQN4UNck4/OiDlth70a2ve6ow5lAi2jgdlV9WiFrPejfa8dD0Z1g19jx+BBsuUYnBEKD0K+NapdJBBeI0We2nj9nYIij2dfZVx7cuvhy8sN6+DdylUQLsFHbga+Gi5hWcMuULT4GOAIy2WanSQL1RSR4ruA6zm/t+VVboEkkm7PPT+w3LuRl3wRaD4a8ZwYiSV/SzgWooFrh2S3YOUeshdaGCiYpTbXscsOxsCxc11i6wQGBqYSjksmtZDvEegdQdzCmxvq4jaVWJElYYS3av612nD5K/w7Zei6RccBiODBPATjrIczYg7HwmQxIM/6QI9/LQn0LP0yqRVUUtfzaODf0uWNpFzml9l/1lwXuBJyQFBp7H7Th46ekw9yEuPD00oZ+eXvKwbwfUU0JshT4hnEBtIjM8fH974PU0y95f0yLAJ1+M6DVXCxGsBix2aKJx9fuZP4KGpaXg6qCb/6327rph7MGomcrGPIiDjYwD/NTMdGluc55OZfGXtOZUaJCUM6nihqDwU7Ly1ZzYorgcvkX/t/0RNcOkFzGYNByp7mdcotyiHqCDKspqz9mEXAd7Noz3HO5GFpPqbRo7htDigGU1f7dvgbbfRoTz17Bt9Mw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ updateDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:33 CET 2009'
+ }
+ }
+ },
+ '6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a': {
+ data: 'b2mcYUi59l434kGl7ij6dBu3063UL1dToMIu3Zsa9RV9RzeLKnezJhLKunqoAm7KwiJeqDo/REexHI1cshGYtHasVXXuyJfMx1grH7yhoWnkSRF4Sax6w5E5wnGkEpGJHOxXJ9rOjWHZ7yqCUUCB/dqLw4FwPOtRb/ynkBEYztEJA6EKGJuz0vrrTOsT8HMXtj/w6MEZ7qI3fPs=',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ updateDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:08 CET 2009',
+ currentVersion: '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3',
+ versions: {
+ '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3': {
+ header: '####',
+ data: 'pZEWSdYIkrX8/r6OYmO0GEuKG9baUgn40Bmw7hXZBd/kfWuRjWsL4/pc5F5Ojrx+N0dxmQn5ZqKAzOOri29Rm4ruxnCbyK+oDsCDyMSnWy/VJcvystnDKzKmBRQVAOSEJtzEb3OtGzvqm0PQ1Dhx1YUAx7L6KlXysmG9h9+MjOcErRL9/1x1LZ33ytR+zK4LvTAb7gN5/9QgwysFyCkNP8bG4nyCzPMiUrBnP0odMTUvDkJDlY0Oia6VjGW6oNxnGIgA5fDraRrW4JH2oejQcrL7+X+jpCp05g==',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ updateDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:08 CET 2009'
+ }
+ }
+ },
+ '6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18': {
+ data: 'jzjPgxRHApIJA/6hiY4XCtb5+eKzHlOeoiGwfVDvip95zU7ThHbdmxOUomeyCOZ3S1SGPT4lHvqZgfVG5m5RvH3JaAIa8EY1ZElRohoX3rETVPJzI/Ov5Rp3lZjtWlu5meNrcJz811HBHrtBuJxAmSjYcY3CCal+oC2zcK2fLZR/iOQ+69ONVFhdV9KiOqzNf8IisIa1sIgFopqsdHXiZ9oLe0a7Y56q+OplyU3A+TmxKLI+Qq+WkjvdMzZDDqzYH47me5niugYPdkQwN6WQUE0sK9QPs0uU4TOwqCwN9nPH/DoQ6oXWAu2+R4iCyt6ZjLNkClbps4s8Cwz6wfFQ+4T8bcldjveJenmrYwiUzxSd/4xa34yFVXVw2OD0n8yZhtvNFvfoPy+X9z+Y4f5HlM0qzL9zYya4KwWjFQzhOxFjni9JyGM2PJ1BctB+q1J+CHuhlVjUF0Y5zIS3zFTET8jjDGBZDWB+Ao9E8fUD+0OJJUdKJ4kUfn4ZUZUG20eLBjmJqWBGYZX7UFaPv8ksahoK26Ol6FnBE4KpPStQeDgXZDzGsiLlEsxHJLUFkNtAUXozw38bWWQvi2VIFtkw/ZViPIenmSNT14kUVWdrlKQC8x0+wECeh5ffv0i8UUw3v8QC2ZE7GV0OMl4ySlRCuDCfZ53YFoB3HIR1hSZMhHlHJDPUz8JOuXdHcUQaJeNrfWoC2KkKb0ZecBj9iXooDh9yGi0g7TS7eyhlz1LHpzEWB0CPsZqhNGMxmfFWur7v2hrYzoHQOeB19ZSmWzfUwd4dRpqMp0x1lZaF97jr+yyYhnuQvuO6lru15Pg6FqjzhsNiLtaqtyoaMiHZ9veZs04qZZ9Fn3U7HeJzjZSAssdLnvopXi363cXm9JqoClyV2OemnVoRwOZN2gdSZxGeOefKR7U+lrBAbJwViMnmT0Nd7AC8C1k34iEt8HJmpztXeOgX5CQpwUPENMCUPsookFbIh7e4aByllEQy0gBbxUz8JMIWYyw98hdASnZ4s8bQfSmiMM8Iw3YxCexKB62LYYJn1UY51NSnwCtwRep+NhaKDk2d6SLh9owxnFbjhw22RriPd5f1InJycjtpvMzWLavl/hDsjjj1kWpnCUBTM46LbERmjz+s4x7fSf2FhhguBT36elz69ivXoiXI+7p0E8f8HsSwm8sgN/AA5m1svsXsdWeZFUiWtAwLg0tI8YNHlazbvFCXfIC6Uhq9eDv04iqdZ3rn2c1rwSx336A7ySTBFdxOCJ46F7ShIhNKm2N+5Qf0K5B2L882fbwqiLsa64+X9aKvufKTsd11vyf19Zivg/Ze0FWoGC8D63Nh91k6Hu32RT+uAtJIjQIZxu9yXJM9lMaRA8ieER+ghrLHaGQqF9J3WmueER3UzU1midvTynOV6g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:09:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:09:05 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:15 CET 2009',
+ currentVersion: 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5',
+ versions: {
+ 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5': {
+ header: '####',
+ data: 'BbXNAy0GcKKyDPiwhP1Jk9mIi3uXMHQdhuxpDvoR2C3YITOUBpurxGhhvmCg+a9pS+fKJdZPxL2mPbJj6GfWTEsm7K/ECEjrVkSTHi6PTUUgYVbCumq9EHjUspos+7VrifZry3c73+qAvIKamvUlNB86TchMpOXVJIyx8UgRX+bdhrxk9ZCEVOiLCG1zGPX8IzmcxPmBRZFlHYqE4ibhl/CLEzWXZBYCofTusClhOh7YM/jBgvDt64W7aIN2y2KiKwmFySkFZdnOvbAb34tXVimwqjqWPvPwd6MujQeX1bmaDD7Y0kXac8CJxqasIezLo2WqzLUbEXdIHGilkaPT2ZKpKhKkpHJHFrV2lVuQJVqwPUr0Gf9qMKgVnsyU8kUfq9ox+fhH70+v7BQSjT7bxxDLs0UesQeL7G4SqvNet5hPI4GQEpOY8p5MUFReIBTRm72NQEU=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:09:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:09:05 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:15 CET 2009'
+ }
+ }
+ },
+ '7bb69b6366a8012f181c01e368ba18d4f7a82bcabb4959189736ad124c4bbfbb': {
+ data: 'wYPZIt0UHiNVefNwtGc7z7Lu3YoQrXdfKmWqilZp8yeIrNfSLB9p60DLMrL3GDq/CsvDYkGAZgj1C/6NVnzVsXsJKq7NDZn1UPOGt+hCnw3lEVbD7zHkoMM4VgFDn1sZdjLe8wdpIFfdlQESTipT3GVXv3swG2qX2O2yuwtlopR8yZQTLg==',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:44:30 CET 2009',
+ updateDate: 'Mon Jan 05 17:44:30 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:18 CET 2009',
+ currentVersion: '23f5fb503e54c0cafe3d4944ddaf40bc74fab8b5d96e2bbddf693b1afb225e5b',
+ versions: {
+ '23f5fb503e54c0cafe3d4944ddaf40bc74fab8b5d96e2bbddf693b1afb225e5b': {
+ header: '####',
+ data: 'IpYj+7t3DhSVD8r9PkLbF5xpGrHhg8omY014P1vkT2KkGDEUj+ekQAbQ1g66Z7oNhRDpjS1/dcDjzH0IIQLjGuQ0oRfL0xZefVTx3N88ZLE39m3cJz10K2xyg3xp06jFBmdNJuCkgRhMzeUXeEJujw4lS2kv7cO04Uh2Maui6jDR7E498rgePY3L32vG1S66li/xU1vPjNn06aFTqSYxUL17/mlJNbgp3XWjGC+l0dXLLfXy1wOm+/I3zp2caTs+a2zDUZ15s+3XeaAWpBH7QCaQsvsQmoBqPbMvkjOQwW3taDvV7Hvkh+qTjCEcLjRFwhZkMNn3N2ewcLWQa2aVIjxt6Z0F4s/1URztWlKVzCfto8RmrLajYRn3ggG12kX2xDJFjNPNfs/7A3tMn+FqXQCCNG5GI06JZ32aQfpnjtmXScUuEs8UeFgsNeYclQhcm5R0sUwISK+D345B8859w+4+9OTY38NgYQQ9o/tmpCjWj1tLYLx/m/GcR2em7iyDpBdcnWUb+tK6Ah89qvXriHwPLSNzhOH2wxmi7nXTRQWMv7g2',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:44:30 CET 2009',
+ updateDate: 'Mon Jan 05 17:44:30 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:18 CET 2009'
+ }
+ }
+ },
+ '8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39': {
+ data: 'pOMTY3PnUAbwMLDEYNJCMzp4iIA42YWr6gqoomg+P40e7LFUtbt/RQRelQwNIztyUSVLl0rilkZZkBUVvxrtTqvibKITCjJQGQIzvcb+Yl4mNosl2Rpp0xxMU03f1+G7eGbuCc5hJXYVAglhEYplaAPzHbRWXMY8iZXZPBuLVf5PN+rdpgAfkGeZ7Uf9RsQ9p/EglrWXYnTwXi3saUfzIjfvSHm5C+dXTY3FHpIc1YkjFrdVgMkhYQGV60JtZcwFtCEL2NpVljAbRgHoIXTOkzUvep4vxrtfBBWWMuAWEI06432gtnH6IQbrR6jOpwuMt7k/09qy/fARPHs3r4qTJ9r2uqWHJ7tjJw+IChQPC+3l5HcPpFURiw8LGAN1NyY1hUrF6N84RSn7AKS0bLa5qN++5lcjjxn/k8+JqmeUqN1/SYIbGwNnJeZ0vA8yvOxnD20iVADX5kOVqJDwXRPLaF6Oz9KkbOrmANCh+PmGw1i6PduB+FgAU4HViYCw5IGOUZ30Pm1NJofqfbhXvgzn7ey2+kUIAwDyOUpJ9fW+9jW/JU4rcawmzwBYN2V8apOoyc3wQJICm2984wIfVBpygCOZM0QDyVgNo57qKtYH3yMDQSkKvpEUmuhklMYhcV+4X5ggdqx7lYXO9IMDnFf2ZDiZyieTlOlRv/nNVecUB177Xpnq2e+X/ik2rCQWVrIymiV6ltr1DEv0krXKfvXGG/FMZHUmo3m+B5bG4xVhmt0GnHseqvY2Vrl9NksLgq3hTDOGSGIy5Nv8kfrd8B4/6Tavh0SumiyXnrTXyYXzCK9E7IqO/0KAln63VkcHsbOtS8mj1drN0YQ2KKaeIW+Yr3Gm0pbcODsgA6aFfz1itZVeovBqUklhXS+/Es8J8xOSvvSyD/TmlFjuErHa+wwNQvftosfwk9ZTt0eIJS5aLHdU2QsCjdfSy0DEPkk2siGhBX5ZhRzqyIAyXApSmy+e7PIqn/dDR51+D1ZHwoTQyTrd+F08jBWZgU/OvS8MRxNZSxQwsi7bcWZG+w0utrIDB8eSOMVBXI5XBeJb4h5Bzut18C1shGHeGkSJp04=',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:10:17 CEST 2007',
+ updateDate: 'Tue May 01 01:13:27 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:02 CET 2009',
+ currentVersion: 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8',
+ versions: {
+ '8a032b53f7356e2d8b28665211abbe2cf1c79fd8eee4752e83cebdced1c19911': {
+ header: '####',
+ data: 'OXpNHHSkdsaD91hw2LER+9XKpf8+bh/O+OcLSgG/gAx228UpifOCD4HTAOs0C7IJ5zhAq1L9NjCGb1QWWTFErYEtDEBRBV4kogscP9HWPxYyZHxjwPI0wE7Ri2eD4Rma76Utb+xVnXWuT+vNb8eRUCK8Ur1rlhYafS0uzAYvVqHDNfZaICksxeVQojil/kSPZDMu8ASz5pMNFNCF4SlwDKPRrJJDbNZ62A3px59YJtsla91DGVyOLhb7VNRxEwnXyxENfP78yA6OjvQDc2KhKFUpHbZws54IolLK1I1mY/Z8BiDXPSnOa694Q1eZxy1Kx/jLINZUIPgGg1++YWITx213awOISdf7Oy0/dUpu10Vr1hgAqCVlDp0IuGK01CswRzEdLVpUk1DaGHuin1rryZx9vThUkEJgQQc3ivr8',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:10:17 CEST 2007',
+ updateDate: 'Tue May 01 01:10:17 CEST 2007',
+ accessDate: 'Tue May 01 01:10:17 CEST 2007'
+ },
+ 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8': {
+ header: '####',
+ data: 'tvSUu+NPKHkwt/ZLXdLGdDm4jSxTEtJfsecdpjJ9UGN3Y2EBCmijU5i7q+hMfNDqBJ4/m5Ayju4zYDAKGp2pt8l1TFoDurITdFcV12jL8j3dc4TTD//uC6OtowRN+altgC1Xc0LsSvEPabjAlwfVC5xqirfm5t2mVmnFZ/GALkGLGxRJRduylT6goPwfunkVGwUdqMa3md+9mwYn2gm7CyC0lpcKX8AZ3B4Oa656yRa9m3Wjgb007TtorLIpZO2MzVwxcHBqqy7YpN+zpmZz6Md9VK3L4F724tuXXWnDeVzGxBO7aZVr62hwPMXM6ibCjUScsaS4f0chivA/tBJoyx7OqKhBxREGeGjpHTeLxyHcekbwXhXyeqxBuwG93yGKutUhGLVYcXwe8/+xSeaBGj/j2RWutKbNKG2yQyNPGj2cxJWsR4YfOQJTSOSWT3K6Mmf+r6hLhIo=',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:13:27 CEST 2007',
+ updateDate: 'Tue May 01 01:13:27 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:02 CET 2009'
+ }
+ }
+ },
+ '9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291': {
+ data: 'xXZUJjgxn62OqnzAvScHJNo4WjYEFp1vQ4ueBe1sk8dH4pXZUKV6m9c1d2cLUgBj4rUNP5cC66GiFHV7G5BDZGLrfrxUlYU6BWvzAz4eG463pRDhHXQgPrhlIGDlK6ovaIsjwaifvHaEfLREoXvLFluqu406KG58guhtWdIFK0rLypyRo8uyltGbTz8wZdu8atY/JYQnb8NaAf4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 16:29:06 CET 2007',
+ updateDate: 'Wed Mar 21 16:29:06 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:01 CET 2009',
+ currentVersion: '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7',
+ versions: {
+ '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7': {
+ header: '####',
+ data: '7wg/yWfSasUjJKV/5ygFfteazVSdqEJ8xGAqtS7m/W2q3rOR+2fr99Il2TzxXCnOe5zV+iir2tOqPQt6BCGbVf0NVwZtvfO/lvfMc7DIwyWuhZ0sS44LBTD9VY9fruuIegktVHSNBoJTCIfAHN/ut1iB80+51An+TdpYT3SGAVM4RdenQ9IdvDOnQo2KE0E7BzHekga800VJrbqI8aJEtmm5mOjte2xHYSPFDCtwURQclwxbNv32hAY/IUkaejqg93WGIzHIIK0+SSDzQwHYQo4yzVGCKKy75eghpvGyg1zbzlv372bND+OuA3laocARFfe4rRd5I5nh8vmSJ+vybh3EIJJzloD+qWk6hsEagkYI0RYu9I2uOfA8drmZ02GV5/ySDsBHX7uhaTPGx4J22rNJoj8s1L7UoaohUHFvUerBvQTir2LPbzqT+B07wZOU0ibtHlaN5C2XMKRxfvGATeR+2J3l7WisCIoRdpQcPFHA7nlTTShBiCVstLxolvd7MMzPOilsi3ecxXLQSeWara4JILqXQCJ4yLbQCMnSpIrZ3TXbwbPZ8fjKjogHNUaBPnmd1hWoc7IVvK9RSFBEdCh9U/hbyPMCiSjdsUCTclmhFmhiVIlB73IyWixmLwHSWSl/ckMxcUK6rB0IPuWcT8iJkxfqOziFhMvC/cNydpN5Nj4WX21c/1M7lVlX10FRx6NIYH5szEXULmLnkfEwr35G9mKJwR2pgZ272UiW2cH64/+M+Kh7XnPbQKxTwVR3FOhR/qdSHeA8MTc9FDslFaTT6YSeJEPoQiLg4c4UdbB7w5nA0o4qg82hiiJbTfT2zFHZeeWOpVO1z4V8SidJrQkh8aL1/Is7KaDVNfL+Lx73gfO6tdSviCJJhD29iTgn+MW4MlGwpeLKpvq+LkXNXi/CVjIa1VqtR/Flk2BqwT2hccgw6E1ML+QdW1n3TvTtdLIvSGheOM5kLdnF76e8Nj0kHDFbnxQMlO7lutngaNBRAvhvSLccT76TMG4OTxNZk5aOre6AIOuUfrFD3KDeOqWie5zpkvTOd/JK/JDFYgbYQh8AqhwJ7VWUH49vfd6AqfwHwdNWymI05F6/0Co4xoQ6qN+iYNConUXz78Uo7AraJuBDQ3a24+wL2mLjnc8jUDFUaAKM6gZUv9+bx1vk6zVdaZcuqgZc6dcyo5Oy8lmbJ/SmRb8BF/Q2nW3SDv77R+p0bKPLmjcytczlMNct58Q1LoiLnGck5v0wByQ0XIMd',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 16:29:06 CET 2007',
+ updateDate: 'Wed Mar 21 16:29:06 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:01 CET 2009'
+ }
+ }
+ },
+ 'c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065': {
+ data: 'HxkHstm/nWfD4tTwtaDqycSrP6vR7O9JUQrVXp90Z+prnnvuUMH3SbOlv+AQZFJotuM9VVOh52yWcl8TuSJ5SYR6pwmZVcK9GJd3aRH48wBRrsi9do+pgyxmzfpBm+CMnUtI63LMPfyz/zPndUQSke5+G/Q1b8ZddaShjYHWHEifjdswmKg68FOSu7RuElR/FwRCBwuT02vMRdrjwxSxxM5zWB3vqzN4xKi/jkvqGgIc21m8adTQoxAJARleZiyWXzfPO/MpUs3vA6nxH6ZO1kEayGw3ZAR3nFBiW0UjjdXCBI2b4PcUP0nSJKetRSiudo2cUKfYxsWgEPoG+PM/CQFdnlfGcPf4d0QYnkU+JHff99mLJRmz7VWH7ZeW10NTxzTEr47diHLpyufZ4knnRgfhfKtwOvgmG1n1lXyXDRVTeyfCCX+mB5qdB79ujqon1BiLOGQfLWZ8bDyTZAakpcRJb8qk3zP004XwN5BpO+jC2waMcUEuH62gSQeelGZ19pzBiRz8kn3ZZ8iviX46Wwk3X1TTke9teF7t6Pop4pRkaAj2z2ji0mqWtv4T/3QW4Xgf1mKaT2t8ZaucGvZ3jrxm0CW/Ra3Cy1v1APwRPvKnY5i/WPDS1elq3vNF0NY7EQbXrxBX7hgGpUGRcHSKYsuftIquJFv0HV31jRhd99nZz6Otx82xidWbroIS+37o2Rr56X/AwkLn3DgH+V/YAK24z3Otku+lbaorXnv6C8ZDUhcce2CjgEuCFPmv928YOahgmE0Q0uKniwVXgXACevvACEsduvW32JhI4D4cjRWcSzB6YhqXE8QYCQwK97OykJ30Szd/ZYykiXjdjymyqFOmI9tZqi/PUOKRJ9NhYZaVAeLEFUunvKJWHNs50CqElw6z7nAvBwYyEVvvc+rSpMb2Z/KAWLMzv5R3MeITVUph/RlRlMIrJr0lBhmghnLRt6cGRQcDA2Si3tGAm34K+BpxVbTK0ilTrwzCfaE3Q+dvBTFRcZzMcPFLHL7Mho1/kNMb5S0izIpsNPCb26yH/gueYghVmhRL76HQAH79k00uJcyXt57AYlOYQM7FKDHWciWtJDOMNjVFDYQJJSAS39HukwrLnAdqCNrabrS+AuWhX+CqmMlKQ0PRszjtT7oQaAcgJd0uPOVz3IsjyZ/CmrzSxM+c4iPXugkiiyS2HYU7EEz9IEDvoqwv3Djcy4+3oxPUdmIJGMz2Mk5UXMDyMpqfuujirZI5r5WQWWQLivD9mid5RWDiQp2NYwpnQ/J0emEpWFlf/XkmXW+Em/A0+DOeJtHB729WsKYEvMWOB1nuITkqPJShf8FVEunHzUuLKsG3Hf5yEc3isB5rWGO8hPCueVUKgiS/NSCxQ+iinBTO3gUl+hzK+yaajQUomCx7+N9/n5HTLM5kFsUxZ8gfG3LMEK1iaza4KZeS8Hmb58NU3e3MI0FvlZHa787LqNO226awx3sX/nuTMX+LXx9v8/AMrkRdbzlcYbe6xWRWcBGiTirbTV/CXMgCdop60xfRqCskQPbfj89zpHQS/GiTJjhUwh6XKc/TpbjQJ6OZ6dAQBDxexPa+sjr70kLARxeUhvDUytp/zd/A5OBpuZ0aUz530aQEj8BCAk18vdUks7TWcpiw+/Lq//QLu/9uLU/rLanu2DFUYGXo7bJzy2QpzuoHqKDqa3anK9Gs34NfcIjUbeMUyCzd6CFj+1vGNIk4zZi44PZvmqxZXI8XcxboTpnheNRksjw36FbhIKWMWksIIq+mh4XMnkQcS83PB9rwMHsYY4nKfCwddYfRlbVjcjX+jSlz0r6Oh3KxVDP6dt37CPo8DGMvXSeU4LFMcYBkZ/Q57sH3/gyblyHK8OqYX3pzbnkCqoaOwAseBrQYMel3OgSLt1nAxzhN+ZicCLhpSYHCcHYDcg9xoa/1u4uEMJ0JC+/OzU7xp3nC4OgSYxVzL+gBNnqX4Plep7oikvE7+qymqwtoEhEEuaO5pbOdPG4I7NknL+u/RazjXdy3IGyfUPCCQKsjAEbAkD6OBZZf4St21e4sSgV/anAYFGr87fHMPtXhBxH6QTQPgWqrK75Lr/RaOLihrQHgVhcQHYcTD7nTtPNelbJKx5aGOFtcqykaVizLzrflZWXnk+QAjHo6Hsn/edm7Hbna+JTlyVsttp2vcs8kHQk6xcCpi2kR7nJwb+6kntEEPZAyuFQVwvdkqyC5nAecdg==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:45:43 CET 2009',
+ updateDate: 'Thu Feb 12 12:54:37 CET 2009',
+ accessDate: 'Thu Feb 12 12:54:37 CET 2009',
+ currentVersion: '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a',
+ versions: {
+ '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a': {
+ header: '####',
+ data: '/mnLRePyLGwPaZ+EkbTRHdE4jz4gY99jnHcIp7AeMfcktEpPmUVNWLwGSJUH3ANP/cO1znxACVQPzC+g8IVIK0muJ/lZ4Iw+HkpsfPtBjPZc+bfhsY5Mud00YBsImleIMlbbJGv3l79eSPcea49OwG30xro6b6I0KK3BmSgr+BG2AmBrKVlFRTPFCHRbO+hG/LgW/xqYgwd9f1dnbeVYCm5lA2zdAnwmMwlUIi/J73MbnsSO0Qg858iF1SPQ2Ne9Q8SCyKKEZwBY/YeSgDzoO76Wvqbzk8uPdmZldaF4zql3ffBeb9ZS9KIyyk2vJcLk7c3DUc65vaT+w25+2GSpEXD4YIV6VSr6Brz4w4gzcDMeLve0U6oruqWijz3CDe40yhd4mMt6wTVs4xo0KHc6yKjTuC1ZUQwZvuCiS8T5czaGpc0+fLyfuE+pVBxTlpOjkoZqzk6NsH5lcKMzB1TCscJ8fbOdtJso7DRUvijIE5+ayY9IktZhMeHsk2zurKV95A==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:54:37 CET 2009',
+ updateDate: 'Thu Feb 12 12:54:37 CET 2009',
+ accessDate: 'Thu Feb 12 12:54:37 CET 2009'
+ },
+ '4ebfe3bec6d419d61eb68a1f25407824e404e3439c23fccde1ac19225b40cb06': {
+ header: '####',
+ data: '6VvjRN9LKi7tt/HsgqmU0bUdZQNVjVAYNLdCrfKdRJCx3W/GZHHR/AQF0FcvuXIn0MWMUypHpTZW86V459OEoV4W18HXEisQKEiqBnUCBaxBd1NKZDpYsThISXXOhZSbXylbLoB+kBaYzT+Fc7utDheVvVPeMo+iEb3ih42B3En3ZXcgUAdEjfbRUm6st9Jiaz4onwXWknVhkF5QewA0GXDhT2JdakFxfUDay75wKvspq5IszbEYwsu+TEgsbuO4/R/bktgsQUrbhtKIEIiNSccDNx1JkUKvIxrRfp1m0Ar3XJsDfv7YSJSLdyVheOEdIpBkeZ40LN83uzGRMZw1bQsKf+XOFTfacYZBBzwVj8e1rJC6AWlH6Fbn0jXw3JcEljA4zUh5IrYhWtyIZW338UVsMSIp91USeM4uCvPsOLAdyCXiWu5H8MMYGz1rJxVlTbMiq0tn1w1f+CL14v8EiUft7l8kfZzBZzdLvzdedD/wHQ==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:45:43 CET 2009',
+ updateDate: 'Thu Feb 12 12:45:43 CET 2009',
+ accessDate: 'Thu Feb 12 12:45:43 CET 2009'
+ },
+ '7ef137cf242e00136e57ddd262edfe6b418b6f57f3b5e5e15f3ec1232867f6c8': {
+ header: '####',
+ data: 'N5eWFfsQGHR1WytyXuVySzJ3zenJEB6IaKr2vgWRHTlJFzexXzJmSLoozTP9Z4TumDOLsNrp+EUeIa3Yo+RqSyQKQRFDHXlUYa6c9PPLPXdexSA9JO3AHzMSpL6K0E4gN3BybjL2rbcQwUqJLvCKy44OdiJvORGfIIpTPx2LQ1o4P+chcpOwwe/ZhgLWmNC6FmkTvsU/xJlNuApyD7tPX7Cj3lP8WBfYEPr68BqTKAa9cxai6ZF4BRC//rFob/4pQNHE+7qjOSY9HOnV5uCtZehPYBwfpBiDYhaxWJxXN6sxtpe7GC5CM7gAAHs5lgVaFSWffOAL3zeX7I4vh3j1nYdXoh5KowZJVVUUfhwqJo2T3YDVsaXNibZIaPd9GlbeBBk2HL6c/ao6B8QNwRU7GvMHAdJKta2I9mtU2NCnr0Uwi4rZRR05V4k0HIMLEJxRo/IYAysAYETNIAXzk0twIokOF5JPjP4uTXRZ8LdiS6JqfoUu3Jv/7yq8wrKZM7DaQA==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:47:39 CET 2009',
+ updateDate: 'Thu Feb 12 12:47:39 CET 2009',
+ accessDate: 'Thu Feb 12 12:47:39 CET 2009'
+ }
+ }
+ },
+ 'ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c': {
+ data: 'zbQlGR1fT8HoH6KvOPBoaIjMUsVMh8MSNIzPO2muIMJDVfXB2rEcPnIFl8fNv9BtE9OLecuex3BQVJKGXdVGFYVNiSS0SgPoEpyD6GJntEIOaB7GnhVflTm8fT7Ba8ArS4r+fIL32Jx9F8sYrL6jKPWeuImGHK+x3X32uORI6znkRac7J727TiTPlbj03X/Fj3Of6Bp9Wa4xbVMwzi+R6NRKD4A6Za3mqhoSpYFeHWld8+ChJU/w2wFkj292OjPBzvvz/SR2Zth+AXTChreQ3Zl1hWNGmU2Ep8ijFCYwcamgPkQwh4vBk9NJlzIgadORcb/0EPDxn638VNA0dbpW8MZUCIMWVe3A8VgdllWxei7dDy1ri6xsKlFovLYjRRPXgAqRSqVATqwyXqhBWhoV6VZ5NaSUGvM8okC2GQSweLuz29py0F987MISmLjav4gdvcMA1wn7FOIaFTNg7oy2CxZefGhHT3sHfX/PIvs/ovfj+7TewI0k+HR414az2D5reo7S5I4+roCm1QLVpPNcXUxbAmEbjF8JCsTtECZ4kdpG39dN6BaMlHoHSN3wu05uTSn+sL7g3Cg0pVLlnHo9baw3fUnVJp3MCEgZJELaiI/WF1Om2y2S9UeLur18z5T7hHFv3Px28D7c22HEDdF2CObeh2uOlZGAa06lp7YlYeoNtb4CqLlZAMK0xIHfNUceC4OMNvqyGswd5WJsYQEnMry20OkxY6YinnQfjAml54B6WlvNVlg/YaKjw5AVinUHjzEFfQbcBFnFGpqg5qJk9hZmb1VI6Ujhq73fPydSfkvfScTImqxCNPD/BR8ovoaJtNpE2gmcoX9A5zhZgu5xUnUnXoaQu0l7K9kWof/UmCCl0O1A6j41aebWr+aoFMalaOPzNJ02vfLuW155IwjFQvRuAp6EuktZ2dFKyFl3QnLbwsMnitReXMoW30cqTYg7ODQnopE73RIb41Nj07qdx6FQMzw4gAIEFBe1iRvlMHQazZCb2ndVvgtK3ZcPNtDoahuPRxMLaKZlRnpa8E5F4o8NHYNivshawZi36Hk6w0dOimCiuk/zvJ1mtx8hhX7B5dsXlNcKxLSvI1onEm2x9HL318xJeT0y29alzPYVFuQs5kq1+UV3h2hL4E/H8h+5mWtTLf/MjaTZ09okW/etuHFFjCmLoKwugk70z2yLWEJGmbjw',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:51:17 CET 2007',
+ updateDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:12 CET 2009',
+ currentVersion: '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926',
+ versions: {
+ '3895963f82854530ff754c8e2d1eaef8d884a8cba7cd058b8b7adcdc12be3da8': {
+ header: '####',
+ data: 'rXmjQYZgxv9jpFus3T/qa9Qc1lxt+mDF+dmZeDmDG3IiE/LnonGt2MqL+YlbFzisF99Uv0IQGOZCPigtBwOXB9m6R6R3lEy/YhD/C6b10s80OBj3yr3PoTsoTmbnmZMYd4r+qx8SaoLLkR0aK6NADYZXebR5QgVtwF/a01EifI6YxH1wm1RX3kyRhIrMzOtL8zHbstPvW4sRtv2YpZqlZqBTdoiqztDUZTKEcCcU5QLnHYMNAVpDHE7D9WvQy8Il1taAbxg97Ir+2ktZLjqfJdKhU7ZLv8fcJiRgnQKPqDWcqpjA+CXM6Ak1HCf9SRJh6Hl64+fk3jEVAPmHvry/xq2RPCG2YnVNWZ+uL3QNuH4zt+IbP4FnrxkCAprmEiNwvuEefMgliGRd+FowIaiFWXcEtYxxQvRDujZN6eoTUU0KVnuy85PKi3ih0ZECoDM88MFhztwCG9/nJQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:51:17 CET 2007',
+ updateDate: 'Wed Mar 14 15:51:17 CET 2007',
+ accessDate: 'Wed Apr 25 10:37:27 CEST 2007'
+ },
+ '5311936f6a95cf123007ef867388adb5c1ec5b2cf1173d66e501daa16488e42e': {
+ header: '####',
+ data: '+VirbcZ59SiN9UJKrQkjQx0Z4avHIhvw12Hq7fs+Qnoz4RgCS17fqzYyJe+jYorjlMPjzUcALYOTobqJJp4Sp8v5nOilHW64Gny2XRp59PQPg0zE4TP22l1PzK04+qJusR5NLPU39hYbW+InkDapdIhdf+nIruqeA311bRLg90A8xmpzio6PkZxXmhZMabbEVfXsYFBQKVBFloTMusBG2eaxTjeK0hOAk0uEc9RGOEwCOvZvjRFCP8DyZ5T6QV1pYYgBFBwSFrB/koXmBmObj8zscJXQ4H4UWC0yw1B3ABbhNX7vC9q+vgZTxnGqI6GvzLcrzaXKTEyfa9twq+vKFX1hqDmM0UVLw0dPOy0/3tabJjFrYbz5EEKVin9UqWhuy5YIvHEJlMkH190Zo+lPMuHvD8TiAU1M/n1bTQSBQb/8STD6uqefbKS/s/bXcS+bdVKBmSgCuutBznYO',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:39:26 CEST 2007',
+ updateDate: 'Wed Apr 25 10:39:26 CEST 2007',
+ accessDate: 'Wed Apr 25 10:39:26 CEST 2007'
+ },
+ '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926': {
+ header: '####',
+ data: 'P1LfM+8PA/kyelFsojabLfBW9D0Aey5qDClz0OTdSamMT2Mv1U35eKcr6ilUrbtW+dKJotAzs3B1dYGzaEQ1j9HnhiL2pk4wgT1JWGe5c9frmFX/3YGO63c2ngnaC/Rrv3LC251cLVS1aoWNPskWkjZLzF7EiWbAeNYTplSa6MWm2LdHAm6xq2dcgYx53RJVvjnsCzpghQdzL96G8ScJjnUx8FC8mHW4Ds0rkHTeoM344Ao8J3o1XwoFqFFJ2X8+lSkj8LVVdjff1EHIicjrMM0oJG8VyxK2TxMvg4mnLWP4ALfh24Wrb9XmrM0NjhQXBo07tL9dwa7sHHKiBrM74644vBR7NB0+Laedg8D+6FmgNoR6icB+qvxCIIvAhOpJ0er9f0CGDDS06knx/lDtVVNewzxx4ATuG0HQn8M61eU83EfbKWG4Mg+9jtRcW0/bdFW/FQr/OeKg',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ updateDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:12 CET 2009'
+ },
+ '5c622bec0fb939da012beb98a858a4e16bd670b3e6fe1f7c92a247f88a65c747': {
+ header: '####',
+ data: 'XGlplDTD1xamZO04H6RiqcLd7XaPwxI3MqpKTCVHPBoMEkwE4A1izGjFKdPqHbQIuYYcT9xDgPOknlkP89jDTfcR4UfENtKHFgFaMee4orSER+MhldJRxMwPLorZmMNNZzVmTmwJS7FI9jYiXEvDbcyw41kN+SA0mxzWpc9emaX4TmZHzlBpY2zXKJLyN3otYYzcTWzuu7DJejWrB+CnNp925X9vVomBPfp/Gt4tiOFsE2ZyEf1B/7cDmMszlQgEgGJONS+C8Qyr+X3GEh5iPoYsGpMNmF7aYnZNciE/B5lP/ABVbZIi2KfmRlSf7Cc+kMkUXyHxOeZHuVv1ZlzfIe3gXlD0/yUJFHNju8ai+F3hpSkhMatf71mLQzD5oFrTmKatH+zQZhGPP9dQxG1cgZRcjbyUQJMazo+0TJuNXNndi/oiRzRJjYRUbZKsfRzIAEU=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:51:49 CEST 2007',
+ updateDate: 'Wed Apr 25 10:51:49 CEST 2007',
+ accessDate: 'Wed Apr 25 10:51:49 CEST 2007'
+ },
+ 'bad48f8ab053804a02bec678db01baf24de35ef04a17b90e1362e67fa352e4a4': {
+ header: '####',
+ data: 'SXl3D4C5Yt81L/117xsHYjZxT/fANq09VZsMNAz3Gcn2+2gopG+1K0JFg/1Mbjt4EMbe5Or42zBlJPo5EAldAfWu4MoTkQzo/wKPzgOWlIi3A9QwZegw3yCuHvJv8iNcpjGfpY0OCzTZKNomTtwc75l+8FqgwPDW4wDkPG98275ERDR8mFSZfUAiQxlTnCbskFneUQ6hdN2gywkyJKuTEcrMkIpzwe9uqPaQg8GjUvvy162/LVaSQAVRIiTbW5URCD+hT5cKOkmFeBejHar8zR3SQQ+tIJlKERBwfE0sNR+RebSboYxWPECYPp0DMj30FnHbfYIVTgRCIlepy2hfis0+9C7dop0jK2nFREjcxSIqonF+juCrfJDt4cTlpn2SmcoMJQsUOedSh6ZoWweXm7lu8buCbA2Q6SY1L6jz7okwIikIinxGDq3qT1pWSgpntI8wvYZ8RD0umJsoAzPYH9zlfQ==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 11:01:21 CEST 2007',
+ updateDate: 'Wed Apr 25 11:01:21 CEST 2007',
+ accessDate: 'Wed Apr 25 11:01:21 CEST 2007'
+ },
+ 'c03d1fcf5b6981741f5d4787315534641c61daee9aa3c063540fbb704989ded6': {
+ header: '####',
+ data: 'sbn5IDJM7VtYov3sqW9+/0USxZEw2xq8di1XVPMMZ6kN6oZZrAY7ukxXHYh+mfuIa1/uV4i4v1YCaKZQShLgUS4cchlK4nnNVL8zejGwB+PaY0E8Um/Jg6E4UAFAZ+haZwzWLQS8lJ1r4hNMTeFqsDRUhC30awJRz8e0rBejLZiS2Hk/jgpH3i8Za1GwDzogw11iHXejYI7MaQGB0E9eQsYYTxGjmzcLfVYkd4AKj5pSEHvsKZklSuWIyDzwaFiIO7xqcJmS/8Wkm63JGNOW3nLR5Ao9V/2vthFHBqS2lQNRnkPWXbmNK3v7vi57zu461w1Nn1U/70EvhHRMk8BdML3XI/U6WgDARjQuVsB8FnTkzapaORG5vUd7nTtWjPdyQzOqacm2YKWpAiG6fUQTZiBusEd8jdnv8BioGUTbXgNVG23zcRbbbEdjKc1aizXHQE1LnROvoHZHkwg=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:59:57 CEST 2007',
+ updateDate: 'Wed Apr 25 10:59:57 CEST 2007',
+ accessDate: 'Wed Apr 25 10:59:57 CEST 2007'
+ },
+ 'dbc283f49de6e303c06a52725b8187f344ba7b433b0158d704f094edba782710': {
+ header: '####',
+ data: 'fbNrpIoYF+gpMUjSxoOc9Y68qRlE2yk7FPPkrHTu07HHWkAWy7H7nFw4BwGiFViMkyEC2orUrMeDYhKmMYFj8DEcALk6452BtNutGZSoqDhD8xnSEPF6fP2Xyy+vZHp4JWDXZt/xHk4vPbxcwTTlmRz5aO8ChXIH5iqfRL9+Dx+gJDKgKmCRMZYMT1pyOUewmsT6QDYdGFJTRRiDmoLfCVAXhJRtqQSBcx3kN3kuf8gyOMAeJnFGISTAj7THzo7eGuQol1omTMgGbDZoL7WJNfZIDamiT9TWwzp3UmQcKIsRvA2ZKtePWRmpWyq6WydJgFXHUuUDVpwT+kc1Rn9Wq2zwm1VBw6gqKCp6W9bZO86rRMs2CtuLT+agSpqb4kz4SEYDCW0+aUsJDCYBXx5yWRM26r0XAbU6X0D+xopGuaVzsV5G7chkCO8mUsjHzZCK7hOAz6OgjR2+',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:38:17 CEST 2007',
+ updateDate: 'Wed Apr 25 10:38:17 CEST 2007',
+ accessDate: 'Wed Apr 25 10:38:17 CEST 2007'
+ },
+ 'ec525dd942f72b71b5fa1aca0a36a9960b71608bb27f32bc7923713bde021b12': {
+ header: '####',
+ data: 'AHP4MFiGukFCCnjLDGoqJUDEr6QNL+KoZlcwOqJIYusRtl5qmhZSsODHbAEpmadxLGogDPrWoH5/XLZ85ASGRF5ALzDgrFKP47/bSEzKVTDABY5BJSqvKgS/lCf2LdR7+0HWUVJ6Z3GOb9GqsXC70pMxDo/RfclOQPa+k/sXCW5u0TmLb/0i/dZEM8N++4umXsyy2WPLtUVzQZ/VdTMDwl50FeQxu3aNGy4qYd4XFk/7gxBH9skBD6/GqpNajHJrcbi/WZt7PZiN9skoVZHhm3YLmteP5hJnrcCGBFJHWuQpXfB7NR8rNmd2c6maemKYmUlX25wQF7JPcROOcyT8iYpF4Hk/eSPs0CSkaDdqSD0Nj9E4kqZrHfVGMwBbDFyAzdHTN3EyGuC4cBXdfNZbdBqwghuB1x7RLXs/pbXg1xqukjRdPLTxUogPdaQBHGo=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:56:58 CEST 2007',
+ updateDate: 'Wed Apr 25 10:56:58 CEST 2007',
+ accessDate: 'Wed Apr 25 10:56:58 CEST 2007'
+ },
+ 'fda6581f0137dd641387a7be193b06edea4451835817bcda38d22ee24ebeb77c': {
+ header: '####',
+ data: 'QwDMobl0Kds+J8mknphumnONOIF9gH+pC/AJpxGmuy/rvKfHSeEuuWAZ/yWj8J/I4V7OjpyTs9/uCWeKs9khpdkcxtObB36IfcbWBHGOgFjvqKgwMa7eZSIUPZz9k1NsqJC9nU9U7w5EBzQKVIjJaey1EdhsggdtNOpQTzt7iu2mWKo33dJKQCQ5VEwhpGh6SH1TgKFbdMkOJJY8d5xPYUxR66LVFpFzgHP0ML5M5U53PK+apT95UIAlqf7N32BjPK63Nsj1WPsnuuL0vWA3KmefHzwKGeatTdsgck+1mwnCDJncPWv7hTwMLGPUaY+Yww3K3YPihuyCUtUdV3fer2VHVAn++JdzerHiLI/86T8gHiLAi/anFFh6i2kMMVxqzREh+62n34MrgdMqbSFQb0V4Dhm45FVJH43uuEaoe3OJPtyvj1HbcSR4VEVgGkDeced8aAK+Dg==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:58:33 CEST 2007',
+ updateDate: 'Wed Apr 25 10:58:33 CEST 2007',
+ accessDate: 'Wed Apr 25 10:58:33 CEST 2007'
+ }
+ }
+ },
+ 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:06:54 CET 2007',
+ updateDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:23 CET 2009',
+ currentVersion: 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf',
+ versions: {
+ '12bd9887eb84b99ad40c1e413cccaa9ffd4deed340c71fe53610088faff349bd': {
+ header: '####',
+ data: 'MiAIw+S6GDmLLMcGtkl+wveV7dZAFrL1zGZh/FPvG4kpOBbnyaolRynNrL1yeUbEp4gLL2cK2BGYiVc9196PMOvKPHR5Rqp6GlT6h4RUJ+nFFF5/3LNGzQtJbiY0rrYKptqyPBC8mhlqtdK7sQkQonj5LPhKeCX6AyE3juBPEuFYhvTv9a/iRPub7BdlAocz+bb8ObpbVHnNvbGhiRpx9MpUg44JRxLQYhtDUMi2UFtURidKaK0k2lP81ckPDCgVgxy65FjCq05vSaCW0hanNrIwl+zAgi+3ChriqmflvsZYC7TQzUBPXrAQ8bKmzppZWlArIOppRF7+paWrHA3Qcz4uO5Sw3DvMwbgl+XINnmkE/EbA6VJOjrWYJjsibvbCw6vNr4q1A4Yxwy0a7EXbjFiwpEr+jMUhsq8+d0DxP3tQTusV0l9wcT2OWrDRKdjDUXLQOV9BVw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:27:40 CET 2007',
+ updateDate: 'Wed Mar 14 17:27:40 CET 2007',
+ accessDate: 'Wed Mar 14 19:00:21 CET 2007'
+ },
+ '35af99615d1be9d9841b4a37488fde9aac291c73c8c3aaa570cd05b3fd0baf5d': {
+ header: '####',
+ data: 'lv0pIfnhZZ6ktahFGl3AgAfdcveIcUyAh9x0iVOCzmQ9VjelBztlvxZEo+uByaFh1ptM+eqOFT/Vk9IKhNjRWTXrDXioP7oZ8IZ1kLfk/XuMFH9AgYzm3H1T/yLq5lg1WqqZ+OfO9m37Z4kbTjK9+adIAJ3TwsMxIDpIHYz+qbznjJocubYCbi+DC+4wo6qu5C44gf8n5QF8DOCGaBCyamxFvkqrSMo/Y+3SG3yt98MSgeMScGESuwKKGDHZX0v3ZXvl4UFbxywUtdbipDv4PAlzh0aadMsGqYwO8bPKEUElCWBXd6kASugaqiJaZFtb02EnC+nncv33ZSx+WyJqwKIBk/Kpd3/YDJnX9t3QU60j0YKf0my9oX1746F5u0XGX1DNRaw/1g95zRHoMu6j2cSTTX7CJglzIlTU8kglSO1LOasxm3Gt8iT+8+Lhh4Dw86ugqHXl',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:09:07 CET 2007',
+ updateDate: 'Wed Mar 14 16:09:07 CET 2007',
+ accessDate: 'Wed Mar 14 16:39:40 CET 2007'
+ },
+ '7cc6c6f2eccd8bdefddca21a59669655d7515f440b025144b9ba6b18472cf189': {
+ header: '####',
+ data: '3W8FqWzBVaEbMZRukwXcm03WbvITt8WVKKuJlcSszN0dCJEsIZ9vLAiDp6dfsFF4PEPcSkiy9Ww4FiBYSg5OLW6snRNdA7Wo62dJ3lqn8TjBzv/Rt+khf9mj/WwJZZ4wum+qdwTRPyaoZcAWgA6PAPPVp85iDBP8UBdiFOs+y5kz9GiB3psvOvqC9LZ/RyK3J+H7ierfWecnbqB9LT5Yuhfi8SO/gw+5vve6z1v8sVcexI0o8gk97rDV1W2gZz2WNtO7K5+233Z7aZlzouEbDZEOGG+zEYh6SctWCspgUATElf8vZ29fABsk3uZQO2tnBvINChs6jCRxnbmnjb2Y9R8u2QRtHjjvRro9E+zhQf3laJc0G0ZJp1zN0wwKx+sL7uM6kG1aszNJkzpykR/Uz8bKvoOfG9vkz9+4Pczh5xR+k9rCE8nbu6Yt4EMiUfdfjZJHAhST',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:01:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:01:05 CET 2007',
+ accessDate: 'Tue Apr 17 19:20:33 CEST 2007'
+ },
+ '95ef5754f9a4514e5bf883436d60c38c3cbb15c3f5452d512a05839ce20125ca': {
+ header: '####',
+ data: 'Rko0V7wG9GEmH9pZtXSfxKGDLRhZr65ef/DjkwhsPoYfLryET/ViMjcZcM2blyiLKOxjiS/avGGcXUmInz2AyD5dAFTGge3qAZ3QtxTcNn/fvfJeN+JyGJPIsTIQ7P+jd0uJAb3vPuymISGJluTsP0MZ8zxahSSRUV/VIYwm10tiMVvWEq0+8FynKfWDqJ1eU4pnI47CAdN9CuWhxi12RkMBYgiUzNzTh/tbPTFMc7DIyRfR+si6TuPS3PmtnKt4FMFAX3FznGBCNsonUFf/n7Zy+EYEU/B8wJO+18mqbui5YvmPCPPKiW/pfVuaWarF7zcIcthYoKQfTaCaulO0VRtTA+Wg2LtJv+QcWWWTiY2A9FC/PppLZ8+nFDeng6LqJYKoGnn6qwtSVH38s3Inzbs4r8mSOR099tqwfCnZc9zZHisdIbVm82H3gnqelPmc3IXb3nHb',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:17:20 CET 2007',
+ updateDate: 'Wed Mar 14 17:17:20 CET 2007',
+ accessDate: 'Wed Mar 14 17:22:06 CET 2007'
+ },
+ 'cc7ee01d38e4f1de010d2a235e3b76e838ca05fe70223b8358a5e41975bf2b7b': {
+ header: '####',
+ data: 'TJ5ClYK5JmZvEuNCA+/UeUJQ2rGXbPnFqWP31GAGXqhZmC0RuDNjl3sv0nFKmcdMa/BzvLSywJhkidoRhfKGwN8nZc8M0VpujFkpvdXgNsod6x+5LTMP67qCyvD67pkYMa7O+aosKi/ZWWnYBavZSdhyuWnU1wPxxk+wwcjjIrA5Tm5zTXM/68nLLnIWs2bQbUtcwHgLrBEUshG5oTUFGxrs8zYwodsYUuT1CVwODZrzMxvvbHfH6Lqt94m4hBF0oIrDCd1cSaXghS4PiZkJWQVxJNSsuYF/4PlPrV4ATZS3Jm+DqOxLOOnU2Xu1Qe9DxBppnXjs/WpohYuMV5YeD8iOJLXTQbFKhBJNSCoLp73QywWazuKkasC6cbBrTHYykEKXpt74iE6oKg67YrPkIZJ/jKEGnZ7wsY4ObeDTS7OUbHKxPHRM3ZrmB672R/8ktglg',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:06:54 CET 2007',
+ updateDate: 'Wed Mar 14 16:06:54 CET 2007',
+ accessDate: 'Wed Mar 14 16:06:54 CET 2007'
+ },
+ 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf': {
+ header: '####',
+ data: 'CiJDd/ShGw3rE0xCNZspkdH6hRzvSyaNiuQeMBI0NR1MReaa9uVMV6Ymj+BWVQ8FaOziQ94aolsWre51EKwDWC1otdovPXWHxBXBBI/Y5A4dyQisBeR5E456juUwDtLKX5En4iIuOL14IGt+keUtb5JyfBGuTTA+EnohYzvDxu9MDh/7nzCcWzUxh2zHEBSyowfOwJhx7G2xEvbBgTg+TkejMudbq9k3Owebe9QNdhU9rsY1UMxjL8+HgJmgyo0C0SA91tZXBB3i5ePvg++ze/SW/r+XO/nnVzcEwCJE2UWAL+vNh8tUm+sEbWaqyKwjHNSquxV4cYOG2Lzo45Wp/vZwiUR/8MK9THf0FO1mn3QCd/37AMMneI1Gqk0TNwNtoQKgLVBNhhgX7dIVpRxB2iiSBYyUK6N9LlFahW2QVDS7kdnKH3vk1cP50dj21E45jEhhd75v',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ updateDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:23 CET 2009'
+ },
+ 'd65b23008b22e5000726db3fd22b074b08553fe82245c3526f708b8d89f70963': {
+ header: '####',
+ data: '0y9WhoXwZSfzfxuql8LBc5/RiclPKQxcBYjcdGv7v6B+WuGrB6uu6d8pjNoUtsZnFv/25sefW3ggVgDuI5iZNg2lBQVIwgcvK5jPM5foit49d3RSWl74XdHY2XqykRNDbboKAiNfro+abo/YYQXjkhNBOC0dWSUUw+HmgK/Bm5NmJD4fDTV7OYFsvX4ExjnX9pktaB6aiLZWN1cZruW3Lsszx/ryHpDtcPrmK2hgLQ4FjRSXunbqXKJLOADQiMbGZ8DKZchB5NcEWlE3AfL6ybJzTyr4jXuS7A9PyitxYNKFHAHpJEhxGkyuhUE66QMt1n9NKzkNx6yhhGdIUF2zVGsBUb/pRrL2gt0X2lsZ+CnWFu4jRAeSi3KfK4VrvnoYkVlJImxPiLrzJAvqkuA6TyQRpJ4yFVJ0dgxBoxZVSN1fp9Yvkph+Os8LZscJtpYPPwVDlCnC',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:22:08 CEST 2007',
+ updateDate: 'Tue Apr 17 19:22:08 CEST 2007',
+ accessDate: 'Tue Apr 17 19:22:08 CEST 2007'
+ }
+ }
+ },
+ 'd620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045': {
+ data: '+iiHiN91FfHKOXC8Z/tg+YynPECa5sgYGGofcoJeXt3FAAkAFu3NsLuwjYIaddJiB3MIxFccrCrB5eDDL0SzOS+j63GcoMCeeiXss9YfVunA4RQTTktiU1BknPYfsfHj8EOPDSVHkPFs7KhAnBlgyaDiQPjYko5Np1H2i7F7pRmfC8W5LGdisaqxFDa+1ghu8K6a54QIpbfOmolQU3w7T5qiOdoZv8GLDDoORvMMb4P09IzXpk/yDEZe1GJ4g1a9t+lHAhiKSvdnZf+MhK0jvs6R6ALlmO84lRP34DmT/35Fr5C7D6EJl0OxXkWgYWelTlfU4b8+SStYP5LPYeD38fodSmObpKmpp653T1v2yaTybI1hojgLbH2DuA5VcQAM5JHMjoSy6s76mf2AZZeRnej1dqdvIOTf1Q6CR+ZNIqnkukrtGq/6elF3eZZh1Ln1EZDiTzsMxUHBngtiRmRDofqRSJUGbEAjw90dBoiaIO/WwLAy4cTec0nJxwYd5M7nchEly8Cb+zz7naP+vEGEAWq991u9NFZhrw7WgNgHnG0E3km+X+SYvv0i2MkqjYs6ItDkBNyi0Udnc4CqfWuKa9q04t8mZiy49LU34Ho4/ijuez3rdOeCO/oIwkRkLZYfFO6IxO56tAI3d6iJqmXY+DX0YUZrJ6FT7bDsUj0umV1htuj/uEgQZyOnKOyA8cSjOTMRIkodI12HrtdrIA966BDznsKW4F7f31VaSxI5ezHsdiYEsTqwaZlFQMsjfZX62EvDLJksJTe3JG15BNgsDUUh1mqIDCmVswFTpUTTb+50ap56c/uERSET0iXP8mb4hKwJkmngrBEir3btuMEMS0xSFQ2jTRjlnWRQr9eZT2biarzgEhKHyu2qCUtsUj7TiieQJY09EXCP3g3Da+61nBMoAwi/VqTI6vQaLGtuDrA2+VYGc8x1SiahmAkRPpQS+5N9qPvxxFRbKforMOvmeboFVxdKesub7BHIXQsSOKsHFZnFHswa/oLBITomp3ewfp125RjBUf1C3hMBNg/tmE5pgLqPfQqWK7IOnfdyt0jc391XWb6H3CVcgC8DcPKJ68o7DBucg9xTNwlIxBTafupsBa9JUkBigqYOW8729lNjj/QTvTUaCxWub9SDT6/y1wQUI1wyyg+EaR0fHqumMhIMbuvIPd/SvKMmZ4TXtBc1U3H3IGbkqIfx0f5rI6AuNMD7/pXTAy2Ot1ZBohnQmEotXRvDwxPMqBvPU74t3USTrysyXfJqeFtHi8GTR5X0m/PYQKWCCHgKvjw3d1CJk7tTe3iV2ulk5cnO7tOydTMJFgPuT2oyDDDTp5jYJPRE0OzZcpAzvRSjELfJ111sFBOEzTqtBUHA/E4BnTIM13md0ZaMr33E7ii8rS7vaKrQAI5moonAtAEOVbx/ZrcZ3kGzHpRCISeteHgnM4I90x391HqDkc1A7b+iDQF8OY0H/0as/3gaVaqs5jsuhIByj0+KmoXsdq3ZBhEQRW151QDCdMKdulNUxbKTYV/t92z3slU6lO8fiy+ON/6sTtS6jgnM+oCLxTfpfBdz0uKG7jiSOyunj27QxNjLyu1nF2+mAcDhtMN18QkJGLXKYv39kx7ny1H74i5rba32/QEAFl5eLJNIQbJZfZG3HzKMVS19ZGwgsYNqV1G52x5+bZUTR8YcrLWmPTJ322UxlhTmyjQv+fVCnpksBtjLGntsGloemFF5YVlcl1AfyHb+KlXiAZn+8vpfVVBddFFMeehokzYE1G8Doa/3huhqdtC9qvAtpP54G2p3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:36:20 CET 2007',
+ updateDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:28 CET 2009',
+ currentVersion: '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130',
+ versions: {
+ '0bea892da673bf4b3d3e4e97cd3e1645eb177a8423dc761583b876c5ffb1e2ca': {
+ header: '####',
+ data: 'BmZz8j6Khuz7Q11xPA5zSECcqn7BOcMtLx8AmX2iE4OrIwKWcZ+u4B5kCBxtFPRZWLdWcxAF8VfaedkHx5jxPNeWNIa7NEXXcFLYQv9lwUaxmtqodYtVapAg7N+onw28UnV1vB/h7ll26u263jWYohtd5eMnXhEjIEbrQYpf84jQYlpMKjUDhsVQeZvTI/KfiXa6O38ygO9R+xlq8xKgPPX2bkXfPJiyzlA+GoLSORc0tdqseGGOK4BFyp1V/KRUQ/7uQmGs1yNWt/ijaQtJXpWkWXmjHyTjXsi0z+1s0KH8TwSOfu8yjVshMyIyEDd+EsmZeK0QwMCm96v311cRhMgAkQOqL8xc2uRpGygtTkV2frthF237GOV5vwO9IoMZQFlvKZreV5mPPPBeqfP+o4QRpdnJRRCaP8Ds/MmzGBqE13ntwmo1UVX1k408ZtMCO7h1eQVTgCZ/Y2RD',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:51:02 CET 2007',
+ updateDate: 'Wed Mar 14 16:51:02 CET 2007',
+ accessDate: 'Wed Mar 14 16:51:02 CET 2007'
+ },
+ '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130': {
+ header: '####',
+ data: '++u0MEaILPK8riF0UzCnb+MnC51GYcdqCFRKOP7XYt5QvzWtxhDMOvq8ugCDF8G9sYPAoBLiCxFcuCtnkG4fp563VeEeC/dRnArzMDvjILYKAETgpnLQAfyIR+D8RfUkCbr+aOJ4XEKcy9a240OQJFDT0whoTKuX/6XVzVM/D7F0r+hJiOD1ELsVEi/+U+dXXO/VDxoyjFxfa1+M+Ygk8ewecX4nVqwOiFWHNK2lXW90inip0p8yqDsADx0KhE2tjARWVsjoNdf5RSUOYr0Sb0syyjBMi7oF4jpbLvHpu9fe8vpIcve+aSA/MF0Acxh0/gToDcO8ER3K4wcJgNPIs9lXiSrmuklK7kmS+uhz/rWCtZZH/OB/ov5sez5H51EYLmSNQbx5wZGZhtJWNN+AkJobg/Nt4XKRTe98CutbeiiYUGPxQvwG431Erg4y/q216n55FmCBIHZcUsa6Hk7ezF66c52EuAnVEkn7TZLl7vvym+sv9lKev31xpAGwX5Gy0tx2A7cSE55ZoyqOS9kf1s5Kwprx6RSBzfy7sffLSWHxyOSBnd7B1MNZglVSsbB1r4gMgZdYG//MZ/3IhTFbUqqw2xXHzTvBPA2Hl96g5Xzx0dVx2wHWcPcTSH23VrLscQCwyiDVINwmIzyG4CVSW/6gzA5VM4QYOrUDX2ZA5ligkZpWs0HTqmCB4SoqYJUpafaF2sEtCWHUjuVdw+rQiTBCcRTr8f1Vah2q2xbXMedLCRS3Vq4vlT0a/3wGgVD05CsAom31ZzmHQm94hZrx3FTPenhxLtTOHtDYXnbzYWufWEBSJs6VNtG9F5Md63NZvzEZiggfxTREDRZ7I9MBOPhrxz/3tAo+xInwvLXOEnTNOHVATm9u50kDs1qkJgqiXlxi9pZKmrTu4BeXS8cOxJ8O+Yb0Nh9bExfw+CC8X5xiWE58OwalxY2qlvuoR6mOqdcd+L7YPbGq+hJ/7WgJlrvtQe8IjGF1sJg6jfO8ZeGaPMF5NnbQVxGAq39g00on/z6dW0BLZyA6uglv99si8aRLpMk=',
+ version: '0.2',
+ creationDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ updateDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:28 CET 2009'
+ },
+ '63760358c7f5783d11fd769c78ca3f1ce787113368743655ade89bfa67d0d30a': {
+ header: '####',
+ data: '7lG/UvX5KjLbN+OrHbDeqXmweYeOL+0p3/UoLi2K93mCYdwsvx8mg+zghxwg5ITKPiZ9D/QWIShqiPpl+dvQJGWgs9EcP5W7k32CS2RNFaZ7U820rSpahHP561HDcBU1++5wHWszLnqFFiCuDja3OU90dsCTLI3g0igFgqpaRbjLcRTddI/1N48xNfV1YieC5Kei+jZ34zzrfKRn1f0F7mTkCqCSfygjnpRBgZyo9BfJ9rHULBvplvpslUUfFTShkLnCx0UbWPXog7DIZUCOwvPr3KJvmcZtCJp/1nW7gm0E5PaueJF10+ZlB6pKvueu+5yEgVmVu/lctmPX/UwTYZDgY5VWSWS3C+JNAvV87ZQKKmp8N6aMFMNOLCsOYL5hFN9uWGtMmvtgawqt7OhO9HukSUs8pDTgNeXoWyrorLM0cH2fa6a78GxNs3nCSUmqSQchJf5eWmASZgvI5xXmHXsNbuc4w5R9BaEPzyrrSAIa6r9D3rpFbUhMm+qPv9pZE2HF9liJVdWCBOSF8ZfCjsq5suyYz+YCsFHnwwpYmKAqJNXUMIhxkjgOTi5lNIsvS/iNSN9kdkeWINZk5iQFta34uJbGgjUhRy930ZGMBEV36T+Vb5tz50M6/MnlzAoUDeZAu54btKcrIpIq1Se+8zldwd6UKGq5nG+dMPk7CyKfZ5LkM065KGbgEJfHO651AMWp1sMAsbIAM6h1gVKbRjNyNwO+UK8eDpIX1nXHVj8bDVh96160cFbZj7htsUnXZh2AWuY6ahwdrGwYeSFoVAnd6xUF2oH+zFz2coLmLjD4Xm9IuQFsFO0U1Vo7EKUJHkPgIsXUT9He9tl8/K7UYQMXGgPTpercQFQ1ctFEqlPbFoVNO0j7Z9lmeSBcLdvY67CCbsoBDVJzj/wLRdBQStfeSUe7bEI6ff8+0gVkEFFACc48fWWA6NLLtvJkYjdojjA+C/Xf6EGNeXU/VENMJokB10EJUTueVWKHCLGI/JDBQBBB3HKX2VNFcEMJxES7Gfcbhysm5bdmltyRUJAIdXvw',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 12:56:43 CET 2007',
+ updateDate: 'Wed Mar 21 12:56:43 CET 2007',
+ accessDate: 'Wed Apr 25 09:59:58 CEST 2007'
+ },
+ '6e0dbb3c582039d985e80e10d94f424a63f0cb5b2ffac6388fd806ef89c1da40': {
+ header: '####',
+ data: 'f5hBUeedsvb1VBTpmpQ+XgGbnuVDMVEAdbEN7ZLK5k++4Iuw7l52zX6AHCWUFMDRfT6joiD2DMj0O8B2g55SeOQIAtZb4PZnbf3+ZEqKMOOI7iYSfo2PctLbzzzztma8EUXYkg7sJKCuZuyXhkWZxikBqVQIp9WE/bhRxa/atnB0jJyttnDMdTAN8kxIizrHFfT25hSbcPI1cSzsmF2nLabO6hLlm7mdLZCOD6DSv9hMeOXgqXo7XdfLA4k8swnOA/85HZFmhaYjTyoDGsK8yoJny/xBbiaRij1HQcHkbG6k2QKcs96pjmiJPoCv2dmsU3Bh06l1O4OEXl/RL4qBGJBKsDW/TXy7Qqa5y6LCEnlFAfefTHVgzuEQjJ2qb/z//oIrmujt+8hEa8F7Jyn6+FGqMNRxDvIQn5Ty/CPUStS1lNL1PEb7TA3ChYkYvnuhNVq8HHf47neGMpUwC5ppk5Zzb/5zEP0XH4XXkNbR5/TYjcb0Df3egNLSQLdO13CO3mKeoccmtfcmaFCtOLXWc2xNNcu09s+/QlZMuiu1TAzhWXU2CAXT7K794mTXHXjgGEaEe86Pj1nO1zHN7QhKDN92WMEdYasRAVDu/XYdzpsKJZ3POhNJp6pynotVBOkPk+2g04S8uujLVSIPZIwu7p3RmPQGGvfMviswhyPvSsPqND77j5msYOLCnXXjeXhOe0E7fIRpxPK1F6/N0R4tZCYNJe9Zo248XdqBvl5ZQWDC6aQH1E4djPK/08CS7/kAECqGqOCDPRvvMUNkGOnxsMx5eofr1YR7zWOZajr2GnfhA9fjrLv6KxXPVU0z702aS/Mfnf87ckGpOKA8/ssJiyZ4fzP6uN4pEb6wEta2DnnacUDd96nMvB9HvGCDoYZH646+n4oev+AnkYTy+ZRpmnsG6/3Z85iH3RwN6P2I3DWvGuN2e+1zQ2kaBMDms8qeXVY1+8qWr75ihizHCJr6E8Rd2Sw7xM0+6mKpu6gVGIi09auHg1+6Q6PlCr8Hy/pc4Exj9Hx1m14WKSF2SB1SYOnm',
+ version: '0.2',
+ creationDate: 'Sat May 19 11:26:44 CEST 2007',
+ updateDate: 'Sat May 19 11:26:44 CEST 2007',
+ accessDate: 'Mon Jul 09 15:08:39 CEST 2007'
+ },
+ '84f3b8571428014d04d7c05528af73c89cedf17e23b1f9541fe7060512f4c1a3': {
+ header: '####',
+ data: '2/zsq97zQBq8wE0oAC15HW5pbbzgokoDkLSEGniP1VL+sW3b+tXYOQV+VSFJo8ERNlCSoy679G7N8tPKgA+rO2/roGP/iKEuE38et9R6v9nhCPfo1vKt7XpvzJYow/qDwdStylXbfW9QN12Yx12r/nkPldVTXCYQDF0Vs0h/I1XMjbILpq1smbNXAUdn9I3W9o8KpREvac2H1ir2vYOzq9Ubhq4jggX/9s+FGm40f5MX/OM+lJGdRPCMG3rfWVeFeWEGWpmg0AXpV7eEuKH7sPrWy+QLXD1IwNE03QLhuOh0qEPsEi6kcCaZyLlCHYlzJ/hIAR1CBlCtGm+vqD+WRr0mGQtl81MMl6/BoW40dya/6aIKNOWfmYNgdfplknkVqxFsJnwVqjQJWfCzbW1KqBvMHx/7oPNjbMS0KKhd8ctOsTLSvq4zFI+mvR6BggwT8rwcfa66shJIaDDC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:38:54 CET 2007',
+ updateDate: 'Wed Mar 14 16:38:54 CET 2007',
+ accessDate: 'Wed Mar 14 16:38:54 CET 2007'
+ },
+ 'a4218c7ece0287ebad7f3cdd6510f424245a4d7d42ceb083b664a4335bcb7690': {
+ header: '####',
+ data: 'hQ123ZhZ4AiXD25P/0Laq3MtRO2oSIrY+GoYe3UAiyEHc9HZDCvR+POEEaARXNyh+U6z8S12P1GvQbzo23ZCt5byhqC+UmbfF3Y4FikM7WmHaRPtWjv8JNf3X0iJ9a2IBLA1BlqgJolnVDtrLsFx+6rBIU9r8pI2jdcsw9w9feRbE9/0S0filh66azojT5RM1qLcIUVWGixROY6PALSnA9PCjA6IG5WUa/DX7DyRrosZ9V4ZheMlzlz8CgEKBTN/HREIbPrEocBOvmnbupIEpOvH3OXKDXf39KAGVBAU2IIkOrGyWfT12p9dK+Zf+MQUl4DDIdAbF81Lus+LQmqtQ1ieyV0nNiqFhPuglLvKRj7QZRFfHNyejkMTZQWjQhBdHRmfSxyEgmFrM17yVVz4cMis/44g3szHMgAAfFIc79wq09oNDEV+ZUMS2xyBCALjRmhedqYIMGRCAG15',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:36:20 CET 2007',
+ updateDate: 'Wed Mar 14 16:36:20 CET 2007',
+ accessDate: 'Wed Mar 14 16:38:12 CET 2007'
+ },
+ 'c6613ccf0c1c6b65798c6f35657a10d4c6033aa32204a90d9d0274783a1098ed': {
+ header: '####',
+ data: 'ATU61Uq3Fe24JAEauMRtY8vMjzaQcPtnt1fshTD4dGuptFH9XoZ4bMC4XKHI7JKbx1NUEbR2ySOj9K/NJuWEGZjRgZbNI/KtuxNedlm/7jEpHQx4ZfhXQ8OiUDd+2bB9g6V0Ck2T1gM4IyaZMJ1QfOlYmGGv8n4flhHC5kUzL2OIiAxNHvKQjdEOccnEsk25Gg6FveKHD6NqVunsiCqhxJ84VBNzHJscuCTRcbt6KwR1+dw7Y+nhTjdDFq9UidlxTO0BKYsqj9F4Kq1LXORkSyab7zKooFH5kNd8torb5UFto8dfI8/+DOVHMxNRh2aWSn3O9bzwi1PfYO1nky2O6OKR48Y65Hp1sm3Xj4AAVHWSGakYUSV5M5XxKKzvoKY6Qqhz8GhbkzM2FC0IKTEcmINMvzXdzKRTqBFg6i0t7Qo80i3sQSoju3/4CYRozI2RrF8W4f3/0XgJf21oUAdTXOmSePSZoqhdejXeNQAgb89v+ZextxA6NJNYqvrx1NjdKmWKJIU+o3AgPYj4UIwWHwVADHITKrIWl/SbOsGP5aERtSiLnC+xqfRUOpgfkAYLcytspouHxvQjgNY4I1U/2S1DThG/N2EzuPl7GLYQ+Y3RAvLObFbrV8S3DS6vXIkigxyJT++MotIKoPBq0xDq0ck6joyvwvg4jXUMKlJa8/LQewJlbH8Lszx7SwjynzEQUJcpCnmxixzSNfRzpzgEBQSiClEEqArYykew3rjz9lc9nkdXUCzz81WYsvk6rGJ6ZdDsfKsG9+kaybuLL8huE0ERhznKDJW44ehDGQLr0phO3CI8n/9Px0PhPeZ1hvoiiH8CFSW5f45ZrFaaQG8hNyzWCpCFoX0/dNsNPsAkOJnO4v0PvO0HDOif1JjgPjCS51vBzxu8gYhkWlPo2hZxHhnnrbhxeBUU9jhLAx+NmxxfTjIWkbtHtVjm3ea/D2nuL1YrZKmQ3Qs6GamKlh3WwkRWRAVU3+/mbSGOISxo0u5v8QSmh/IPIXltniaQgWweqGNnCLWluuTyhoqnqDo0II7q',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:04:29 CEST 2007',
+ updateDate: 'Wed Apr 25 10:04:29 CEST 2007',
+ accessDate: 'Sat May 19 11:22:01 CEST 2007'
+ },
+ 'dd2b4cdeaedfc97c384f79c2878fca9a981efde6ebe212138db235e51b80c64a': {
+ header: '####',
+ data: 'd7ZpqQ4CTF00+/UnTvNnnkMXB2Ow/K9dys8V09Nedq4sgMUk08E1vqi9mdWbzNfRD7aV3blru8PfoRrxXRLTG/bjQ6xncecQoAJeUtSplKEO8fhuzGqbMqz47/y3aQDHBbygMAGV3wLgJO2Pv8p+8U/P3cEJisd9OqTNE+EYQz4eiq9dllMNUQjDY9aLHE8H0ny/5r9uohGNjXX/LfFMshjeS4rToCG5mzRaJPaRs1jkjzSntpF0RLxfU1acpJX4pNSuaLscdJ1lIwc17vygg6f3xexqvCeeFZBot1RwwbztZKbMfap4pRF5KoftD9bXJwoFMXigeMGLy0scpzsp1s8zBIwLhwUxEE0IBh7qeStg/3eRSW9slazuIR452O3Rysb+n/jWMyAhIOCSrnncjjH4XHbzV5GgT2d4f8jfBPmOT7l7C1ev41D3FGFxEb5TZGcJTaIW6ofLi5T5',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:52:12 CET 2007',
+ updateDate: 'Wed Mar 14 16:52:12 CET 2007',
+ accessDate: 'Wed Mar 21 12:16:29 CET 2007'
+ }
+ }
+ },
+ 'de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4': {
+ data: 'ZYvHAVCnw96hB+0XxnBY6p+vwvup1BopHUeepu7yOOSdYNFFOFEvtCbxXXoyVaKZAeSd2Vd7YEwRP4TTJjjWNPapT0D65AFqM8x+0rEjhmVfQGZAS4L3QctzRAgBoR1qTr0iqI/46ETkNq6vHz9mPLHEL3MQ/zoh4Pp0T+uMsY5ptzuMPcG0YwajSm5J8XXV2V5ZBEANpgL91xjgh1I9LiKJa/Lv3R9HAZG1uuCvzqjA2LWYeH+6ZcSpadk/UPxDw9c78FUnSNbHAcjuYZ/yI3v5SaZTjEzsB1MtAh6AFiHtvKIMWpqoOs7XQPhz1xXPoGZ7VR64A+/bN2h+Uqn49bQrKjTRGegqkEWFcBwhFH/ZkYfSHCGmZQTVqOakqyofJ22tS0ief45gYaO54YvIliTNTY7SZMRCEhUzz6dz8ENqP7FxhUVcQRbBr0JTmaf6DAwu86iDgkvcp1cY2trnUmlvrgz2GW6TgXoFjFlchUkHIByFeIJ02olfJg4zP8PzgYp2zhwmXL8iXHXnwzuP9bQKq5j8o+UhR11zn4MFvWQyD1UEplK6vphMdS8iXDViLrOwuMz1XUf7RxNdW0gqXwx+qLU+CeypyWLMIlgTlOr1pBqD/S5Jx+Gbn5GHQViuFZHJUjJsU0xel001KjB2Wf1Y15OSdLZ5l0tn/4HYKmZLufTYpub0xrss5r3Z72RYz3wvAWFXzkxWa+oBiRQiF6+ix8DBPTc3tm+ORnQBYcV/VNVRziimV3MFSsD1nHgIF1zu+eXIKE7/b3lzY19KpvtiBio94dejWoA/WO7KXWv2sHH0JoZnRh6lzu0HRFgYqVm/052nCGVA6XSfrFtfIupxdBs22C9wrwC5/Rwanf1S8BQIXpm25P4dv9Y9cS6c2/DUHcle4tsUJlqC+LpRGKXRdolFkiL9r01V09Kev/K2oXaWGYmBLbRfIyvEHyHNeNXv5fnaZ3pTlIwXjJ9K9yKA/1AKAsAEuKlM3N5ep9pfyuyfOWj1I6RvBwVqKvcBZtYJ4u8n9jrxiyq3ZZ35eB62D+ceOAD2s5+LL2IylYjiJA1OO2qpu4x9rt1NHXM6LYJAruBnUrJ0Ylqz/ElcJn/lXAzY6RLqVcZ+tuV580AUkFiaXFEDcqdJbbzh0R15g9DtaeiQZd1PG0a8Xblj9aMQoRDRJeksw1GWO7TfrJX1Cu4k+sgARWRzZ0DvB0SJAxPcmhg2iBByn2ESlcxPvMOpzuJI11BUQsZZ7dcynubeMvdqBeKsC6HMcm+8DLEUPmzsC3HIfARlNbt1fOrGJNuKaLvF1AAdwllELoPf3lQ6EVZI120=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:20:58 CET 2007',
+ updateDate: 'Wed Mar 14 16:47:01 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:06 CET 2009',
+ currentVersion: '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28',
+ versions: {
+ '201725aba7b4dd93531e40ee08eb8156e3aecd3db4f11e54d4d88ed5508c72a2': {
+ header: '####',
+ data: '4ndloDtoW1Mhat41ZlW+nN+WkdEriCn/z/oclyBFQSljJRlMwUFvzE/OCVYc2fQx1D1GBedY/O13v+SCAiJXUrr0dgrMDOfmYy7ZtNo0hYshjaYQucJovt7UQLeFAuLO6rNK9CrsYA/AWoiT878z2iCYCqVq41sL8juCm9n+d9aR0eyjXAKj8QJzVz/uvdudoGQ5xL18x2yUZnemY5gQklYlm0u9zzCJ3rLOENnnAggFnSJ0oysNjB2UwQY6P53bqXzF8E+u6Rv3OoIbmCIZMaoK1G5ivnWHwhLzp9UVdIj8ipfLsTJnGMk+aZ3nnEJ7wQCaaLy/lY2RYmSeUTTZt2ImK4ZLrSxRC21QkD+juyIiaEBJdhP8UOfcqE8Hw+etc/Cl0QgBtv9AgXD4BiZs3HUTXsV/PhIzP+6TGyr3/A2kt8dv33V7Gh2Ba+28wtsG/+HwCMk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:45:40 CET 2007',
+ updateDate: 'Wed Mar 14 16:45:40 CET 2007',
+ accessDate: 'Wed Mar 14 16:45:40 CET 2007'
+ },
+ '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28': {
+ header: '####',
+ data: 'eSAwxBi9CLckMV3o9PxBjVZZ47g2AOIsbPt8QMPta7U+6KKUm58cXHV7BDfRkbin3JYQJGYfu4HYHmayGt4IcX4RD3riftxnG3UFNqG4LQQ8+fwA3xTMBisnUSq0JYc/PKdBKzxH9x8moSqZC/cgFWe90p0PxdY13otjd1qvDL2ALAgY/uEDboTcLTbSEhpGIYQHtQ1ZjDG+KXI8J7atuMvS0KFreNUm9+uMZT0yCXwNpGy+ez2+ZDXTEjZUKaFPLI7g/vyySn6VMXmlqJftGXZ+fW5UWGaxb7WFa1hh/nI2okPuRlUQh50xXQJXVvanw1ATJbN1PRfYEfvQKLlAAwYuoB/qL0y0vU+3OktAbgBvwt9prs3IsqjwMeaejVTo3Yj9pQPJ14a+6lxQZQRFUaLePIPdYvq9NRM7chkNYminW0JN6umi6bvJ4KKTyjAglBQ6X4s=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:47:01 CET 2007',
+ updateDate: 'Wed Mar 14 16:47:01 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:06 CET 2009'
+ },
+ 'c7398bb27021058c9965a332d678b0070287b8ad12694bc8732346e6d84fe9a9': {
+ header: '####',
+ data: 'L+wk8k9ejeUeVz0offdItFpy8drMl1hi0FODBMKlPIAmEcNjnHU/IktOlyLrK0YHj66DaplXw2EyRkJNcMIbfACUtavxhWBH9VTftOPepsbsrU19aP6Xk7R1pr1sC76w1TgKCjE6IyBnK5qk1oHqcGv71GJLMmiqGivKyYOXQ45SH9tbHC4GUrg0YxoAYRwXqg+SlwRHpSZkX55NzPCEZn9eatGKCznTZs7pg0uBoM546fOIEBMgGndNk6gnsAH7At8yYxDMnkGHUctsSExL1O+W3bDDDx7D3uPkkjtd9se0exPru0fmsfcKPrcRkx8b8MAdgcylOtMdYvSudPdR6foSIqKMqktH35QlH6Rr5E/ire3O632QlmCieKDoPk/cB/qL3gKedxT1NxtC7SNR3aumKBAKOBDTVSjWWq3sIImQPZz+RUdRajeqkryNDVVPLFyjdC0=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:20:58 CET 2007',
+ updateDate: 'Wed Mar 14 16:20:58 CET 2007',
+ accessDate: 'Wed Mar 14 16:43:46 CET 2007'
+ }
+ }
+ },
+ 'eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 13:35:58 CET 2007',
+ updateDate: 'Thu May 10 15:01:21 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:54 CET 2009',
+ currentVersion: 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec',
+ versions: {
+ '157b5933272bb6b8a70bbabb7fa0369eb2660f7f0848dcc653f592f5afd4f2a4': {
+ header: '####',
+ data: 'z8BUTeAbrs5GeJ+SxaV9ceaAoqxtW/touC8xhjkEqbG6+IgMrfuz6ABRn+vwiN1/Vmfw/tyad4kB2SyzKgaYPH7rXyBir1mzJi73/oHsXv5wWNhEePmjZginGGcWQ0P4AnrAoxlaI8tXo3fbsz8e40x1b56N5J6zIdvX3eewgIMU+J+iomZVPDQq5DNu0aGUL1xs797FNm4vLQbVRF+mzrZlT4XZNzOr/W/Br4vG/Ureoq1QRjAjj+8HRt7ojmzrpDX3RtmSbWqUPQqx/KpFGqVUNw0zs09MomVIYilRawe/zegW2KZKK4rmqoUm+mnWQTf/I31FYO2N8dLrI7OV71EWlVN4FSO2A7NRUd92uVxHzItMQPS3CSQ57FYAC+WhJh7k+/ikJumVSf18pZRSRaEeKPxbJZFJqrWsWk+SsqBIJ4EklAnBBU7zLmMVe3GO/ml3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 13:35:58 CET 2007',
+ updateDate: 'Wed Mar 14 13:35:58 CET 2007',
+ accessDate: 'Wed Mar 14 13:35:58 CET 2007'
+ },
+ '1835468626573e6189e5302f6f354628f49900efe08adc931990d1c11fd522ef': {
+ header: '####',
+ data: 'Bv0je7USknogpb1ng86CEx6GbHlysuN3e5Iy43kg1iN83AgRm0Hp6/yMivQe/mEmQb+67cjHfKKrznAESYzY8uv3b+ystxoIaQL7tKJ5HYu2NUVvZxRC+PE7AkBhc+O28OzpZEHXXz62uZFsjRDw2hC/KP1XfYW+Deuulnpz6sgjuyWIYXF2486DzaycCqX0NmYXKE7oXAthOlbo+Zsm8Y5MWh5ploJFrzhAm0CCzjsGSa7NBOBWU2o6vN0NFMcOG2pdjZGWpWo1QQ5G9tx9UvM5pTamwcg5TOr4yOd16JmYTDjK2Fd5mdUuG3zIxFR8StIKI/Sd1ah8U+DGbNlVYAVb5OREJxQxVv6I5dxGC43CGWbpx3fB5wuFT3Jek6tv+LgBJaI9Ika79NFJQrLVMFbQgD0qU8YgCmLbxIJ4gxMBUgTN+v6PraIDHleYlpW3KVIiNxv2Ztc=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:24:49 CET 2007',
+ updateDate: 'Wed Mar 14 19:24:49 CET 2007',
+ accessDate: 'Wed Mar 14 19:24:49 CET 2007'
+ },
+ '47f73115ba2079f4b3703f502e3455498900a21941625c25d52ebb7da31055f7': {
+ header: '####',
+ data: 'pK+wAHWg4IJcixnFodLQ5EH+SFQIOMOrthx52u21WZ1ziRWJLSYGwA8CNNK8/welwzPHOPWu2El+zE6cwLHrzmL8EARLvvJ2fEK11ZIvF2C3R06uNrA7QFZr7iu6t67osrpfljqbjKQrMECUCUDrBywRvlpaeIlThfA3XByezK2HtbyHD1/xnyQSenUFu/6Zq1EkVdm9iCkbej2KxZSxA6qMl1WcnplBdOqBSmeGGJ0+Ikn3LZ7t4ztqflsug7QYyQlrmI+d0UB8MFWpf6jYjZQwf1rMH5XHFvrWUCi5IbFNJBUPF3n3IfUlrnjUSBEcW3tmodJa16/biK9/iKqh5ImlnpbQgK7CStgQ8ByJqddJre1idCiK/dyR1z+IXHTu4qm24cJeGUk7la4WMG2O5U/otFbXG5wTVgbLsxfXlE6fzxHAzvEftEE1ZPNOBpRZ+LVYEHKFESIz',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:41:15 CET 2007',
+ updateDate: 'Wed Mar 14 17:41:15 CET 2007',
+ accessDate: 'Wed Mar 14 17:41:15 CET 2007'
+ },
+ '6564169ac5bce1a632c602c51e9e5d637bfd4e87c1fa276e2cf65f39405fc4c9': {
+ header: '####',
+ data: 'fs5hydWDsT/FxWTb57K6zYKwVF310zjHHHtRS/AeBN8XZqTcirhV9oxJW6G6TdDkD7nQfWf53AbsivXn46Tx7oarzoU4R+1mz94TRCkEe5X2X7Wa3HbTj38+QwbkomF7np4MUkVc06aRPqkUE5hvSDbGn4SyKCjo/AnGhuW/QJIqnWVj70tf7CNTb+GR/y41JhJd7yk6U3cIP6Imik+DAvM5pE0KqxGLfLs4c1ChuTFNHfiQbYjs3tANqJCO185t4S8UIY5VxMRcnqgRoloFK3uFACIXoyDGG3FjILgxRCw2ePFsrm2Jtxv+JX4BsM+KDk67OsN91rjQnK5vBP72SzSge4EDCKJXYKdA8KJGYNwRIzk5d5ycbZgW4YCizVw8v7sLMn60v7YrDfBwXAJvvlTP1chA7HoE+WALqXkfBW29AOCNodE3eTXbI7iWz3vcWOCPvSm3hho=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:25:28 CET 2007',
+ updateDate: 'Wed Mar 14 19:25:28 CET 2007',
+ accessDate: 'Thu May 10 15:00:47 CEST 2007'
+ },
+ '7674ea33b650e84f9a461a91928bfc259de5549ce905339fc3b23623c6cfd09e': {
+ header: '####',
+ data: 'D7mLcDpylLnklOtIw/kvYX0M+CR6Si2t8CB9bTT3ZR+bTpXP88OtI19g1k9iPEUPdgbtFKPVw4oNmynP3x+pc8R/zzn4v697SvVtQxdF39Jmry5dnB4SMx6oRkuaISs0nxvTrHJe8U+s5ehzvQ2WWxWZ+LaoBWaYR7slgUFKLdJFyWEalPwMPVu//DoLZeWg19n2C/0Sy8u0DGdYHJVserWrQqxxg0h0m0x1wuKhF7IGvqgyJ31T5w00nMHNZbs89cUuqB/2doMgoUD9BqV7F/53AveuBDcdCc6jlEe8NOdoUyMuhwwwTyKONfjY5e5Cu5W9I36o7GpeKlckoKrTIWFO+NLG8XZvP/f2WJCsIOrCk/LI3C+bxBP+bK4tHRH13iXLeJYUlMK4ibcf8WI445qNoggJSbZzGr7Dav23KZWPcxzRxhI2u6j25/kKGnu4kcMB8ke5N+4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:46:36 CET 2007',
+ updateDate: 'Wed Mar 14 14:46:36 CET 2007',
+ accessDate: 'Wed Mar 14 17:40:01 CET 2007'
+ },
+ 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec': {
+ header: '####',
+ data: 'u9HEcfobxZhG9BY3dVG68ZUYkREFcZ4q1o/xWyt3qje3icA+Nu9yCrZip/4fqe1daUX/MHyzUQdulIfjSwATjj3vvDSPjuGvrtx8oUjJ/K6GFsL366ozi45LkqkOaH02/nVrb+ik2HWIgcne/OzNrwf1mWLJoBF+8ZwQ44xqQK7ikG1mblNWWbZFFQE1B0QPmE/I/1ovm2hAr1ZsNj1l+N96hwGsdsdVFTzn+S7Sg8GTbxEFAxDQkBYEw1k/R8i9EIBndPoDZCebr8vP+c8qSEk/YmBXJ1MGVVvic0/Utn67iNLz9aBnv2z31DvvBj8bIwOxQpB+tom5Ivwe84tFkwwvpxFqYccrEg4bbMcevUo67TBVe+Lb2wzcK0zOr7iHhswbXaLzzOEQ6uF/v2ibTbATP2zNq09AIJjynoSDmrisGHsBrHgeXjiDspc9U70PVC83EsjPRwA=',
+ version: '0.2',
+ creationDate: 'Thu May 10 15:01:21 CEST 2007',
+ updateDate: 'Thu May 10 15:01:21 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:54 CET 2009'
+ },
+ 'e699fa287c2de3d483144b48064a47cd0bc56a436431ce23b48cb8d8c42ce851': {
+ header: '####',
+ data: 'hVD8NOt8g/DIe48JbUUo77e2hMf2UBN6ah23PrIzGTpq0LifC2K/0/s0yeL/PHUOncdT56NccKpF8Fp6EWJqDKoKZPWASuB1vHCEkdbcxlqzqo98VS3A7p2JFwQzSv+5t6y909hhbxobXMCUfZ10HBqGo6TaFc6+pkYqQ/d7MEnj2NuAXC9X9TLLuZSrZ96NCKGr8YVKzxinxHdiF3TdRvIppFByXPlbZ3xiielEnYm6pu/GffW7Hkwd7Vou6jwyggxVqvoVtuAdiIy67l8GX0gQUGipFkvvrAkXfm0sgtWGQvpgDuV/bXq/L5vX/sFpWI2u066lMUOsJQmptNP/Nkp31+ZNk1nCcUIYDDa6vcOy/gRrOFcenPTUQjRkE95KPaCqYBSIWsjoFE0EIB+iBnBCTK3laBSC7pplOtuLCY1YJcJuOkzCVQCVXjhWrNJM77s7a5OyTuE=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 17:43:29 CET 2007',
+ accessDate: 'Wed Mar 14 19:23:51 CET 2007'
+ }
+ }
+ },
+ 'f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732': {
+ data: 'vxOgJv/v3pP8GFqbFLTcgtBqw8V3zhCN9rRXUuWAfatABtr3pySWvt74ITeGw+sDtApBsu+zTY/95BFVtK3y0QJkC5cjJYhLDwvMwpqa0lRfCXWSYmuEhbPETwkW1MN0kAEOMqsUD9cQCH9GDD4A17W89AoTG5Ce//X03YBG0cDjbotgENsWjQpK88LXABHBQAoTF0BPDjN+xai2QPCgN0l1IVpUzI87oZJS7x/4r6DjGTOgcc3+vtEujr+8dGNaq9xTEfAFs1kv6GMeT+R/VkIQLVO+vSxi2fd+954EAXQplt047+aZ3c0c78N6B+GhSi9DgNnbTLu6sl332Zdgo9R09uucS8nvRp3HcTzxriKpx0ZMDh9K9ig5NT9Z2H49pDjCJKTukDU7b2ktOEUNZt58s+uIlw1bMFY1TMETGAHbTq+hld8Szg8f7nJGDQF10kV2ykVEQ2oUBMC9y9VCLyYD0BWId6DUcTNXyI+MqAC4j8pp0NhURY8VSjtnV4Rlq+b48ahP/ifJdq+xrSiT9ykGqc/EyebC1uCTIZewk9MtIAndVYPckMIe0xQ2xhX6/m2bdNboVa3dnS5eKFdbd++un6FD+QAjgtcBkXQnwfptottZoghclKL5h5gPePCQL/66CLYy5+3xctfCG9u+VkH97JKL2hW+XZ/KuxLPFkIAYmbFKsNdIizfpbk5WJvoSzacpo1mwNjZ53zn9xhy/VkSIz3lGl83a6FyoHuR9VklyhTaKrj2JNWzjLaQPiR9Sv2eFNjLTivxtxLwKae5Tz14WU2QlXATC5xdcLeF9nK7yYVarcKlRsYkkvetrVpRiWUVfy9mZQIHOWJtY5AcptKso2Q0v4CuD1C/wV18DMDXzwMXeOq0cKxCsZOuWjO6RwWKzfeZnJ99S+EsFmdI/wxqiu9slJ0xXvgLvjiJhJ03qWwZV45peU1qmvKQrXS80QqLp3kUfRGLbZNOvkZbyf5OK96MA7lok8PuCZGg5jZHFX4B3vxSQ32P7VGSWO5CqHpF45YwtlONZKB0cuvKTRazZ+B2zJfwMYRQloj6sL5501oPqmjVtDg+0aoqKe5DmTf+fHV4FwAxQ8RuW7/BVL+lwf+zjtd31I/yrlDdb/Scs6yayLV026yuHxdQRl+ByogtrXbY4ViuU3NCkVrme7K7meRHnQdXyidhjzHdoJnRPa0IoI4VW3VwWNENRRNDTta2whOdIKsQYtscWBWZnQplRmDChGikERYQVCWejDNgvnbnGrlyQYPF0/vcv6PoDpIvh7Pze9y0MLBU8DnWqAhpdqHPNVdjdq51OKlSitUk5TSN9kxePe0KNFZueLjxZHUFIZ+SIkTxoCoaRWYMJIWvYkcT5S9Y/7NbdapuUaLZNGDc6tgD+LVYRRvGEdPWaOHb7G+qOmdtx8vYxZUqq5mtwnIBRzEllTJyKwwK/kOfAxiRjLxf7SOXsubPuA7bHR9fI5rROSR5rcU+nOfSV9Wf4wZkYBlSmQYqzQfmwl0UCiipJVa1DwYwLimgo2RqhI0M38gEH+mrknnevE8zlUIaEWzxoOnyWbtCecakXS2XvE9j64dswJ3bbeQ3fDQr1308x9qKSjFdDl3eNcJx2e9YwC7wZnTmHeHzRXnZwXsJXqMPDQV99wEDBr71BjlDjMx7vG9bOWrhsyJ37EOvO2X41Ij3j0X4MYpbNgxBFP6zJSu3gILrtqQRpQq6mQJ1bWHyCN1ge1zKNT9pG6rGTRPE9LqHROQuROpgFM1R+DqW4XnGOBYSOtznnsnj5fxfdpGeFq+v/ftvVuN5XsgX6dnT8R77iNUs86Iz2mkxLaQokkNzXl5o1rnQIse9+kcKVZ72mf5SG9s9DD7cZ7bOtmkuZCexJpieIosqLV8jc0IA',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 17:39:39 CET 2007',
+ updateDate: 'Wed Feb 13 15:29:04 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:41 CET 2009',
+ currentVersion: '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74',
+ versions: {
+ '33ce5a03b6d36f59d0fbc9445dd01a515cb56eccc6d854cffbf8aa66f3e4a45f': {
+ header: '####',
+ data: 'pwMmqFOwpW/uSys3hm/AcoERF3eDj4dO+O5SdYsR2mJtmEfXcjhS9altLhVOsck0KMQJdxE3rNDFbduF35yVetXuQrrL+bSRlXMq03EXETyrRzIVhFEM4BjoCSS9nKGgixp04Ve9WSuwD4cXRmcN/L9kCJSCqflXqhkYkjAywQoj1KxHPdAqMaGRpEWioUIfX+NiWbO/qtOu/USAhHmWFXla6/A9kKQeU2d+P3zl9KF2Zm8qm8NXjPKmh2dkd70ATbdzxt9P3BafoRf/Ud8zLIVdQYTbv0pn6UMIiUDRK1ryvgfSY180zg4qkP5pBnxhEgOxbjT8JO6hCl8n2jUCRJLdUXHwgpeuHcKYDyZizc+p9Kbc4+d8K/2UEKgSR6gza6Cpw5TQbZQq+2LxWUoVb3HM3lTqBKUPM0FdY2/3twZm/1bI1uBMPnyp9x/JsQV+xOpu0ZulTA==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:39:39 CET 2007',
+ updateDate: 'Wed Mar 14 17:39:39 CET 2007',
+ accessDate: 'Tue Apr 17 19:09:44 CEST 2007'
+ },
+ '686ea579db132287e8e322194652ec57cba6e60274c00f734db7a0b36702c817': {
+ header: '####',
+ data: 'ilf8U30hSq2mqje9kZkKQAMiEFV0aptXrm8fOtoOR8pp36V29kXyUX6FEOh5eXSRr/jbqGytxKENJeAGxnsv5U+8GgbvlYaR4MPM8lbKcpAoBCc0+CCOiwnp4XCoXFCNttbTzfb6qgR7wqdK7YLnrvfzJieQqJukQZvtWtsVZB/Tis+5niomz8Ca8lo/FjFOIjAq6xtwrW4CS12+yZdTKNbj8e+HwoUcesF9RbCKQlpVHuwhZ/8ghdzDgjEE8z44rDepEv3Lx/aUi+67velLH3j+1crnxBUz7wP/dWzftwWgIxDkCR/vW63yY2Xebt77swDg8g1Qj5OJdYiAq231HKaZjxr10y88JI5HC1EvbbduDN6pknKUgM+qEdojpi2BmjK+9MtV7sVhJoWqwHG8q9z03kgGoFnWEb53HyMVes1n6HYfzwnw+idPFWGZJ4IB25WfJLfQuQ==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:12:39 CEST 2007',
+ updateDate: 'Tue Apr 17 19:12:39 CEST 2007',
+ accessDate: 'Wed Feb 13 15:27:04 CET 2008'
+ },
+ '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74': {
+ header: '####',
+ data: 'l18dnf2TRfinuu9KDraIo41yvG3mNFqiSCOkyMI6WZZD4RnF8R2Ob19fJ8zXv04eDx7TYyyGP1IlFWEdT3LBrOmmbtUmIvtYanIfKTkT6UGHNH2jh1HyHqJbpgIlr67mOm6Es/AgF44BiyJrk5R1y9tA90oeUQynMufiM2MFLpdalDYWEh+W7GV9WCmbBIU/soioTJ1ep2gvy4kJvTSrXENaxHevKfYwn8ucocvY+hjkWB4GWOR40qtaG06wWMLeRsrTBH1jBG9srzbBa4u2IQ0+NJjQrYdiu7nfu6Uyu7Ya/4bxV3Sukao91XvXSFIhcI2OuKl0njUshv6BDEfHwXIQuPtn7KaTx2uYl1pUeTv/tAFvf8Ng9OFNgK0siIMkeg1thFwRiGSmxjP0QZipDtcCekIxj2k=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 15:29:04 CET 2008',
+ updateDate: 'Wed Feb 13 15:29:04 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:41 CET 2009'
+ },
+ '7ee6a662d1980467eea86a58cd7299ee02000740693df2a7ab9dd64347dbbaa4': {
+ header: '####',
+ data: 'ZnwtGdkg72+TQKCJQhZQIqP9sz79FcptnmH8VJEDQY9xTburh4cyhgbgROBis+awp1C5OyiAAoWfPnuRAN8Ai3d9f8M8yjnDGJ4BAJ6OjQ5r4RDQxNycCApXWO3mJpBrx56wMsCVWT6Z8a4khzPrf5HlDtus4lRV4GRdhU9FMpwuaCfgVD38MhlYXDaPgyu/8N+6eQHuFxquXjOJmptfO6tVhP1+/tEHo6iUAX3sXMZAionssRgPllQJxfzrsu7GQk3h66PakRzgStTHUCcdyoEe9c4VnvUgaasTbhENA4x8xPrxjo24zwxfFpWNEb1+pe8N3+dOXTsIdd3CMKrxQ5KkwzyN/Bj9jXNk9YX8PC0geJiR3bCGtPsAd7aEFB7E6y0RVX/RL5f6x0utSYw8mg6lfprlr5A=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 15:28:28 CET 2008',
+ updateDate: 'Wed Feb 13 15:28:28 CET 2008',
+ accessDate: 'Wed Feb 13 15:28:28 CET 2008'
+ },
+ 'c860f9bbcab5fa70854212e18c11a3e9bdc2382f91cfbd25636955c443a05f8e': {
+ header: '####',
+ data: '1rztZ6mKVFVjlL1kEoUsXEMketdElGbOpYK9iy3g1/WeMcTd4D/UjgHvmQHzzNuYJc/yx6cCMMU9dofLe3vWLKhqDAPAVCo49qiH527hP9rQE+0SNO1v2Ymk80hL/gqBfju51bIYxPKAD0uYA+GMX7OdL+S7qdealebERcnVa0K1AHiVU8lu5yIKk55U8zwitk0u86J1zwcraiM3RGXir/x3oZRIKDwT+lhUJPr8GbVjgKlPu07Ii8OdrAGdHefETDlyNnaKPJHTbGXkd3HZ2CYhJCQZGn1Hwfs46iRd5aO+3UErYtgIHl6CXuXd4E+DNW4UJZedP9YV860DBkpqMiQokEMYTh8Y2sOUyf3ZEOshfGvJUhj8O5p7rNm4+2BYO3XhREdV39tn4vUj56wYj+GL5CekEl0c4Mx7ViTQA+gLvk52V2w/5gFyFNQ9U+jUQpb2n+d9cw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:11:33 CEST 2007',
+ updateDate: 'Tue Apr 17 19:11:33 CEST 2007',
+ accessDate: 'Tue Apr 17 19:11:33 CEST 2007'
+ }
+ }
+ },
+ 'fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6': {
+ data: '4zgqvaaWm7nJO09LKN6o5hbWwGzOv7VVmXDu5T+JCHTSOXbteogax2Zrv0uKLkfooGFThJBk0rXfXxE64vMOq3AeHXGw7Chg7hz8Z2Lpjr4FfE6q7Em7UuAlAuL1PiyXXJJK5iSsRY9tkizuYl19aXW+CgpPznYD/PyXgeYxqt9WLqK8cl5iAU87R0cQDhwl16ivzVgiiFeaB6B5FQqWBAHCEgXhqTsaw2gv4snbmPOqcUZbHy/Vb9hv4lPBJwGFNxQzeZUad92VBC8YbIjmbohDsXjteqD2/k1qOgpUB/U5BpyVwsi+5ahgb8gbS+AqYoRDYzkaj83ksPI4JzWyZhpqjhDauaI6M7hGnJ4GB8UZc0M3WPgrlf1r+TXCgpcfembqL1MyteM+C+ItPRP/QdaIXxLOmvGFOBKQYEI7UceUWBCSEzORlS2S2lltlqt+K4B8QTULiKaXCfRmF/u60FpJufIkUX0pE/rQVChxswSWvh7uJFDBIDx8MplTX724A7DN5d4/Ad4Yi2cj3V8X/DEErnHTvirP3tZ2F2oAe7kIdu+JuCqKcMaGB4hVijzv+yim2TCPvrGTFaMmg9PvcWHpik9jEIabCkdqAR8EGIkD29+yvG4vD0DTRKv2vPIfr60ZQnsgs8nlPPoNa6lNHvI/EO0nBGBYBc1TW+syV5h/zOG3rHX0XCHhISZmDMjra7eUETWChncR88P7ciC4yJQtzXFGzeXp2ktzZ8m5g1EQfgtlUVZsHN8e4OQ9DjKt0unfq5RFBj2jlG8TBZn6ZpebxWR2qOxp81KQLHJND9zRTy3h65+k5wo3MnnxE3GbeXg2dFIORRvGUT6bWsqW1fqR/pg1GO8KNtrt3CryZofgE52kuk6hlcmSk9974JR5523+1/hbts8n5VrTi1C6GWhnxpiJb1XIvICdag5g7C2iYppzLKVzbJcFMegwDUrapbmGhkqnGwSY1EQSDyagPr2xlziWhdWdCOVAYcyw8dOpdD97QhVef0OWrJ8nbgFKD6wn21475OFxooheWiMCyZwXqESVG1cVCjeaCsymBtEVPpmQdSkOfMdXpKVF+3osb4K2XDpPeU1zPWVozeMp68YhLztQ/g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 18:43:29 CET 2007',
+ accessDate: 'Mon Jan 19 16:09:30 CET 2009',
+ currentVersion: '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a',
+ versions: {
+ '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a': {
+ header: '####',
+ data: 'QfC77EWgmmnxz9JqLdn9Tw7mNztfQZPdNpaML03EdFpphsjgLloqBRX0UZ21oozjQGHpcUMMOsaJgzCuDlfh7T7ePVV60Ps4AJtzv7bHSVGKsj1iALU1qjtesOYJayp8bA/3peo4HEnVgP86jc5NTwJxpsUhNG0Ae93xVu4lPF0gL0/yjgZUHqYZXkb+oXrcybL0BSOjRnB9fRpA1dEhcwJwoelLTvg7il354qp/Wo+S9Cz5E/K+xnlJAuSXCRXboWea/ZZ9TX88q5uUcY5jLF7Xi2HoFVZw2f5tbycxwGtT1CKXp+OAKn6mQaBAYM51zoMNDT7MvBDXD3v4Cidjgh24GZ2zndfkYT0kHCtY7OVIVSTsXTR+5/XMedojVvDlX9LBa9ST99NLCUy7Di94rJtX72ev3Ei3I1w3qPvCl3jgD2VbIwLogCzqLtY+2IkLAa8M2EpX/D+h',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 18:43:29 CET 2007',
+ accessDate: 'Mon Jan 19 16:09:30 CET 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'joe_clipperz_offline_copy_data_newVersion': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ 'f527cdd90d0d47f8524b4e165398ad1455eba515d04abd101d1e93b3c6ae0674': {
+ s: '186f0c40bf73f2af236eaa6c429df225efa933050c9aae65240e93b7b362e3ee',
+ v: 'ac61a6e325ecf329926a86084f591d8852d0ad3e4a6080f2adc901b82395ecaf',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5":"0","13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551":"1","062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80":"2","ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c":"3","507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a":"4","d5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d":"5","de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4":"6","d620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045":"7","f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732":"8","36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113":"9","fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6":"10","6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18":"11","9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291":"12","6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a":"13","6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728":"14","8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39":"15","084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d":"16","c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065":"17"},"data":"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"},"directLogins":{"index":{"61e87fdc4f1d9112e3b30c1f6812d095dcdb24f014c83319091eb6c9899ec348":"0","989593d4c48929f0c8f1581aa96969c622807e99619ed4732026e967530a68ad":"1","9f7979368fa29f66c44bd97ecaf6c545abc800b1c7bb21b7655a68e1514c3906":"2","dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496":"3","aa18149164302d5dbe7e2d3724565b9550e00887b49978559783b2e38c625584":"4","1f9bfd677b531a03168d3f8bd8afabb5357244a7bc355dff50bd6c0a072114a6":"5","a48e38845713462ecc9f827149eeaae87da882031f98ef8ebbf9ee9537b63468":"6","6f7bbc4e42ea462b5246e6f51c3f86056bec50601ce2de6067c8c1d26f21c07f":"7","2df54059e78f5771f23bd285cce19595b38331b73d67020424d9a1b2257db09c":"8","065cd0c270e5e8ce50e4ea8e3828dccdae18c01ab030813d756a87d03fe68784":"9","ddbc8d01300a4f10631cbde09e1246332eade3a877a2205209f9eb9e5bc9da0b":"10","9b7a30e667afc9f76ba77600658b2c13bff52432d444261d39bf3d069a160afe":"11","9fd2929cde3d32d9cbc5f1d787f2f64729a5e12a14410556b31c0c099762c46a":"12","f695fc36ac56bead80c0d20a88e01e382819c18dc268f1679551b7c83db7cb14":"13","f22dc41ffabef4b3bc8f7af804fec975bd50718098322a673cbe4aaff9464ae1":"14","03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c":"15","a7b32e72502804bf2946a2a8856139cbbb759c5777e6b3e673db1fdf7e3bd06e":"16","cb9ae0bba1957075ccdbfd3b3481704d62087687a2ac7c411a4f07d444bde0f7":"17","7e1d069b7fa57c03bd7bf48807520feb953157834503aaff8c9d493f37dea69d":"18","24404059cabc63b2dbff0f42ba57183108b8189ef53ab62fa25141a1caea824b":"19","6e218e5d129105c20ac499307b260eb76bb2e753f6c319e17efdb848675c5fa2":"20"},"data":"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"},"preferences":{"data":"lwtXtArw4a27+tL3R9WRPagZT7T949t3Btdf3HHQ7w5vb7rkmjipAfjbuQHuMUxy"},"oneTimePasswords":{"data":"j6xAAs7uiQRbzdHADZO4wUKkUhwvqLR1tz5kIdHpTv0KIfJuSx96FoOjuHcOeskbxvPVr2b3fYYvvdzM1d4jWu2bg13ZIL44xwakhXlCwc+2dbYpkJgN5nY7D7/BwN3q3ctWlsE9dllYZ+bC2LQfb+lgxJonhCLF28BOWh3uae14xbdAHZ314MZmmju+xRZ7iY2GEu1/Z3Cuuf0hwpbSaY233iJeN5Ooc32rF1eHo9RrlcJVTKGzN74QQ+9f90lq+XlOFx3IfWba0axFxHlQLk2gnGwu7TX++LV9zpBk9MfRUDN2b1Rb0t/GWT6kQLtO+6Y+oTTlebc3dDbqIx8u5tFhOzELoS2fYctMTvW9XKg953cyFRHfmmq9b6NnAIoespck+gF4LeH8Ips0nqVnr3t2OpGnNk3ek4BYjzpgIqpN1+VrdciXQfo5bZFvAD7RHEP6HPSziRsoSml+5qyF8bAJvQxZwpWHYuCubeowAJX5FyoETtB1VRO4I3lYA1xhZgaJYyp3dAqezaXOZhLoq7hsneKczwpJFZGlNrWTbjpWYYh3Oijv2FGKaNUXz24pAP4FbweAtzE8Hbwpq3rgxVC9k1vWlSJRhSmJEDdNO9MFtVYcgoetnkK1bsYROQLQA9DA0Hy8Ew=="},"version":"0.1"}',
+ statistics: 'QJDMnceWmEr3hl6ZcSh8YffA',
+ userDetailsVersion: '0.3',
+ records: {
+ '062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80': {
+ data: '7sgxSQlqR+wh3g06M2+sWp7raQxjjQ9jLIz2OcEB7SckuQcXNrhMlDCbL6ncSljtzgqhioWrOB409kIG8lc7h6ekghOE/Mhi7rVwAiRfNGB7r3mYxpEXRe96O2RG7E+NcSp8ezl+5gJ9D0o1abXPeFQYGcr95hUioCfyY+xrxY8TJVwdb9nHkYvBdKV7rCl1dTxgsKWK3nlo1T7e5uyiz5YUAE6BrCtTFAqtprLI/xOpRti9C+llohS7D6s8hkCBPZfp3chKFDrgpsCBFLhXN8jrBKSjHi1PJdRQzpJsgrxyeBj0dZx3gTsYOXqrYgdIzFUo7K1Tqb30yNprBiDMr7j0YYXiSvEb7OuOIP+HTXGN+yt09bk9LggyY6Fh0e+tenjQQ3soySN/XznOBpEjXbzXoz6fR1MXVnE9GgaX99LVNqwWfq2rIBdSE/FfspRiWP3BY5jIrEkNeRclS05U1zw3K3wxOL+cB9r2IynSXnK8QcrDNNRZ0W3PhsSFfByUXuviLSEOPuJa1mYP29L9Lj/WyHL1Gyl8xLbt2H41S6+wvIleKMuc7teH6wPXbnYphvbwBowoI6HZTEFkz3dQKhhY6VF/81iCXsuaz6BjyrzFX6SkQ4S3lN1tv4opQMJFvnmHb6EkXqVWfeIXzJIJO+owL4vDOf4okpAD+HPjjlVXhq6fvyM5UBIK9+tzJW78X/zifrQOfWRIhwjVsfUdZWmZ/S35vnHWNuXkM8GBYrDysqxanDtah3U8XLAiIhFtBOzpzr6qGaNDOKKgG3K8QXT4bYHOq1rQVUwzQuKhlCyStrRMQrC5Ry251xmLy6dKfppRarVeGDtzB/30BbtFNdZmzMNG2g+Jj5tFCrEtCMvMiQEWZHMU3tGMFxDef/KKdv1fFTJC16jmaUiCHUZmNjB3EO9R6xPVcMlAVKf57n3efrpRk/GTmm9JhAFkuF/wsveH4JjPpDUdkHYFu5tHbb30sbga3ufBAXbQL4ck10S24akU/cKraFGLvuKGaR2U0i6ih911TBSf3pAfZ3RFbBhVIl+6rSknC5+IXoBR7MRstBPW/xC9pQVjN5Qyn0g3aUjUSI+q4jcTuvMl32NtTJbWRMGhfkrpVzypZTyPnIh6XJkyBghlUARXw23MlbjiZxmY4ScDmcWZRZJWIknHlqjDKFDKNnwrfnEI9qWyMDno+jA/DEQz0mnpdZYEsoz1/qAmAeDt89vx',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:46:44 PDT 2007',
+ updateDate: 'Wed Mar 14 07:46:44 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:37 PDT 2009',
+ currentVersion: '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3',
+ versions: {
+ '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3': {
+ header: '####',
+ data: 'GCNNIhDQjMJQZGVSf+95fPtU6eOnFWVhuGm86r8WZGVR2Gf2EjbG1OJ0ZIGpZ/AXgirCMpo5AFxJe0Bay8IYg+xmBqMFhwFxzAgJBYCIts+raSaNRipuY8dTEqDxAqD1cChcG8EhSoiFgQ0fG0I7nNEUDJi0pIt4/ygBcwvAhuAenEp9ZW+oQA0+YysPQRqkz3IieFaOoSEbe5/SqpUilV4q1gTVyzNXvrxzxx+rlvEyGFgFN+vgtUZ1NrwlPk4gVksTpylvv6CFaMGEWKhgMG6efo0rJckKosaJTu1pldJdnmMK4EKNMLOd+jZ6pEhEhYyadrA4+zYU5TlmZA6ASzTaps8piSwZodoi9qY0ch2StK4mAbzeEGe2HdfHuAU9Tyq3Ppk3+VfNdKgpQfYrQOiSlXbKzK636tzXTN/gyrfOTHjBrRl117ywibgSX63ayAYNfcLpKotC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:46:44 PDT 2007',
+ updateDate: 'Wed Mar 14 07:46:44 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:37 PDT 2009'
+ }
+ }
+ },
+ '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d': {
+ data: 'fGzBu1On7e/6rAoSB1a4fq/CkS8Be/T8UP5cQ93asBTWndSYu2lW4DQ4SXQXSindIi3OnNx/f6SNv/extb7OrMLREF92wXI045ipPwy+DIICb+cQNMJ82Sh4cXaIcAWcyrm+MYri3qq9LBKbpwkILcebZidJ86lmKYHJozUezmfbMcwNCljHs/gYkHVzVcuw9L52Ugc6wC7sjsshh+UH6i4/2Frlrophtx+b1vervNd8eoYiKnedHVXVfW7UJcQoF27eHFgzwYnGvRW0KNXFFhqmPb61TSkIvNdCCvBKDP4SXrWvGgzU89wipvWdUPpQ+fCT6Mp3hPRrbJxwMunmjujZOzBld/HkjnXoiNfBb5akA280WvdyzWYATrjV1ZFx8yQY8G0+lRt/MxjKDc38w4y+Rf5WeRbXboJMvFatwooHUggk6qSRmZVvgOmFmNuDRnRYIFzqK3JclhJeVasnqhR6RiGSowc1Ffr1HhcZCMnXpQABGBkZcHD/zw6YjHRyh9Plw7XAm0xb16HMDtiwt7WLJpxLH/HP99j/A2hvMGWiUiFCaYv7AzyEPTmYbN32D1IsAEE/GC3FG0HypGTBolP8wpAfTRdlvWpJz8oRRdwuLV3Pgpu+kXh5sQyeZI6tnuMPQFmRDcMN1oo3E5V5V585nVMnKTFcXhBzD4UnoV+DQNkG/+iSPybQzz/EZmucEqGEYyjI3kl4MAX8UMEUxE4JO0fF8MzyBI13nxknowAceEammx1dGVaJCoIOdhadaPVPyOzXM1Vp1erVm5k4TsxSx1pll+GOm6hVoNHIuQLDueaMEpRxMhfwc8cDyXURqRGPTgTc0bint5xVjo10fnpX1gcdc/AWL6y3tXM80NW+uFJ4GI7VzyzfcMRzTiRaGi19z8MIx8PbIVGh2sw4FhgGujNsPrpuESvUVT+17M0+v8oEoABNlcizTMFs/sA1uqlPumFASltzmViAzClOsDuCh069hFLjdk/Ex5jy4vPYlwOT8Uq9DJC9ZWuZgiI1DrhWN/8QGAEGxxbvnSZPNCQ9kpD5p+iabinLLWOAirVNgKwIRJRyAu/uR9xKd7J9Wxq8q/ii+y5lGilbo2g24wbDwrkXYVhqp/4J0g+p8Wv1NBjCTSCqV39WEizUCRHo3ee9HnQnBJQDOyTBRuz2odTJtJ5tLYjWXZRdFzFSJrEq+Z1z3oq7LnhZy3YWaFXPeKmBCemMthtNt0nL',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 07:49:20 PDT 2008',
+ updateDate: 'Mon Oct 27 00:58:49 PDT 2008',
+ accessDate: 'Sat Oct 24 02:11:26 PDT 2009',
+ currentVersion: '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac',
+ versions: {
+ '0ae362285f103722abbd046eee2b7d10aeae6a1d05cbaf2081392ce9df882bcf': {
+ header: '####',
+ data: 'sG6TUmPSEPFpiJ5YdtghWHmHbvUK63tZCZ+Q5iz2ALas//jN+lZCBhZcjEwPEJskBkK2R0MyAh14wWGh2bBHMjsokgTe+L+x+0c/Zi0epE/IC9gtOBhsTe/hZ2e2xOGF/SbzET3DAAYXvxduZ36f7SvvFnrkkKvpj8wGSdTFcBmzqMb9DL2bRyRCLGLMzE3F1a0q5CufCIRz2TgHm+Uw+kfvvwC7ig/F/5iLW90Ypz3vmEtMEFYFHZ9a8Oh0rsXGfevbMhFqALoywzihQEe/NiB8dwn7GEdYKSQ35rhvZh29ULWOZinqmg0ONe0HYaxx7DbKsVoue57S0CIUlgHLajzHfLfqQg2sFI0OT8TnHsGg0YZ6mM2EdKmEjJiER0cP',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 08:00:31 PDT 2008',
+ updateDate: 'Fri Oct 17 08:00:31 PDT 2008',
+ accessDate: 'Fri Oct 17 08:00:31 PDT 2008'
+ },
+ '10f45664bbd979a92f37886f1ecc6e52e49798b16dc997aecd37259ad9b2090e': {
+ header: '####',
+ data: 'RdKVaV/WWWchrCse3KtcXd47Bfm6IAwjqVUpaxoed3HeunI42AAm7xYYSjeK8edHpbNRJbhobBAX5OZtWIp/HmgkobKM8CIiWxrWz89FqyrbnPD7+fXdtgF2yTax/0sC1l0ibncdOuJKX6U829oPlXCpXIOjlomc4wEEAD/5V6FbORvdZ9IE/ME3LsG2y02cT2tIpx6+R6wC/PKXhZA2UDsTE6R2Op2BtIzpVORZLXsdyAp/4wvWQxq90i9cEpbsVQsMB10JVyNHNsRTFhIlHi9MVCaMxQvcrwRElMj/Y9x3RbsFzSGKqFLqdg7Fn/U+KYkpYtsgHv9hraPIb9lV5FH16+iItU/HBM6FGezIj1ZkoQ+dgjPfSjTZzgzDYwyb',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 07:49:20 PDT 2008',
+ updateDate: 'Fri Oct 17 07:49:20 PDT 2008',
+ accessDate: 'Fri Oct 17 07:54:23 PDT 2008'
+ },
+ '2fa7b67e569d5e268d2b70b3d4d3a960d7e437e1937bcb324b67d0b9441db8ba': {
+ header: '####',
+ data: 'dpnI2qKjk0+bfyKktw4ZCWf+rWZ12hO5bda39CwD29JH7KtdpLCLe2LoLd+KKF2wOdpDsoI2iTiwRgFpt77e7DoWJABxq/0aaRCVN9XpqZo08iHiYhJyNlIszO8CdEhX+M3AeZqzTnd6fs91VfIEWggvku2Z+jwr0CbclY6FnOcNnS+1fj+W79Z9XC383GOm2ujjfo3SX/fyNQSw8aX+7AgJIRGR9uHK7M1cVfsNNTbmDb/HDgLlYZ1Pqm/9poHpmS7G4HUoRM2/WjI0R6F48dy5s8vZRi11SCnlnj5oRykScJj6wh2DltbCyesiaTpAjP6MQjTXsZzKpaosaQcQClZw+w6hDD2cA54IaBIv2j5KAHyhxDh2ERdwbdnCsDKPz4+zP+fmKfW295d4OY0l1NCSdcY+75HWTmBWRAooZeDTo7AE8m5sRwxewE0Y8J2MLUYsrs7Rl4kbZCiRRHU7cs+us3fq2DVn2OLGEbkRrK3kA9swT9W8ABqINoA79+DmDaIr6TGxe5AlHkCAl5sYAN4g42UX1NKhl4fWI1Scj9O1Ixds/1UUvqzavld0mE2cR9yt6LntjE5sQSAaexvymAJbU5IIM5NTk7NlY7G3PEvAPjcUsL9SGw==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 08:00:13 PDT 2008',
+ updateDate: 'Fri Oct 17 08:00:13 PDT 2008',
+ accessDate: 'Fri Oct 17 08:00:13 PDT 2008'
+ },
+ '5a17723c34226d8cd663f91b11bfa14979e694e461818113ec8abf7194b46b6b': {
+ header: '####',
+ data: 'yRTvhkoY9zDRBwFYf0G5U8zhfS1XWIUfwes6ADNnFyOrHOr7JZvZZHSgkOPnsmN/f5ngcvFaIV9X3TNTmmPLzD/ewgGVMR+ofMLyOIMGhxUDzosSd1+HKqwDZWneZ6xNsci87W8UCfJgoEGrkAtAwktqyS04pcAas74XiRGBWNcv5mHZONwGPckYUnnaVG02Zf+qif6Pp7ugdvXrgncO5oi2AMSoR8GQxMP+tX53YzLwOpabA32PDT6o+aDPwMstJNQjWCXjeYLDIlb0GjL2zgjglX5CfdGw8vNT5hwGEK2D1FkvHkw79m++9sOWd5w9WdGgtS4mrTZP3JHWC1sPqvsIpq6PsrzRrbfCFH7C4X/ya5ciOIZTCNl4dEGAif94zgN74ueY5BF31PNFtaRaQ1waKkbsrU63MrbQbBar9b0hDZoser3BdgDGb1Ecc2GbJM1HbDITttmFDrzy/Ugh2kistHx7Dci8IGgfT7K94TntRFc5R6suEqYRrmOn57YJTZYrwSgbeTqAt/KOE+gL9LawiLJ0IdSC2RQnO3yu/aOEThHxpdLIKiVJoiEQXYVnq2UpnO79GNtplNnUe1hETQ/JT0o5X1bbENyInUsFjPuitAfChXofkAysIhDOHAdifc0Y+pxOHbQLkL65ZOsEDXWSlwMcduMNdQm4LVx26GLIV6yVsaDN+hGta2CxUuSvEIMM6T5xhaPfJ4K57LVw9MbOjRXpmFQz3QgEr8ZZdUxgE+Kj6CtmsjvzXtCQ3Bv/SccTLJSR/LQ8XRdIcPoOlDDy5jSQDF/8lxkgV1V7M3+SI1iWESPT8My5C+RH32F2MNZzthYq5hIFUB3wsM/AaQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 07:59:31 PDT 2008',
+ updateDate: 'Fri Oct 17 07:59:31 PDT 2008',
+ accessDate: 'Fri Oct 17 07:59:31 PDT 2008'
+ },
+ '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac': {
+ header: '####',
+ data: 'RgIWPbNN3sPkIPBE6lfvf9/EoDFLemTZe0Qh/1wZLrKxLRNzFpUk9+NmeGUp5f1hM3XjXw4cXRvP6GrWq69mz9zGja+1TA6RoW3dFMpSQkbONcrSD1mIjxV2zIvzA/Pangz0ZixbEeHCfwXLvgnevbTXXFjkti3kLHQlk2pJpM3zMl+rMJtcsefszuJ/0tE/bO7sBcFqcYgKAht2OyDQORBAGiW1kI9USKM5OOfJJIZDQ0gDhRgl2U92l3kIOO8hdnj32oRedwfKFmdSRkuMY7ykU0bMuVEVkLi/FWmhHxi66C2ovAztVtMd1IiyoNcHc4UH942GC4pT1A8YQpIHxBAJbrQVhpl9LfFkmJ7xUc6Xs5j0Nv8+z2JGCnJI/D4nDJqYW+iCYtRWu6vUmbg0vGfaYWQFGRZRk8zWfHzHXBvHU8p0QsIjYgCLKiUaU2SRRD2P7JCjeTUrm3I1OI593iPsEH9J2PHCM9OMQ8/Fsdgd7lWgH6P9jLdGUwtb1hGaq8mg3JGrHFXcrVkUEBfeR7xljeSHD7j4YahYrua9EeR8nvq6CNaOr406AWyHse9SXhaOxt8qXRLoELpyQPsaLgafUpsdLjJqHz7J76Rp77NSOtXGplKjAtU1xj+d/agaAKYCjvUJC8/APJI2890Pn7VSXr/TPc5biPEIopyVYEHFqaT4e5nZW1Ku1HXC9gwUwUI9rITG4GzIH1WMEm7oFLNUaSMrdK/UTdTJZ66ENE3B9v9cTUpR0NTkbI+iGKDnc8GHPRlr2ZJwN4KFTxi+o/kkEOBjvRHR55nRh2+dke75LS/fzHQZw5wlyqBv5ZeUZfRA7QHfkj9acR0fJSqqNX25AUzZQnRL3oVpOxFWCMU7QVf5VpnRm9OIOd/5F5EoY7Be4doM/UV9U40F3E6XPZQ8S0GKQzrDjc7jKyGPLNPLUWTmGB39mTNDHZQHh5Xv5Q==',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 00:58:49 PDT 2008',
+ updateDate: 'Mon Oct 27 00:58:49 PDT 2008',
+ accessDate: 'Sat Oct 24 02:11:26 PDT 2009'
+ },
+ 'b57a2d2ffafa8029123362071c09709bb9192f06a17140440f0e41d22143148f': {
+ header: '####',
+ data: 'PQ53T2Vo2D8PoLI1qNX//jLaVZFTDTYk6geT9+4RoThTxvlJ+beDPnQzgYhd9iASaF9GQEEL8JxsBnNpEPa6JPOY4ndFLmDLyFDKXMprxq1UIbzFV6kFoYAk3uCCCa3UCDzdr1KXB2CiiF9HrilaA+xkm8krAvH8I5kZD+j23gByz5cAFvXg7A77KEURpjujURL65DW5M+ceIjo6OXaPW9VO03xhqGt/M47ayObpoEGJZn+X9C8s0SE5wOXHbn38YZlRI480OMvtDAxbEYUeQKMmzu6lO4Nw5hhOUjoPSLr/i3tmDx3nPcDwnSafx6jyA4y31eW6yazqTEOP5I5ArC5mUrF7mAAiFvbHIsMoF8PLj6MONlRIOZgbf9HzCpFdt8xBrX/TXp3LaSAj2XTWgSTFI2cgmU3qqPyibvIfUsB5cVHQCXi692JpC+B85axJ0FLyMl5w3vq0txlPkf6q+dadPYDaLHGZEmDjkWScA1GM5xPJHWFwqGE7ejgXKG0sMYsMKWYk+F2LEUmMHtEvSlpgJBntvcQ1ZjYQxeu4hg5txu1ykkif6fXgkXF6wn6qu+5caeJeNhWtAB4q7WVD47111woYMdkmX7AnDTXSAQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 07:57:17 PDT 2008',
+ updateDate: 'Fri Oct 17 07:57:17 PDT 2008',
+ accessDate: 'Fri Oct 17 07:57:17 PDT 2008'
+ },
+ 'b713e0a1e2664ac7bfa7ba887329ea023204d10298973e322983b82b222debf6': {
+ header: '####',
+ data: 'H3gIieYrH7Oy8LEWCZpl9vGp9qYdHNCoBNGijYqlcfXt+1JYvPj1abPp12xLNrDUHfaOZklU2Ip4tOf0CDNhgAan7LYyPqFoy9ss2f9/5RLcbjwiIwSduySIL322HTAwqlzlBt/qaJdHHPUrczmu0fb7fT+0dO4gCL/e/IjcHLefUUgNPAbpHG0Nv0+4lNwKZkIQM3tLRtfJyFBIgWKcMcP1XMic33kr24rwybR8Pb0CHZrOOvvUiGqyoED3ZTZf1twUDVNXO7MWCAC5dBc6/Mk/vSmbbGhppXAH02N0g8G5qzZfp3UVikls55VNhRYLHByVsgpkbIrKXyZnBPTwzm7qefpYAXDOgO+164L66/Art2FYGqZQRZLuh5r8oF38',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 07:58:00 PDT 2008',
+ updateDate: 'Fri Oct 17 07:58:00 PDT 2008',
+ accessDate: 'Fri Oct 17 07:58:00 PDT 2008'
+ },
+ 'c4cea1cd88a86b05f48a99896a37967c3456228283a0406331ca9f67c6f29f97': {
+ header: '####',
+ data: '1znWPwc9JwCe7iOFiUd2iGm4xJd+824B4VRqEtzCQkW46tg25RWfo7XagvK46USB7t6pC8WMLU0M/EC47KucsfpWUqHGbseoXT/8g8E8GoLnIsk9qFyJG7LGd1sUvqBgszLZwjWWG3t9zifmpW5nY9GialBYNmeSLS3bg5xDH+eCEilUUfDe7zGuVSuu/XkHacv/DYUst97e+6u44F7H8Kv8dTywJZpqbmveNPeWfCej2aBXdVV616J5lIRaj2uIYuQYG7blYJh9KZ7yLStdPndl6h65hIJpfWo0PM8nLJuo0lWNHz7misrutnmxJEjkwVIZ5YAmqp1Zz3VC8zw4IxkXrC/sPmp4PaNXgKz9ZJRaY2KV69WmHf7BUQ3QneGngbT0tN526SS5qDFwTGiuIlnYGWvTB2jVrbns68n/d8Fps8sSWfJBvvXJUEkaZB+1WqNilOPGXvyJ5k2O/iucFbRlxwlEHDny+AgsbtXZdp8cHQ4C/O4G0mnUMZuS38gn6e2kQ55mUhxKeORM+J6Rx1y4Iiu9KKNbxyS5eBpAlFB4xS/o35CS4g309vyOEhi37F24bpp4pM0xEPG4mcc/IyChHzaHUGEp1IX1ZO/r3ut9RIN2QWrGLUlZV/9rFKpLLAy6BkY/g8VYNrV8PztOL3rqy/qwqNZouONwPw8w8SA=',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 08:01:59 PDT 2008',
+ updateDate: 'Fri Oct 17 08:01:59 PDT 2008',
+ accessDate: 'Mon Oct 27 00:57:58 PDT 2008'
+ }
+ }
+ },
+ '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551': {
+ data: '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',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 06:53:11 PDT 2007',
+ updateDate: 'Fri Oct 30 10:52:54 PDT 2009',
+ accessDate: 'Fri Oct 30 10:54:46 PDT 2009',
+ currentVersion: '933abcdd036332b566a70beba4ae486123475dad2903b00a939c067c34a074f5',
+ versions: {
+ '106a1116d22c2395906a346da4d830c7afbd2da9a46210d0b7a11de238016783': {
+ header: '####',
+ data: 'jgDUvByveAFnchBQKhiHGYDNDtj/7Aja2RePMer0FCOkkEu5GRAiLkxA3/DD3eiU+g+mCxnjnOaEIYL1O5o0+JP08XapsblZHTRKfveeFfs6sWwuqEHGYULBaXx4XSfK2B12HgpBwa5aD49489AkuyXi7t/aAXcKKJcLB1sC61DI3NsmajUaXHBi31Sp7nKAUpMuiWyguW0JVfH6KUPqyldVDBTBqHAis37c1qoR6aFHFfGgAfb35+syfmPRgemujMRkj2XO6dbt9zAYlHVSYFp9393rwPZoyBfXMMdDtSTmq7H9qbmx31GecHZlFN3NymtPPDYUbQ9mpPVRbxE9NjtiPrI5eGFvb++OdOx75PKjYjCAPWWFZ+4aryNn+h+yqab7pAuoG03ACVVrAFIOn09g1ssol/vqvalulEf3hAIviedyiNAC9D0UDHtzUwyIiELvR9qouXLZ',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 10:13:41 PDT 2007',
+ updateDate: 'Tue Apr 17 10:13:41 PDT 2007',
+ accessDate: 'Tue Apr 17 10:13:41 PDT 2007'
+ },
+ '111a8a4b6b912b808a93cf5e8785ca223112628d05f0bfc5dfe1eb40cb72ed8a': {
+ header: '####',
+ data: 't524etHmXljCnLC+IM+WPD8Q5VE7wDsSHVNZzFU4hQzk119t/N/vhtfHYz5HgNstU5T8c7h7RHKvFk5f+4ZwgNgDqSH7H2PrH+7/bV8+uuqbe+/3GYOvELjTF7v3xMyYs1B7ruHpT+291HVNZqxajqCl/+9nbG0e5feqNsTXWUTdLzF0szJuCTNr2I+fhxAO0LRVaf8h+MBPYyuBDnfFDuKm899IsgF9YoYRvjaYO69DkElvf4VP2jrXIJsRnGIUfUaIS/wQ54+X4JBZM/9M09MVOw1SVe+cwG+P3xyPUkqnSb77ECo86C0MktzeYFmPnPv2SM2KFA6slctXsyudoaNlReh1k+6no5J5BjaawTfqYjYrAtWSPsuhxYVsZym/X2CVbkz4rMSn+J5Uio9N5uZ6AqgCKdhAJlwzVb3fIIJwvFpVpy/0LMskb7aG2i4eAxwzx1H6rD3Y',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 06:53:11 PDT 2007',
+ updateDate: 'Wed Mar 14 06:53:11 PDT 2007',
+ accessDate: 'Wed Mar 14 07:24:35 PDT 2007'
+ },
+ '144d6eff3eb5f1cb70c8906741d88018cdeeae3a618ac4066598ad6b04242364': {
+ header: '####',
+ data: 'NPgSZF0eSOzy0/Ns+15Nz4bjSwh4o7fWYgKgwXLRFrF8y3EdbiOH7AiEmmPrCpT1raeYLWCcDIrRTz+/9uvIrz6kK6BjU2emr8YdyLai+PTCRY0SafWS3QiYixX6DJiKIt0SC2F6dfmSHwNsbfTHilFhVXn6wXTJpWvC+sRzw+h42cYpQp0BoLSuFV7vPz/+wtuQdl28BiBgLzGsrtPud0tPcfldGox6Ia/1SrOPcqUr0tnFlNQiUvPU7N0JZgRNyr1PfpAEhmYRI7aEJidsZ36vGQpE0ZQMmQE/9tLS/InALRZT1YXfMsytf0o3y4QlgJrvRgBL7fGiQOZJpU7igLk15xAwU+OLIaYIbr2xlKDJvndHOcrFoYKry9/A/aZSnEYv79wsaf64bBgIVD2WJGLuSFFmzlFnbg/O4kGTin3A8XBpvFA9V6iCMvnEMkrqxD3Qgf7WhxFE1A==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:33:00 PDT 2007',
+ updateDate: 'Wed Mar 14 07:33:00 PDT 2007',
+ accessDate: 'Tue Apr 17 10:12:56 PDT 2007'
+ },
+ '191d456526b14fc5b4ff11b3f856c9568562bbc68435700a2fef0d176482edda': {
+ header: '####',
+ data: '9rcbGeLFjW1cwULSScOa5zfb9BZqoSi8IvarxwjLVz+4VqApsBZnwJsxJHq/L9zV3SRYlAQRRLNy3lhpO/fJAOg4RNp68KdtA+IZfCsn1MzwfOoBrnTTELPKxDim4US9xQNdJp5ffWoLB8demEL2YkSNTrPVr5crvVPyepuRCzdqUoe6Dba05tR6Ju7/+d9K/cfJg+KI/ziSUSVlOTsIahGkipvMwYzhCOqjljJvdeF6XLLCh7F70lFvpW5vtv5jNmpkgvAhfxgovIZ3tav0WDc+DEdFNHNsCtFhwRYsb1dH5Ry01M8g4vS7PDkuCNYOvjL9bS2Wmy/lVulM9dYdB/d/gKWTjbqgre/IR1TPPdtfiVBo2J9PUvM8P/c2LmQrf63OwjWT74N0D7q/NuVn1KXzREQiyMi6ezzujzJolpNVUNkJFlnSHl+EqnfFiiR5ALZ7Nts4uWLe4Vpn0XmyvHoAVDBK3fw7e3n0tIG4x6k95guIWRKdDpYLOTHOe9jKJbc6KxdGmt21/5pX4KdeWavwirKRcXW6ReJIOVF+KREEZZOGWu7UKWgqgdaMuvxO472zzXzxTBvnpOmnxl/oIkhs23OPxHEwHXX8gXnyA60hd2tthCfmzfI48wWkO40cUTFnqO8htWRXwbUa9gYTjYWDTmoIyK9AgO+PfBLNqx3JzJYAymDcw39ItO2lIcEBkZ4=',
+ version: '0.3',
+ previousVersion: '6ca08e08104f73943447eba327c8d0bdab3ab9a01fabec1bd4734b52034a9544',
+ previousVersionKey: 'RDzOj7LWZcdVg5KmmIT5VXM0cUFeC9tC3n0IXDfNpj12cq0w3k1rpBYbt4eSEkOcdM7Va07FPNdZY4Pd65xBo2MGc56Ka1pX3wW4jTxz350qtw==',
+ creationDate: 'Fri Sep 11 05:54:50 PDT 2009',
+ updateDate: 'Fri Sep 11 05:54:50 PDT 2009',
+ accessDate: 'Fri Sep 11 05:54:50 PDT 2009'
+ },
+ '1ae171ac58981896484c222ab42373b0b6bc3d054dd56faebdc9018f3abbf549': {
+ header: '####',
+ data: '0ck0NbHAOYieUs5c1U6xSMf3pj743aIv1nnBnB7f4vsvKpMiYleQwr4SwY1W6vhg+3sLnO9C0CCD8Brt4V1wScz/STp4oB3hoy31W4dsAFsUyAWFJ8MrYDsZW3jotIPVbMKxu+4Yp051iDPcFKimDhfAu1zVyiVE9llNj3tP6d9gukUNfGZ5CvFmEXcheHB8t81Z2tgeO70EELFUn7uqKJwh5xCqTeogPtsifmCjgx8Yo6hi19vl2TDAaX0HquFO3WcIAL185tzYZ5rU23BYwxD7hVfan7lngSVq614MsEB3EX9WiHRoissSSajNkKTlTW8zsNj3VlUXKMQiJ2aA9Pi+/Yt9sNAbmyTl6T5TNN4QSquLPLyxO4p+OIjra1WPdmVsCti7fOyGirogfJF0XhZg4imvGXK0c6lPZIlg/OEnoDSTiHXlOYpSgaEw1Js5HZ+390XY0KYPtpsZlY+oeVS4p29HN7x3CEairuIldEsZrk4whiVcwzlnmw3n8wiewumus4eRh9w0CIwJELKeMiz5cX4bX8+AKS+u8O1W0GwKlEGTj/joA/M=',
+ version: '0.3',
+ previousVersion: 'dac2ca240227fdf7a08fedbc998c49ee7b6fd622bb8404e804c5dc7f439bf8fd',
+ previousVersionKey: 'moIwxP20kmN6f/+pgb8pJNqsLUz8Qo2BvcAFnXBmiX2E4oL1pakM9iq0e3IAiNLApmID2TwyAxhsmKj422R9uWXsUFd84LRRt6lMKa3/u1dC1w==',
+ creationDate: 'Sun Oct 04 14:05:10 PDT 2009',
+ updateDate: 'Sun Oct 04 14:05:10 PDT 2009',
+ accessDate: 'Fri Oct 30 10:52:36 PDT 2009'
+ },
+ '1f1bdb7a21440ac20c6d913d676aa30dc360252d27059e77df51a1be36b2e263': {
+ header: '####',
+ data: 'TaOHH6IoHPKLLoyLyvsBszgsPPcDs6CiLVXzXuXjFSTrhPxzUw9suSsisgDRRs0ncjZ6BCyqoCxMnw6QVvGN4viUwYVR8AWdCg0NMQZ+LkNfq/2WN0M3KyASI8sIdMCwTb57NzOn9soB1HmmmETZfjr7HpY2cc+lS5/4f5rxI8XTEK60lLed+aEuJamAjeZUdgIyu30mMKKjxPfY3Y9iWMwn1OD0zF0mAW+hyEoMhhK7EYlWKCy+4qN0QM+yNFXQyERb04o2n4XrM+qr9df1GtbQMH8igK5VzXIrKjdHjKoLo9G7D7mfx6mRLsmoAJuE0R8gyzotgdBpOgWasHJ82iWEa1dLRKBHJ1d0Lnumv22tvYfasx2DIR5Tmx3kIQ3hFieLSXq48cYMiaZH/IbLiapIOlMgtWDow8JuySBLei/8FAV8jCxSc1Ui/SjbuK/kCvywaSOhDVIxGw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:26:35 PDT 2007',
+ updateDate: 'Wed Mar 14 07:26:35 PDT 2007',
+ accessDate: 'Wed Mar 14 07:26:35 PDT 2007'
+ },
+ '30cd48ae2101c0005fdbb57917031ef36c2e5681890f212a95a2863463369043': {
+ header: '####',
+ data: 'jt/CbXS+TEjH/jPrstH7cQZGK3yse470grrhdAOdWoGVtFMmL7fMJZQOKm5IQSrMHFEsH3PoSs99Rr4ui/u71vUb6s/TIsjyv7yihnCYVsOEJOPcnL2wynciILV8p48Lky1wGztW+oSynYOG0CGYDofFhF/MNCBsG1EcTqW7Cf+8rUiS4nA4ZRZVv3HsZp6rCabJsAoK1pmf5tXGJHPjS6xdy1A9ea4bV5Gad0pu8IXvjbZTrDymHem0t8C+oZ7uJ/mG9cFVcNykXoO/TDP0goD6KvTqtdY3VWNNTAERycAW6jFtdMv2W/AFNmnYatZ+EbSbj6/RyGaNnRv/ceBitMh73HRr1EVtZw0wPthMBXwnlPbpkfUwWPBHYpwImligm62/6YBhxDgnMZta7TSi8apT',
+ version: '0.3',
+ previousVersion: 'cd3479e91eedabe34a1b76f0f26c69d7612672281bcf5d682a787a48caa66521',
+ previousVersionKey: '8BbhE8C41VX8B8m3TbfLz4bgSfE01IAUl8Zlu2YFdEhpw1erqInN1eRE6WLyBB5MxckmJpbn6VSizqbFbi/3Id5p/fibHKmbmNp6xu7iIo5zzA==',
+ creationDate: 'Fri May 22 03:30:43 PDT 2009',
+ updateDate: 'Fri May 22 03:30:43 PDT 2009',
+ accessDate: 'Fri May 22 03:31:39 PDT 2009'
+ },
+ '6ca08e08104f73943447eba327c8d0bdab3ab9a01fabec1bd4734b52034a9544': {
+ header: '####',
+ data: 'XKsPGp4MeuvDrgikcjbMnmw/Gz74sTfyP3lLylbrtEZJ3aGSjRvE7s9o3Ya9GKRhYxNQ0dXT0vM6xIE6r/dMt8PwU+/5dNtRhCGPAHvKmEEGb6EBwR7gUDxQLyFTAYX8ut+CpyNJLQa2pHoEl5aNUTjk6blYrKp0GHKt2Q3PZrjIn78rcOLcKY5bx4OK0h9rN0G8mOFQ0g29knKyaykv8dja/Uy5XBeshKnVT7YRHk1nRuwz69ZcX+1Z2qzfw5sxJx+fDK+otWVpjzDP02qqn7ju/r3GgSnW8p/ghBeurUCLdQiS+fFAevhOwCkZGjPMntG3Q4qVt42VxIiiuvfShdaSsNMOW9Uziew3XwOYL9mNIOSdPSjtry4sKrAh3XNmfuJjWTy+69Iyi85CtQ6xMFilANgSBfTqThUePCrEkv9ZBbvpRovuuljlxqZ3gUmtvwy9a3ACAr8SMGWX0ydQjKyvZhoGRCBM+ZC7zCe/JmIpdklvNd/+HqUgS2iAnf3CeH4gUPQVizFR04Ysgj00xO6v4bdY2bYVKIxunygBGNzySi8DeSREu/rUKWgx0KY7S+Gg/jqFMYpE9oy8CxUCmSLeNrnxUgprPqKrr72yue0kBGVoYyJwhXo4MG+LPV0rtVp8b2GeHE9fYmyEZO2Ke93SrHjezS6CnWQsvjYsFYCLdLtEGwo3mpS46DF69LlO53k=',
+ version: '0.3',
+ previousVersion: '7c80cac9c8b9b5f0f533dd3852d89d6be07963eebfbd2081f2ad6d2f2a06b447',
+ previousVersionKey: 'eEvij0YZ1r+5cNNpleVHE+kjCZlSggZuE+3Kum9b/11JGHTgQ3bY/o5amM+4+FPaiCU0Zd6MWFAI4dPscyvAS9in6WdTOm7z3fQ3uqYAtHghPw==',
+ creationDate: 'Fri Sep 11 05:54:01 PDT 2009',
+ updateDate: 'Fri Sep 11 05:54:01 PDT 2009',
+ accessDate: 'Fri Sep 11 05:54:01 PDT 2009'
+ },
+ '70720f026f37b571e9765d27c51d3d60c7be0293c3266f1f987c8de9c6b5c416': {
+ header: '####',
+ data: 'NYaYljcgfzrlN1DVgrbyj4AeVhXGjXPho3IQwEKD3ZOx/yEZxldCNSyFsrk7PoRB8Q1T/6VV4CGa4HLRSB7QVCrtVqWyu4KbbmFoX8NIQ0H3xv+TSo3S/b3dldUeyW32ScaGbspaf8nFf0CffsgpGusd+kHdiE3gSLJvH9y5j47KgpyyX4TteVzqgez4dcXIs5tdzJq2eUlknwU4651QeKIuRSmRaDRhhOP4yRgUo/qXMlTJFmHviCh+IumvBdmDoPe3Vc1vZ1r8PxpDJLvDoB8GTDE42NhqHfVrew9ym1xlTD9wswwIEikfOyTq3JM857qPOHRqSqthEvr4WHbm1VW5PReIyse0lugGyOzqtCnADp9NvNI440VjaTd4NBQqF7XrRm56+1u1uTdfYGFV5BRiH1KmrM1sxXQ6PlOF9Lou45ALo20xxvJOLKG0RKLMr8gmVT2bNtOSJw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:30:09 PDT 2007',
+ updateDate: 'Wed Mar 14 07:30:09 PDT 2007',
+ accessDate: 'Wed Mar 14 07:30:09 PDT 2007'
+ },
+ '739b67f6c1d52093f5c2153b406df90cd8ebf303ddd0d13d825fc946306114d7': {
+ header: '####',
+ data: 't4ohy1/z6oUzyQLtqQoumRzcLCnaYjL/+WQGwE6yIXaGEhCWywe0aIVusPKLcsfYTCXVU1/dXtuucaZoMw7PMSOUx9awTp14NmShaT/9VKChZf1TLi0CO2jOUGsvO4DHlNAQhJhas431l83F+h5+hrkqX8j5kIhzpwlroGEjkml0fswmmwDyHbSTgVEyErZc+b3V+9oUCwzYvd9ITHh8uWLa6j+GuwZTZAk2FY7Vzoh9K46WO3/qCz1pJ8JVkcffun9alK8qzK0Wp05mMLIrt+WHFFTKrG9zpBkcswkbwhJ5ZnakfYLJ8GPH7fKnAid1FGW0Owms058smDBmFO20HyH+ho7SL80Q689W+Jx0+nkUKvxWtq9BWLW6Z3ClDZOVITeg35gQVr6aRzZ+VZwbAy++',
+ version: '0.3',
+ previousVersion: '30cd48ae2101c0005fdbb57917031ef36c2e5681890f212a95a2863463369043',
+ previousVersionKey: 'i4e0h4QhuN0B39drNLsOWruy+R64siKHWxc9YXgpoCPitWL/ika1MVCRX7CJC7lH5WD9yzx6l9isAy/Hb3nUIEp97VcFKG4S0gOaZkdWNZ/U5Q==',
+ creationDate: 'Fri May 22 03:31:46 PDT 2009',
+ updateDate: 'Fri May 22 03:31:46 PDT 2009',
+ accessDate: 'Mon Jun 15 15:20:17 PDT 2009'
+ },
+ '7c80cac9c8b9b5f0f533dd3852d89d6be07963eebfbd2081f2ad6d2f2a06b447': {
+ header: '####',
+ data: 'LDAixBQ/CEqQX35jio3aAXG+Py4wNylXI1mQJ5IDxnpqmkFZfOXCaScpwIkQwQzEOjh9p3cOShzrBm6r234HKxgg0ufFnkTWbQSjCgekfVEqiBFi2rWSj5v6a5LMANLwtCz0b2IPr6Z8LSPddgao7P0nwBdCiKJAnY/uGdvSn67WSFhAUGAIs5ZKIZQf8Zi+cA3hd+Xlv1W/2+OXLaIPTkD1bCuQo5qEiAoOl5mXngWOmQ2kTGpC7Hfkknm/uzDeiZTe8VpGjqKTwB/tl64LU5OD26DMpihnVeQNqMpYndEJO7Yu9Zodv8WMyYmVlrw1UzTB4BLTL337vVm5uBiUjAfJIwJx3b3fXxdEiWFuK8uwOXAO2X9OOKfLPuowOj21B/+zRLum3Dti23IfHab5KwSq72sB/vjpl/KVbcGsWZET4VTCZvO04T6Emjb2UBLFLIgInZ9tqN4RXSKz0Uj4n+pitmFSDleuPtL8EzEESX6FtmT/IVdr5AGNjv93wIk5CgeoK2YiNlpTb+CHbcA5HPn+TH9T4999mWrJh5hxZ1vGYxlAd1AveMCgA3y/Wl+kZKMnUatXPM0deUS1GnzpoRXtI0dUi6J5sOHxeahZL0TQbCbHcKkoaSJklMl5YEVaLXyakO4ATKyNcsPfDQrPvWfra1I59RI3seStv2Q0bs14Zco+0opvKN71R/HxjF/etUU=',
+ version: '0.3',
+ previousVersion: 'f8ffcda2eddd2f6d19c4be17f6f509f1f66fc5d4bff362f402c6addaeb9cf32b',
+ previousVersionKey: '3JAEXzigeX/PwpA42+K/CPSpP40EO/j++M6pB0NF71EfKCApWSWy89flo0KbrckF+mUAjyY2hLYBc/F+Q2vgGNhAZqq0vo3wcUpFjFktqgRZ4A==',
+ creationDate: 'Mon Jun 15 15:21:15 PDT 2009',
+ updateDate: 'Mon Jun 15 15:21:15 PDT 2009',
+ accessDate: 'Fri Sep 11 05:53:23 PDT 2009'
+ },
+ '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854': {
+ header: '####',
+ data: 'xI3WXddQLFtLVzxJaZWQaw8wAgSuXLjLnyoNXnFuLecTH0BzU36PatglVh2HK3LM8aDLzzbHILdlLNnJ9CY+YnhmGh8hswF9oKTgq0Wsesgdc20QhSMNFFjmMljY1LSXmcAYK04Q5mIzi6Pe/04DRdj+e4zbe5QI4vEBhp/ohEpxZnNqc4BoX6J0eVf6LA1pwrKWvxzMxorWsJrrr+mn3svdlF437n+MMr89k5sQJogufes2GZ9tTvVZ4247ITxXqxgAhwXtbuIs/A5UqqnNdsxlHfpLKG5KjxB6F0h7TtFA3gkZCve5UmAibBnoBCFaIVWQyVq+VO9iqDm3DeXsK2pepvgIvpSID8Poy+uwN7T95mivAsHG5p7MtgN9KwQzNW3Iu+BfO9FlPBMngSk8L29So2CIXe6lEsXSGEi5Yrgyo6hZi6IkGCXwIQ7TCEMnlQEGyKnnAVik',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 10:17:52 PDT 2007',
+ updateDate: 'Tue Apr 17 10:17:52 PDT 2007',
+ accessDate: 'Fri May 22 03:27:59 PDT 2009'
+ },
+ '9588b523f39cdfc14efa1e15ea7716c2d8eac45d8efd7bfeb19d716f9df72d66': {
+ header: '####',
+ data: 'q6DKkxhgDFs1XkqOYf6dvojPF+yhJbniTLFpSOS+I1sum3EZIJfYxJXyi2Jx3KOVNBMILw1+vrSLe/fh5SSWj8ZBoeppkPPLjyRNdiUyd4IfcRM5OSv2YcTxCubKCH2kIMFAzY/29A6ZGPG+AN8/kxkEHc1fxKaNcj2Cs8qejNR8yK1iKT1Ut9VfEee+Eqy2Ohgdq8wL/xAD5mUzdqHeQl8BY16pXGIYncLxMzR+EJ8E5jJTuGv3O41UbO31lvBSfCt2pfz2MrtsuqNoI8LBHJkcR6t17Bj+rHZUniHlyxSW/1rQJ1NnwpPgUJ1fhfQJZM8Faoif+0bvWFY4xWs/tCCD7oEvf0xM0I3FfcJLbYX8M+wyO08t9BmGdEjnr3VUcuS9qKaJRpdpMP7aQf+vJvioeQDXdOJ6Ceo3BDFc6JdNta1Qc+agGzN2KPbIPrLDL+08hWl61yu3GQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:27:35 PDT 2007',
+ updateDate: 'Wed Mar 14 07:27:35 PDT 2007',
+ accessDate: 'Wed Mar 14 07:27:35 PDT 2007'
+ },
+ 'c7add675f676c4615a2849d5017ac8db9066265253ffe7e03b34ab8260b10888': {
+ header: '####',
+ data: 'ZRJXJ72ZBH01gAML0R7n42fI0WjdbVXzyZH7H5MP2RgtGuVvfdadVK9+U8mzdf1Et9DoKrHhZUp9baeREPO/Fk0r2IO8NmKv/8+rMkK6x4qeWnI8ZAJfQemGtqke/VcTn4KGAyTeV8arzXn/whsLpp/xN087NdDw9dP8PLb43Yk8TNC1m2d85FUagSh4NOI3rmcbHAiCOQpqHBPBoJY1Vf4Pxu949TEUm6kT6Rl0n/sb3PSLu4LSa6+WiGZJ4mgE+3XZyfozrJsvGoTYSkim3MTwhrCLEVaDMTq4Ei6FyG+TeV95Q9Ei8HHwBqdp0fxUxavNe67Oo4m+ECiRvZ24b5+Nz6POBjXfn+61yCyIhz3SV3IaYIF3rgXRZA1q2sax8kRGtoG7ONxczUqGyQ5S6Lht',
+ version: '0.3',
+ previousVersion: '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854',
+ previousVersionKey: 'ZbGA3id5JTGeRjVUR/LkntSGjPDEbZbNrQxc4SiQDdlDO3dJNVpfRp69PSk6vqEiZ4r/6OKvE+fl2TtPadJQ82fP7WsULtrSkYryQL+CQvz0VA==',
+ creationDate: 'Fri May 22 03:28:11 PDT 2009',
+ updateDate: 'Fri May 22 03:28:11 PDT 2009',
+ accessDate: 'Fri May 22 03:29:03 PDT 2009'
+ },
+ 'cd3479e91eedabe34a1b76f0f26c69d7612672281bcf5d682a787a48caa66521': {
+ header: '####',
+ data: '6TAJAQ4qE5l2SybVzeEqQxYZgVow0MKzl8xwfoE0HeuSr8uJlszGas5NaJL1SFI5sDDwIJzbtIBE/yjaNwWw18+JzswIWmkLW+kTIAtJKjNtWnaGlDJMTA4OIo5gj2Vqq4o1VngzMTk/DV6f5ob3/HxN+YpE4r1u2SUVeADbjcyjRmYE9ygvuvQ5AuU3u2hzmstI582kBlksLPGhX6nJfAPCrSkdphNj28T393p5w82/FFCFNHKjgKN/xI3Rotq7rObFaNid1tmHvozKLYeLQQfjglJ2rRDQDTOJONRVJEObDFV5bmaY4z3XljO2nbQ4iMK5CrTFAYTYNph3/WOQWjZHWmAXaHMYvBSlICvF99C530sOGQYIaBWKFuOv/pNuCZh/tBNVcI4pU1dz438/7LQf',
+ version: '0.3',
+ previousVersion: 'ffb687c41ee598b30cf28525024fc18ba96b3d7998fbb298d702311f76ca2127',
+ previousVersionKey: 'U2Z+xaFl6o4XH/8DktJimjP3+1PaYRf1mZPW0sulAOykDH0LY2U+kbBj+mfNV8rVAJlA7O8LYl8AlUNZUTS+036MiIinpD0Tmhkc91rFkMYgbw==',
+ creationDate: 'Fri May 22 03:30:03 PDT 2009',
+ updateDate: 'Fri May 22 03:30:03 PDT 2009',
+ accessDate: 'Fri May 22 03:30:36 PDT 2009'
+ },
+ 'dac2ca240227fdf7a08fedbc998c49ee7b6fd622bb8404e804c5dc7f439bf8fd': {
+ header: '####',
+ data: 'zqOJI8Qken5hwXQ4MFRzfnB5tnROjMhg9mw+aYwwvI8VV8aADoyPuaRi6bdxy4LP45PqVR9G2iXFT+h/WaBql+rz1AA5AVz54cpd2gdDh8Eec/PJXyL3SfXW1PQoO3bwhW6rkR5cNQf8xKxlmGWLvE88AXT65tV/RdYJE574aVEZexzo/40X60weCl1ZITl8IH97eug5URe1lSBFsy5sjo+SE09FqtnmnGy4O2LL+0XSR7xJqiJihv80msEgk3lTbwUEiGWm3OiDnvLk0GjaMy3+EGV2/rHZuICMJkD4ge6cIBc/h00ZCFnXN4bX+OC/KpEFgtnPgQ+duVpsVNdYmNwxSavyFs/UnFFDTDIPZxEKhRHFTW9zaqu2jVTZd4+/ro6TSYSlEN6F/jtiL06nM/F14Bp/dYuqBZfc+N3vx+72jj6IOKTHtqvlj6jdSZseN8olODT2IGI/fsjR79biVCIOODAaF6DCd32ClvoenCVPTIhMc2AfuKTbleiquk95nN4lgpZbMzrrvWHPJD0oKXHo8X1GJd19QCj+IhzCTx1Ap1JPOTMIG+reaxxwicGjH5Iios5DmA4gjsRWj9BVr+QmMJmY4KTpyRG1lVYovm78VWf0nzyGLNx5sgWrRyYLOI75m0zUdNGDUpKGSyqrIuEwOrI36uRr71MvJ0ui1HXBkDbPIvrQ01UyocO1paeHyTk=',
+ version: '0.3',
+ previousVersion: '191d456526b14fc5b4ff11b3f856c9568562bbc68435700a2fef0d176482edda',
+ previousVersionKey: 'zOAbF4q8A+LjWfMMXHRHH2DmzdToA6a2U12y0G6cyAm5tvz1BrrAcgk/5dx0yvFF+ZSxuOOfnvCPVBN2kT75otq44tVEg+FSJ4khcC6HThCluA==',
+ creationDate: 'Fri Sep 11 05:56:02 PDT 2009',
+ updateDate: 'Fri Sep 11 05:56:02 PDT 2009',
+ accessDate: 'Sun Oct 04 14:04:58 PDT 2009'
+ },
+ 'e5b71df0d4d79a195c7ec3288dd7738069837a7c4da3bccc1ebc05d8e4f19d79': {
+ header: '####',
+ data: '1NvK9Y5r0Q880BfB1W5IqdOR77mmqQU0d1GL1XUeQT75R2EgYE9rK1X1jLygCXboPhxzegEe7TDhUsn5XcHN0LkXcLYz8gD/7+He2HiTFxoHd2oQbI3ceBxDJ7+5kWA6Aiqy42QSCuA+TWIQcDVthSyFU7nNdqNxeBYeXiI4jgwcH3xvm0+pBf1OYLtywjUK1JwntP6o68b1LMQJFinDG+sqRcm25ggaZyxDtoLh1IBdSpmXk0papRnyyTGNgsws78dLxnH0Iqxb7FhqYfgLDIvN3i7+IALI0lF0EuTS0hSPlr/1fTz1/6bVt++wI9GpUsrdafUJJMPerXoCK+gAP8EMneLq4f5487HIkwWh1qON6Hvpg+tB95NOSJpqE72VpVxN4+wTQWyDMhfjqXBuQ1wKvTsD/mUsdinU0Wb/YT/zIWBNZPdqur0rjOC+mrOtSdlYSCH89Jj2',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 10:15:09 PDT 2007',
+ updateDate: 'Tue Apr 17 10:15:09 PDT 2007',
+ accessDate: 'Tue Apr 17 10:17:01 PDT 2007'
+ },
+ 'f8ffcda2eddd2f6d19c4be17f6f509f1f66fc5d4bff362f402c6addaeb9cf32b': {
+ header: '####',
+ data: 'Al9KSfdnvVJW+GPqYbIGXNDb4KefUjtkNTJbk0zlBsyeZc+eoDDLJKy3ukugFfDFDmX+g0U3lp1UIsRQB7JHEZ+NWKPJu/hyvbTmwuVFZUnGEZMhMOIqc6nECN+VFCllxV7QBKpdcRJ3E3fiYP4fV0v8wquOD1dfsMs26f3y2fOQLNS0+UpDe0GoRw2R3+lbot3qlftdO6vb5+LYjZEjdSI/G2fPQ3VsS8N0KLLNVHQxix4xn4Qn78i/ImlxbtyoKNLP4ZIaXZ9ELuGvV+yKaQVOVTwxpJOWKMu1Do55cMwdFjxU7Gid03xEYEaZpClcsrbwdGgkJo2+WnpC/L9G4I9X5L+sVISbO49PaZ9DMdQJAlY5QCIjokPchYUp9Vr9u4KcgbAw9FrLQAMSRLnWhf0bLr0mv2ioTOlQKPFBkTIuMnsyglD856ZYQOIHl48+K5HvUZYZqI5UJjPXdrmzycD/Yxt878pSnkkfeyX0Cr/7Rwfq/zOPN5XJcwsO6j9ubuXjnIos0E/SG1BOKrLY+sE7SXzWOqhpzkApb6ILaGhtHNOHmYAckpPAqCe85g/XPZsmWjsABB64Gwg9oviC2ew/IDXigNXGtY8tbQmAny58QPfRihT5HxCRMFP2pA1Xh2WU1vEXtP8=',
+ version: '0.3',
+ previousVersion: '739b67f6c1d52093f5c2153b406df90cd8ebf303ddd0d13d825fc946306114d7',
+ previousVersionKey: 'B0wCj/b+UZP07a7VlnKVl/wtiaFzCmPux+T4tBFQati+nSNQCHUQM2XAQ3n1VWeewIyLjKlVI6W7SXRZnCxlcOdqBLDymDkhKfL0FIvmHNKmig==',
+ creationDate: 'Mon Jun 15 15:20:54 PDT 2009',
+ updateDate: 'Mon Jun 15 15:20:54 PDT 2009',
+ accessDate: 'Mon Jun 15 15:20:54 PDT 2009'
+ },
+ 'ffb687c41ee598b30cf28525024fc18ba96b3d7998fbb298d702311f76ca2127': {
+ header: '####',
+ data: 'mZNwCsPrEohGEYglwUcTQNPDGJWoQRcRDIoWJ482qFJu617UU3Y0hML3CZ+ALtITVpnZl6mGZ3nHCpigt5naJmvwjyV9O7SVkGjc7mrzvjQSP2jrlXGXVIPqjsywDgG74bmaOPLEstQ9Sb2UPGIdinYdDglvQsIaFHQaWHO9bSYLjitfuS+qH2erK/QhqJQ56LxSpcnF5pevfuKZVAkrfhYAhIxqSQ15lZ3QSHxJfT8pQntR8QWL65RetkX/c9eydWyPqVFKqCTghU18p2Omz74UEakBBh3o6DxeTw90UY4YM1tRmsalS3oYG00BFDfDD3mEVZNSrqsxdCikqUSEGvq82whYxsFTj/5fHVLoJybYg5MfpLR+iW8O94g9p2d3jx2mTeNNjOZp+Q5/Wc4rKS7r',
+ version: '0.3',
+ previousVersion: 'c7add675f676c4615a2849d5017ac8db9066265253ffe7e03b34ab8260b10888',
+ previousVersionKey: 'RFTIyzDM9GP+QklGI/YfTgxB64iqyF7+c7bZntSZlFFDkiVN7pJbToZjl47c272J4dPXFxkORR2o+pIyYDdRvKQZQ/oHXp9aZi5BDKGwHYkl8w==',
+ creationDate: 'Fri May 22 03:29:12 PDT 2009',
+ updateDate: 'Fri May 22 03:29:12 PDT 2009',
+ accessDate: 'Fri May 22 03:29:51 PDT 2009'
+ },
+ '933abcdd036332b566a70beba4ae486123475dad2903b00a939c067c34a074f5': {
+ header: '####',
+ data: '8mmpKGrkSqiLyreEtGdKN9EXeb47uEN+XkSXEhdIxkMkmvR0A/AGtKjG1o6bbSXfPzAtfrMfJJxwyhWcRVqcikzc0KwINua4X+1Grf7QG2IOYYFqujmLyCwClGSRaannCAbio7+YI2PlDrlMrwB38RvMde6zrMfZzl2O75nkVX3DH+5IHJpwwYeukTSAu5EQR17oed+xoSHkKCQG3ToTsbnGPwZSGM0D+aiTXVW+PJD8D8LvDEU8i3EHQ9E02+d3dKPV/3FGRDgvwLIIjHU0qX5khYJ9PjqSgAxOhRKFwnG1kJn6NG1rvsXYgefJORElib/xijoCM9EJkUZ9e340WwhfZa1GbV7gLEbVn2aeaLcaTjhtPz9pL9WQOklChvdi/0XaHRrgflHogqC0qUQ63lA2CFOXwR9EXspZIi+zLzgAaEMGN0NlnbGHjAiVz6SVU/RUkh3DkKmMuGNS1n93spVbMMLZgcT5zxBFzT6jARvC8qKaxe9UlbMIH8ZCXMrq26V/sEZrxmPT3FZB+dmmqA9lLEBFEcw927uu1U3kZwXhQArQCN3MbEQ=',
+ version: '0.3',
+ previousVersion: '1ae171ac58981896484c222ab42373b0b6bc3d054dd56faebdc9018f3abbf549',
+ previousVersionKey: 'gxQ13UMdZF0F7chGySUkuhxxSJ7CU2wubdG0tijs2G9uxYEY6ADjVX6zi3nrft7ggnLM8LyuFtZqj1wMX3pMUsbxZq0v2vfpVaYZ9cN1pahwMQ==',
+ creationDate: 'Fri Oct 30 10:52:54 PDT 2009',
+ updateDate: 'Fri Oct 30 10:52:54 PDT 2009',
+ accessDate: 'Fri Oct 30 10:54:46 PDT 2009'
+ }
+ }
+ },
+ '36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113': {
+ data: '6fhueIibbxKRA7Mtb9TPcWiUKajnikM3D7PbOROBkE39Vw9E/nG8KrtJlwwPQeOGCFhssO/KX3ymYehCR8rfaEL1f9pfdh5x69mSxKRlOmtEknWqUgPzcb1yPenRbQagERadh0LF4zu91M4WjXK9qynEHoxI/pBhwQb1IsnhwtXl4ELtajudv+2Hv3p75v4XOXFsGQMsHPY+Zw7dkFFA8EXhvuxjiGvnxCUkFwNICFRdHTEovkW3VSerLdrYo5lDgjY6ebr/g7wDGuu4RLfUK4+HpzFwZ0+aOrjpFq2ePg2xObvkkMNNjZ2PcR6Cue0sf+aNqzIHIlFPpY2Hmrob8+bwxocKA6aagBu7z5GiUmZNXGE/Vtr/WWBV2+xIJyzXZPet0MLmSnGiALjPJveeKnnFdDtA929ydcAb8efc0/snfU/uDoXDiO5SWEQ8DDNjj1bSo7VPTtvZyFormE1KjqimqSwaUJzbIS4CxPnoDezaBtQmlG4z8mc8jXq1HfPu7s9PUzcbG30gbF0ch2pDj4h47AhE0ZoeiV+VYZTaYateSifQXKBQKjPcuh9PQyDI0HVua3itbbwxXpRubEM4fbvlcd+7gu+Zq03slYICD07fP0I6XGrRHVTfYpDbEb4GJBvRIeZLwRTQzOeFbPLpBU9Lv3zXxfHfcHy9oK+giIxefPdY1ZR2ZFPKOO0xYJsTr0vmTuXeXzy56bKl+yP2lFst5l9QG8j2JcQEotDV1KQS6mbcLjfIpEnltu5fc2t10Q25Noh+F3kF+LcMIYsDjwanojYlOC93mZl01hmSJdimRTk9otjlRTyC7NWwiyy7fe5IyVi7ACNPZyeUYJUPtKWcPbT73Vtf8W3/+HdhmyYNyMQ9PDCBb9WKMon+qW2+ZVH5yv/KqMHRY1fflAfxpHNhrCkwqcAAGw+G/cetbvQjpkfVT2/u/uLupMsITN2Tgvr/8D2IMm3cyDBUCshrp0AfzARRygHFK4x/0uLfCtQSNjw6zMK8mn80R5aS5bZi5gRS8JBMZ4Q0iG4kBlLpIYtsXSBwl8faljjdl/4XvNNWWrdGJn2k0eM4cESlOFFk4s3Yu0Zspo17nKAHINjHAiP3VlhuKSnk5C9hMU5i3vZO8anQmx9UEwUgQVm22azCjyNtUl6jVPYSNsal7A==',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 10:39:35 PDT 2007',
+ updateDate: 'Mon Oct 27 01:16:14 PDT 2008',
+ accessDate: 'Sat Oct 24 02:11:24 PDT 2009',
+ currentVersion: 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463',
+ versions: {
+ '381201fd3b67549bd6630841e8902be1499f3ff0c3514dd464ad9679f22f3561': {
+ header: '####',
+ data: 'DgjIW4YcJAYnckuEUzBFkfEC841LuanGopPgp+YkyMn3xuzdpGq/ObLFMVQaeAuyErh1B0REHPbq0E/SRUZbeXLXWN720GU4GXvY5bnen2h7pHvl/H4yz+kvyKh3EHJmmBjuz8s0kclFJQB48lter+G93TEmUaFke9c9m0IkKlgzwZ/PQKZyIyfZA09KFaozdSxdFRbswZj2Vq8Df2PQsKLapZWX1wYQ3lXOcyvNdTULy9MCXwPwX6te6hTLWxQOiSPsvB8LItlhQUsSbrJcJEvWPlBupPu5SeI25zDnqKDETPep63Ks2GWf45nXZzYYmQMzL0l2cenYFxlE18TcOd1Ms24TQ/iDKMhi60zZoo13qjVT5AKZ80KNu46t08qbACxjv/LeK2aM5TNycTFixGskPywpnb6MCo8ibRe5rs1WcTJRMD04sNoiuriivO2fiyo4rxjfdyfueMlOz+Zeztk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 10:39:55 PDT 2007',
+ updateDate: 'Wed Mar 14 10:39:55 PDT 2007',
+ accessDate: 'Mon Oct 27 01:07:56 PDT 2008'
+ },
+ '99dc86ebeb20a3db0c5393d6d94bc1150187b04316a876970dbbcf517b55d6f2': {
+ header: '####',
+ data: 'AJwqCWNKC9z8DC4TUI0hWnqHvQ40Y/x+jXylnVAkyO2QYQcqg51odLFSfgP0GiGEGPYwDc+kUxRrfO+ITgTNm+hHi2iIWkP/ljAC+AQ56MAEKsU/USTbvl6ShZ0XTAdRpwI/oqqOhYThVs6jTm/J8+lx4tWoMtNj835py88c/9eW26pLQubr7VysLSWuIMi+iDp7zXZZz/0gxGKDe5xNq4MGIYw8/OK1iJCOsjBdrRygLlS/Mz9sRlKkwdrDsohtRG0F/NdsIoaU4FttGs/rY91SCedvHy6ovh0zXhxOO44O6MiMbP085D1jCjWJn9S1RBxjxc368MGfMJeZja87nuvgSnLS2tGDL6zFtVJMNcH/7GqQPXZv/sNEykDNWpypchCnwYUJxvBVb45FcUzagPm+SSiekWK1hrEntZkZuEhQZp7Ud9RcENpa5h7wXUJSV1vPl8xBylx9HWmxez7D9OYRqbOlCRAEDqup4ahNhYB9',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 01:09:11 PDT 2008',
+ updateDate: 'Mon Oct 27 01:09:11 PDT 2008',
+ accessDate: 'Mon Oct 27 01:15:58 PDT 2008'
+ },
+ '9fbfcd3e7fe30d549a813f0e6c1be58ed45c3ae7305d7367bffefa097b424ee6': {
+ header: '####',
+ data: 'nZ+Lc5LWWLxnPvUrRrHhxG35PHq7GMbVENHfV1oS0Qw7/63NecssNoEbiOwFVMjAshvfUK7IjnzyvfQhNtFRbj2yzHOTWCd0eJ0O0MmvGzjpUntSDu9/G8RFeEu9jDKugwi/NhOa5legjT9pcsEAqR4s4NN/Ac6juQb6D/Z6Wd6wO0JQhT5/QPk1KllDpDeo2i/GPUKvEi/dXpik0KQcVLVylU82rf6hwEgvRQi+j0O5hnFW1E4ttxClrnPBEBv60jkNwcIpD0r+rvomDe8+398xUuB4DVDJoM+WUYfu6Sm3qI0yBfET+tJvjn8WsHhKTgZpOc2BXC7EdF99nNEg6kV5pSxV6AUA1XUz5kW+YfcSzAXzUH74OqroC0SucHe4+BtRKnbJy4h5vRfjTD+FJaj1Va02cxSR55tQhxm/k67z0QeyB98dnU1l/pPHwBlIWa1eR74gswNSeQ2jrzu5JeQ=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 10:39:35 PDT 2007',
+ updateDate: 'Wed Mar 14 10:39:35 PDT 2007',
+ accessDate: 'Wed Mar 14 10:39:35 PDT 2007'
+ },
+ 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463': {
+ header: '####',
+ data: 'm3yhZu81UAjCY6U2Knrgg8mK+LX35Y/iZgIEm8MuRDAlg6UUz9Z1Anu63COFV08YyYQRuBzTgR9YQ8wrUD1S9FG2ZmtCDemqvd+5OUMgdn4sK7G3CuzAc5osOa5neU2m4y19WuobkGnhO78ko7pVVjO42q0DeMT92uFL6KE/2UCkWlq5SdFyS5qXEJEWs2IO5C8nVpdlO/eZ36Pl2+v+afl3QQMTthCVIUR4/zVP2ajbO48yjDXhYxzskFjtXMYLApEn0wO0dcifcsYhPkozz6Locrt/R6IZXnfZfuW5XXHbqhutoJFPK6L6t0Ib3B2r1TNkPaMsVs2g5V1g3ENRd0IlbG/uBk2o5tgeu6gOYlA1scEiL+/ad9ZxiqYB2ENCGZ8DXA4VNMnzxVPbO96OIUCb9suV0fldGOg=',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 01:16:14 PDT 2008',
+ updateDate: 'Mon Oct 27 01:16:14 PDT 2008',
+ accessDate: 'Sat Oct 24 02:11:24 PDT 2009'
+ }
+ }
+ },
+ '507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a': {
+ data: 'ncSFmp/+n1pYUKi2fwhMCevSwFYO5irdcpOlSxC6YPOKYavK4iUbtBsilYWd0hpvUHW2ItaDwiyNFxs2Lwegex6dawKrpMYkPBcaZQDa746yACGgCkhz4MAGnUn5HCmz6xhpCVXMMKe3w2nEOjRB+pOMOeJt2n7aw0hCJ9tQ9JTFNrZOxeXrqoexrd210Rmr9FnKhLIvhNTN1/vXRqP0ys10omJ2mowzF4KoEVmz3ET6pS2d7tGjt9M/OYsH/ETWWc92doF5PO84g5/3HePaCo8NCqq4ul7AWJEbdnkxxmd7urJzIscPQPcoLxL7GfG5LhHTFyHlfFz9dNlccfA+OPftjyfjXTjLYZzbxxbi/nAB9Esqj5AoHfqaJM1ZOrZ+qAvm8Am3+HAXrqtiybDITrCLmGH9ukWDsx7R3lYTlvjArwORBUH+4w4/uYGscVm9kOYj/Rmz/ZMH9JibYFcPcOnr3rWXPFUL/XsXTrm9lzOvPyEYJmkENzd54AHC4Lr5vHpeuipWFLiJOrtn2WcgDG/DdLaYGKsmISXj74XDtP6Ee5lKOtbwwcmVNrl11UCQBEFHNybhXvpil5laKddOauLJDKtaDL/mKYPbr5YSk7HPCzRyE7HM2dC1MpBHuJ8g+hDkgU3wQcxYduKLRpuC0uOqrODigGWhVrdiKdZanlWUq9EkE3eH+E2A/CA8mHl7UNaH89XSvgV7uZyOmK7iZ+1kd9OzhBLQdJnK9qqP467Y14KsTt1E1+tqlqVAuK79QMnllaR0e3ztBRAQsyf5SD0KuSGXWz+z9/RjbhamW1s0UFRGh3voQMypU5RcYfYUA5KVg0BiVKFaiZBZKLo213hKbrgE2KoqVDEmIBFmwsu/S3EDzUY22tTB+o8ZKQiYesAUafGtnvsOLa+h6weF1ZvQVBerbD3fhb2o+d4ZyPkoRAsop+5it0QxsWuZL+J2oWybaikxIP/1ZM2ow4QZLaAVqihyHxqhF5UxZ9zrWxfp34BIPzzU9esSifrD0gXZ3mwutaCukZoijnGODJZtFOy9Rl1gyS1IbpyRbwz5O/YRl4BsD2aOk4InajT13Sa1BLPblQcrau13aeg/IzQhcUJ6n7enkrqiJFTP8N1aFAuYv8ilu0V2ymIuCLUtc4cbo7KyA+gnHhZA+DjjrhG/izOyWtQY/WtDsqvo/6ILwFk37JDjHfkchPEVcdl9qT7goG/4zTGX+lx8UTKKZJjJhLjA',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:01:24 PDT 2007',
+ updateDate: 'Wed Mar 14 08:01:24 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:41 PDT 2009',
+ currentVersion: '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b',
+ versions: {
+ '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b': {
+ header: '####',
+ data: 'sgq3FGcsnlbhTLetMa3TQQE6uFZv/JL6Awha1066IimKoAtQGbAr6E1+mxRmvJle91sL7oRfi6suvDanYHfAI+rrG6qCOtESn70ssS+aGFyO3XwFgypzG/Qa34bjxJ16Aqd93H8IdhzdtOxs2Qmou3CjyxbT7Cq+YW/fAo1WfctL4yE4GBNPWC5lfebxSmINlBY+zTjhv9Pf2aK6vL4p3obHl+zhz0YdKAMBwbDyCLa9tYvhGBnq/W6lFUsyZCPVJJP3bQCQww0TNCcLJLm+SYVSiC0NwCQJq+yNqDkWTvv41p5EDB06eOQ2VqC7l4i/JLE/ql9h9Z++gck74/Qs3ppdVdG7sTzWyPya4v3RW2OTc1awFRZipAX5Zd7I97dyw6Yym4y+/9UT8z8iMDYykQ4+QnOhksDIE9a8q6agDF/rbZ/BCRcMWbFylGTdudk26mu0GdPiuLDu',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:01:24 PDT 2007',
+ updateDate: 'Wed Mar 14 08:01:24 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:41 PDT 2009'
+ }
+ }
+ },
+ '6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728': {
+ data: '3oUg1TD+Lu4ou06j/MddOTXDqRM+qSKD+6Iuzia1Hop1w7v/BXidqeoKJZQI2VY9oO9B70Nr3B3wDROF+ycy6Rq+FM/xqUGHKXn1lAaSc6Wgj6TLQ6eRF6YZKSPqTj7TDWyw/2pEWk4HjcT8drTrCaC02tzAXMhYWlYPQPW4fUdq4hawoHIdopUN3vafQuFjY47OhqXKav3bNao=',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 07:36:08 PDT 2007',
+ updateDate: 'Tue Apr 17 07:36:08 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:21 PDT 2009',
+ currentVersion: 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc',
+ versions: {
+ 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc': {
+ header: '####',
+ data: 'fehYRMkg/wFj2t/aWu7szbXwrCyCDpjQN4UNck4/OiDlth70a2ve6ow5lAi2jgdlV9WiFrPejfa8dD0Z1g19jx+BBsuUYnBEKD0K+NapdJBBeI0We2nj9nYIij2dfZVx7cuvhy8sN6+DdylUQLsFHbga+Gi5hWcMuULT4GOAIy2WanSQL1RSR4ruA6zm/t+VVboEkkm7PPT+w3LuRl3wRaD4a8ZwYiSV/SzgWooFrh2S3YOUeshdaGCiYpTbXscsOxsCxc11i6wQGBqYSjksmtZDvEegdQdzCmxvq4jaVWJElYYS3av612nD5K/w7Zei6RccBiODBPATjrIczYg7HwmQxIM/6QI9/LQn0LP0yqRVUUtfzaODf0uWNpFzml9l/1lwXuBJyQFBp7H7Th46ekw9yEuPD00oZ+eXvKwbwfUU0JshT4hnEBtIjM8fH974PU0y95f0yLAJ1+M6DVXCxGsBix2aKJx9fuZP4KGpaXg6qCb/6327rph7MGomcrGPIiDjYwD/NTMdGluc55OZfGXtOZUaJCUM6nihqDwU7Ly1ZzYorgcvkX/t/0RNcOkFzGYNByp7mdcotyiHqCDKspqz9mEXAd7Noz3HO5GFpPqbRo7htDigGU1f7dvgbbfRoTz17Bt9Mw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 07:36:08 PDT 2007',
+ updateDate: 'Tue Apr 17 07:36:08 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:21 PDT 2009'
+ }
+ }
+ },
+ '6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a': {
+ data: 'b2mcYUi59l434kGl7ij6dBu3063UL1dToMIu3Zsa9RV9RzeLKnezJhLKunqoAm7KwiJeqDo/REexHI1cshGYtHasVXXuyJfMx1grH7yhoWnkSRF4Sax6w5E5wnGkEpGJHOxXJ9rOjWHZ7yqCUUCB/dqLw4FwPOtRb/ynkBEYztEJA6EKGJuz0vrrTOsT8HMXtj/w6MEZ7qI3fPs=',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 10:12:44 PDT 2007',
+ updateDate: 'Mon Apr 02 10:12:44 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:40 PDT 2009',
+ currentVersion: '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3',
+ versions: {
+ '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3': {
+ header: '####',
+ data: 'pZEWSdYIkrX8/r6OYmO0GEuKG9baUgn40Bmw7hXZBd/kfWuRjWsL4/pc5F5Ojrx+N0dxmQn5ZqKAzOOri29Rm4ruxnCbyK+oDsCDyMSnWy/VJcvystnDKzKmBRQVAOSEJtzEb3OtGzvqm0PQ1Dhx1YUAx7L6KlXysmG9h9+MjOcErRL9/1x1LZ33ytR+zK4LvTAb7gN5/9QgwysFyCkNP8bG4nyCzPMiUrBnP0odMTUvDkJDlY0Oia6VjGW6oNxnGIgA5fDraRrW4JH2oejQcrL7+X+jpCp05g==',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 10:12:44 PDT 2007',
+ updateDate: 'Mon Apr 02 10:12:44 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:40 PDT 2009'
+ }
+ }
+ },
+ '6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18': {
+ data: 'jzjPgxRHApIJA/6hiY4XCtb5+eKzHlOeoiGwfVDvip95zU7ThHbdmxOUomeyCOZ3S1SGPT4lHvqZgfVG5m5RvH3JaAIa8EY1ZElRohoX3rETVPJzI/Ov5Rp3lZjtWlu5meNrcJz811HBHrtBuJxAmSjYcY3CCal+oC2zcK2fLZR/iOQ+69ONVFhdV9KiOqzNf8IisIa1sIgFopqsdHXiZ9oLe0a7Y56q+OplyU3A+TmxKLI+Qq+WkjvdMzZDDqzYH47me5niugYPdkQwN6WQUE0sK9QPs0uU4TOwqCwN9nPH/DoQ6oXWAu2+R4iCyt6ZjLNkClbps4s8Cwz6wfFQ+4T8bcldjveJenmrYwiUzxSd/4xa34yFVXVw2OD0n8yZhtvNFvfoPy+X9z+Y4f5HlM0qzL9zYya4KwWjFQzhOxFjni9JyGM2PJ1BctB+q1J+CHuhlVjUF0Y5zIS3zFTET8jjDGBZDWB+Ao9E8fUD+0OJJUdKJ4kUfn4ZUZUG20eLBjmJqWBGYZX7UFaPv8ksahoK26Ol6FnBE4KpPStQeDgXZDzGsiLlEsxHJLUFkNtAUXozw38bWWQvi2VIFtkw/ZViPIenmSNT14kUVWdrlKQC8x0+wECeh5ffv0i8UUw3v8QC2ZE7GV0OMl4ySlRCuDCfZ53YFoB3HIR1hSZMhHlHJDPUz8JOuXdHcUQaJeNrfWoC2KkKb0ZecBj9iXooDh9yGi0g7TS7eyhlz1LHpzEWB0CPsZqhNGMxmfFWur7v2hrYzoHQOeB19ZSmWzfUwd4dRpqMp0x1lZaF97jr+yyYhnuQvuO6lru15Pg6FqjzhsNiLtaqtyoaMiHZ9veZs04qZZ9Fn3U7HeJzjZSAssdLnvopXi363cXm9JqoClyV2OemnVoRwOZN2gdSZxGeOefKR7U+lrBAbJwViMnmT0Nd7AC8C1k34iEt8HJmpztXeOgX5CQpwUPENMCUPsookFbIh7e4aByllEQy0gBbxUz8JMIWYyw98hdASnZ4s8bQfSmiMM8Iw3YxCexKB62LYYJn1UY51NSnwCtwRep+NhaKDk2d6SLh9owxnFbjhw22RriPd5f1InJycjtpvMzWLavl/hDsjjj1kWpnCUBTM46LbERmjz+s4x7fSf2FhhguBT36elz69ivXoiXI+7p0E8f8HsSwm8sgN/AA5m1svsXsdWeZFUiWtAwLg0tI8YNHlazbvFCXfIC6Uhq9eDv04iqdZ3rn2c1rwSx336A7ySTBFdxOCJ46F7ShIhNKm2N+5Qf0K5B2L882fbwqiLsa64+X9aKvufKTsd11vyf19Zivg/Ze0FWoGC8D63Nh91k6Hu32RT+uAtJIjQIZxu9yXJM9lMaRA8ieER+ghrLHaGQqF9J3WmueER3UzU1midvTynOV6g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 11:09:05 PDT 2007',
+ updateDate: 'Wed Mar 14 11:09:05 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:48 PDT 2009',
+ currentVersion: 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5',
+ versions: {
+ 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5': {
+ header: '####',
+ data: 'BbXNAy0GcKKyDPiwhP1Jk9mIi3uXMHQdhuxpDvoR2C3YITOUBpurxGhhvmCg+a9pS+fKJdZPxL2mPbJj6GfWTEsm7K/ECEjrVkSTHi6PTUUgYVbCumq9EHjUspos+7VrifZry3c73+qAvIKamvUlNB86TchMpOXVJIyx8UgRX+bdhrxk9ZCEVOiLCG1zGPX8IzmcxPmBRZFlHYqE4ibhl/CLEzWXZBYCofTusClhOh7YM/jBgvDt64W7aIN2y2KiKwmFySkFZdnOvbAb34tXVimwqjqWPvPwd6MujQeX1bmaDD7Y0kXac8CJxqasIezLo2WqzLUbEXdIHGilkaPT2ZKpKhKkpHJHFrV2lVuQJVqwPUr0Gf9qMKgVnsyU8kUfq9ox+fhH70+v7BQSjT7bxxDLs0UesQeL7G4SqvNet5hPI4GQEpOY8p5MUFReIBTRm72NQEU=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 11:09:05 PDT 2007',
+ updateDate: 'Wed Mar 14 11:09:05 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:48 PDT 2009'
+ }
+ }
+ },
+ '8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39': {
+ data: 'pOMTY3PnUAbwMLDEYNJCMzp4iIA42YWr6gqoomg+P40e7LFUtbt/RQRelQwNIztyUSVLl0rilkZZkBUVvxrtTqvibKITCjJQGQIzvcb+Yl4mNosl2Rpp0xxMU03f1+G7eGbuCc5hJXYVAglhEYplaAPzHbRWXMY8iZXZPBuLVf5PN+rdpgAfkGeZ7Uf9RsQ9p/EglrWXYnTwXi3saUfzIjfvSHm5C+dXTY3FHpIc1YkjFrdVgMkhYQGV60JtZcwFtCEL2NpVljAbRgHoIXTOkzUvep4vxrtfBBWWMuAWEI06432gtnH6IQbrR6jOpwuMt7k/09qy/fARPHs3r4qTJ9r2uqWHJ7tjJw+IChQPC+3l5HcPpFURiw8LGAN1NyY1hUrF6N84RSn7AKS0bLa5qN++5lcjjxn/k8+JqmeUqN1/SYIbGwNnJeZ0vA8yvOxnD20iVADX5kOVqJDwXRPLaF6Oz9KkbOrmANCh+PmGw1i6PduB+FgAU4HViYCw5IGOUZ30Pm1NJofqfbhXvgzn7ey2+kUIAwDyOUpJ9fW+9jW/JU4rcawmzwBYN2V8apOoyc3wQJICm2984wIfVBpygCOZM0QDyVgNo57qKtYH3yMDQSkKvpEUmuhklMYhcV+4X5ggdqx7lYXO9IMDnFf2ZDiZyieTlOlRv/nNVecUB177Xpnq2e+X/ik2rCQWVrIymiV6ltr1DEv0krXKfvXGG/FMZHUmo3m+B5bG4xVhmt0GnHseqvY2Vrl9NksLgq3hTDOGSGIy5Nv8kfrd8B4/6Tavh0SumiyXnrTXyYXzCK9E7IqO/0KAln63VkcHsbOtS8mj1drN0YQ2KKaeIW+Yr3Gm0pbcODsgA6aFfz1itZVeovBqUklhXS+/Es8J8xOSvvSyD/TmlFjuErHa+wwNQvftosfwk9ZTt0eIJS5aLHdU2QsCjdfSy0DEPkk2siGhBX5ZhRzqyIAyXApSmy+e7PIqn/dDR51+D1ZHwoTQyTrd+F08jBWZgU/OvS8MRxNZSxQwsi7bcWZG+w0utrIDB8eSOMVBXI5XBeJb4h5Bzut18C1shGHeGkSJp04=',
+ version: '0.2',
+ creationDate: 'Mon Apr 30 16:10:17 PDT 2007',
+ updateDate: 'Mon Apr 30 16:13:27 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:35 PDT 2009',
+ currentVersion: 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8',
+ versions: {
+ '8a032b53f7356e2d8b28665211abbe2cf1c79fd8eee4752e83cebdced1c19911': {
+ header: '####',
+ data: 'OXpNHHSkdsaD91hw2LER+9XKpf8+bh/O+OcLSgG/gAx228UpifOCD4HTAOs0C7IJ5zhAq1L9NjCGb1QWWTFErYEtDEBRBV4kogscP9HWPxYyZHxjwPI0wE7Ri2eD4Rma76Utb+xVnXWuT+vNb8eRUCK8Ur1rlhYafS0uzAYvVqHDNfZaICksxeVQojil/kSPZDMu8ASz5pMNFNCF4SlwDKPRrJJDbNZ62A3px59YJtsla91DGVyOLhb7VNRxEwnXyxENfP78yA6OjvQDc2KhKFUpHbZws54IolLK1I1mY/Z8BiDXPSnOa694Q1eZxy1Kx/jLINZUIPgGg1++YWITx213awOISdf7Oy0/dUpu10Vr1hgAqCVlDp0IuGK01CswRzEdLVpUk1DaGHuin1rryZx9vThUkEJgQQc3ivr8',
+ version: '0.2',
+ creationDate: 'Mon Apr 30 16:10:17 PDT 2007',
+ updateDate: 'Mon Apr 30 16:10:17 PDT 2007',
+ accessDate: 'Mon Apr 30 16:10:17 PDT 2007'
+ },
+ 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8': {
+ header: '####',
+ data: 'tvSUu+NPKHkwt/ZLXdLGdDm4jSxTEtJfsecdpjJ9UGN3Y2EBCmijU5i7q+hMfNDqBJ4/m5Ayju4zYDAKGp2pt8l1TFoDurITdFcV12jL8j3dc4TTD//uC6OtowRN+altgC1Xc0LsSvEPabjAlwfVC5xqirfm5t2mVmnFZ/GALkGLGxRJRduylT6goPwfunkVGwUdqMa3md+9mwYn2gm7CyC0lpcKX8AZ3B4Oa656yRa9m3Wjgb007TtorLIpZO2MzVwxcHBqqy7YpN+zpmZz6Md9VK3L4F724tuXXWnDeVzGxBO7aZVr62hwPMXM6ibCjUScsaS4f0chivA/tBJoyx7OqKhBxREGeGjpHTeLxyHcekbwXhXyeqxBuwG93yGKutUhGLVYcXwe8/+xSeaBGj/j2RWutKbNKG2yQyNPGj2cxJWsR4YfOQJTSOSWT3K6Mmf+r6hLhIo=',
+ version: '0.2',
+ creationDate: 'Mon Apr 30 16:13:27 PDT 2007',
+ updateDate: 'Mon Apr 30 16:13:27 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:35 PDT 2009'
+ }
+ }
+ },
+ '9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291': {
+ data: 'xSjnJLMCEBBiOM2RxFm2EUCxMy9a2eexGsBj851cR/PsJlfG1lCh8HwD1i7HEWVFB2GBK9Pf+U7TpNSYsq9VY+AzBNz4p1aSg3Hswoou4OpCCgnBpeNLkr0q7KBmSVmSH+omECgWzbqux3LiqT7yEWxemVRA4ah4a09DvhB9bpVJiteBGg==',
+ version: '0.3',
+ creationDate: 'Wed Mar 21 08:29:06 PDT 2007',
+ updateDate: 'Sun Oct 04 14:06:08 PDT 2009',
+ accessDate: 'Sat Oct 24 02:11:33 PDT 2009',
+ currentVersion: 'a999c255e435e85633f136d0464f29e6d41f87f46e6fb50ca63adeede9a6650a',
+ versions: {
+ '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7': {
+ header: '####',
+ data: '7wg/yWfSasUjJKV/5ygFfteazVSdqEJ8xGAqtS7m/W2q3rOR+2fr99Il2TzxXCnOe5zV+iir2tOqPQt6BCGbVf0NVwZtvfO/lvfMc7DIwyWuhZ0sS44LBTD9VY9fruuIegktVHSNBoJTCIfAHN/ut1iB80+51An+TdpYT3SGAVM4RdenQ9IdvDOnQo2KE0E7BzHekga800VJrbqI8aJEtmm5mOjte2xHYSPFDCtwURQclwxbNv32hAY/IUkaejqg93WGIzHIIK0+SSDzQwHYQo4yzVGCKKy75eghpvGyg1zbzlv372bND+OuA3laocARFfe4rRd5I5nh8vmSJ+vybh3EIJJzloD+qWk6hsEagkYI0RYu9I2uOfA8drmZ02GV5/ySDsBHX7uhaTPGx4J22rNJoj8s1L7UoaohUHFvUerBvQTir2LPbzqT+B07wZOU0ibtHlaN5C2XMKRxfvGATeR+2J3l7WisCIoRdpQcPFHA7nlTTShBiCVstLxolvd7MMzPOilsi3ecxXLQSeWara4JILqXQCJ4yLbQCMnSpIrZ3TXbwbPZ8fjKjogHNUaBPnmd1hWoc7IVvK9RSFBEdCh9U/hbyPMCiSjdsUCTclmhFmhiVIlB73IyWixmLwHSWSl/ckMxcUK6rB0IPuWcT8iJkxfqOziFhMvC/cNydpN5Nj4WX21c/1M7lVlX10FRx6NIYH5szEXULmLnkfEwr35G9mKJwR2pgZ272UiW2cH64/+M+Kh7XnPbQKxTwVR3FOhR/qdSHeA8MTc9FDslFaTT6YSeJEPoQiLg4c4UdbB7w5nA0o4qg82hiiJbTfT2zFHZeeWOpVO1z4V8SidJrQkh8aL1/Is7KaDVNfL+Lx73gfO6tdSviCJJhD29iTgn+MW4MlGwpeLKpvq+LkXNXi/CVjIa1VqtR/Flk2BqwT2hccgw6E1ML+QdW1n3TvTtdLIvSGheOM5kLdnF76e8Nj0kHDFbnxQMlO7lutngaNBRAvhvSLccT76TMG4OTxNZk5aOre6AIOuUfrFD3KDeOqWie5zpkvTOd/JK/JDFYgbYQh8AqhwJ7VWUH49vfd6AqfwHwdNWymI05F6/0Co4xoQ6qN+iYNConUXz78Uo7AraJuBDQ3a24+wL2mLjnc8jUDFUaAKM6gZUv9+bx1vk6zVdaZcuqgZc6dcyo5Oy8lmbJ/SmRb8BF/Q2nW3SDv77R+p0bKPLmjcytczlMNct58Q1LoiLnGck5v0wByQ0XIMd',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 08:29:06 PDT 2007',
+ updateDate: 'Wed Mar 21 08:29:06 PDT 2007',
+ accessDate: 'Sun Oct 04 14:05:49 PDT 2009'
+ },
+ 'a999c255e435e85633f136d0464f29e6d41f87f46e6fb50ca63adeede9a6650a': {
+ header: '####',
+ data: 'xw9i2USOB2xkgG3MBp1+qq9e2nwapnEt0usRAVmUWXcGGLbXJi+ImdrFNGPg3TSZrTIXMdEbLmjxAcxpTWlBfd5NhBVDzY2q/stiNaUWfI8JAHdl7E2CQRHa9quVnxPzYytVbUP01xoUokBWKQnqHZduADt7OKcgLy5iheR0ECoFXT6lKcJtD8mV5TZqKlYHkhNR8FehkNrhX2BWfxDHtlxZQNOK6xBCHF9YQGk3PQqmeIAbvxMiN2sGCdH4pXAURHIcF4uayV96bmCa42r+i4h2p46BcNghSR84ipC6Fyh1y+oGyZ5GqaolmVQcZQ5UbCba57+r5OOSWqmpmbhyoZ8rPOa/ZYFiZDj9UqNl7Ny6fB7PqWjVs9oSLb3oLe3oqfrONvJ/WmttA5J/jztDYYN0peN4AAEiNQLnFZuoHp4S+Wxuf0c+99N+I0egIIgIw88+ssowwMY6Xrf6sxEmA7B6hXB5V7TO3J1DGkVr4Kw6NgxMrFVw1AlqNpBrxKdREYaGRmLwB8/jOC9tr2RzP6SPylXzeOk9/v3XikG0CZckPATqLG2otmZ0pVpJc5XwyKKhDAZWYEzPKXXZoLfdNoa4SAiGF7/otBtH8k1D8d2rDMlhigIjtYR8WvBxCdfvnFeD8w0zewymA1Fbj72Dv8eHtnnNYYsJiHldQimSgcaGkmyFr0oVPo/skLjRjBsQVbiE066eTAjqrcAfKK7pg295Mhgo1aU9cyFPfOha1yiM6BKulihLTMbCr2+KTdMGagVnBxKFmfWJBNbl1J/b5ztazo3A4rIOddUPmGj0uQpaOVLDaFIVvs+3d13JB3iyYOz1nAYlOptS0yzNEMlJMDX4F5gkABGFazoPPQ7PgQ5JUmRrO4BBnp4HvJHNY0Ix9LOUfaLcp/533C43fHTcofB0AVqpdnU2R4lPl9FkUsyeQ1vmY3Z7tE0ZNbM3rE1P26LlEfXg9xbSBzRwS5EOxZF2ZJv9h9a8VPPbMnEUt0dZrXhyUycHF4SfnKLmepZkHTnco64kY9Mc0vJzy5gPCF7z6SDzeA35SX2T25Rl6M+xKSeU1vCv5kPWDpacFhXX/aVJnSlgjYKEWzV4jTGdlg2RA+034JpbsJgDTIqdLYdC44EyZwocR7MObXf0OTprugDIM9AGHFlxPda+TO6Cg0mI7UMYEP/D7AU=',
+ version: '0.3',
+ previousVersion: '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7',
+ previousVersionKey: 'tVHT9HgAaAzSOMZrMyvyTvuJW6P6cSGU0lUWky8NCtKipfN1BPGcX3sVgEf/PTXwKlNxTgpogRDGhDMIl01RHPaqAIXY+W4x/u3bdH/c2NTlJg==',
+ creationDate: 'Sun Oct 04 14:06:08 PDT 2009',
+ updateDate: 'Sun Oct 04 14:06:08 PDT 2009',
+ accessDate: 'Sat Oct 24 02:11:33 PDT 2009'
+ }
+ }
+ },
+ 'c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065': {
+ data: 'HxkHstm/nWfD4tTwtaDqycSrP6vR7O9JUQrVXp90Z+prnnvuUMH3SbOlv+AQZFJotuM9VVOh52yWcl8TuSJ5SYR6pwmZVcK9GJd3aRH48wBRrsi9do+pgyxmzfpBm+CMnUtI63LMPfyz/zPndUQSke5+G/Q1b8ZddaShjYHWHEifjdswmKg68FOSu7RuElR/FwRCBwuT02vMRdrjwxSxxM5zWB3vqzN4xKi/jkvqGgIc21m8adTQoxAJARleZiyWXzfPO/MpUs3vA6nxH6ZO1kEayGw3ZAR3nFBiW0UjjdXCBI2b4PcUP0nSJKetRSiudo2cUKfYxsWgEPoG+PM/CQFdnlfGcPf4d0QYnkU+JHff99mLJRmz7VWH7ZeW10NTxzTEr47diHLpyufZ4knnRgfhfKtwOvgmG1n1lXyXDRVTeyfCCX+mB5qdB79ujqon1BiLOGQfLWZ8bDyTZAakpcRJb8qk3zP004XwN5BpO+jC2waMcUEuH62gSQeelGZ19pzBiRz8kn3ZZ8iviX46Wwk3X1TTke9teF7t6Pop4pRkaAj2z2ji0mqWtv4T/3QW4Xgf1mKaT2t8ZaucGvZ3jrxm0CW/Ra3Cy1v1APwRPvKnY5i/WPDS1elq3vNF0NY7EQbXrxBX7hgGpUGRcHSKYsuftIquJFv0HV31jRhd99nZz6Otx82xidWbroIS+37o2Rr56X/AwkLn3DgH+V/YAK24z3Otku+lbaorXnv6C8ZDUhcce2CjgEuCFPmv928YOahgmE0Q0uKniwVXgXACevvACEsduvW32JhI4D4cjRWcSzB6YhqXE8QYCQwK97OykJ30Szd/ZYykiXjdjymyqFOmI9tZqi/PUOKRJ9NhYZaVAeLEFUunvKJWHNs50CqElw6z7nAvBwYyEVvvc+rSpMb2Z/KAWLMzv5R3MeITVUph/RlRlMIrJr0lBhmghnLRt6cGRQcDA2Si3tGAm34K+BpxVbTK0ilTrwzCfaE3Q+dvBTFRcZzMcPFLHL7Mho1/kNMb5S0izIpsNPCb26yH/gueYghVmhRL76HQAH79k00uJcyXt57AYlOYQM7FKDHWciWtJDOMNjVFDYQJJSAS39HukwrLnAdqCNrabrS+AuWhX+CqmMlKQ0PRszjtT7oQaAcgJd0uPOVz3IsjyZ/CmrzSxM+c4iPXugkiiyS2HYU7EEz9IEDvoqwv3Djcy4+3oxPUdmIJGMz2Mk5UXMDyMpqfuujirZI5r5WQWWQLivD9mid5RWDiQp2NYwpnQ/J0emEpWFlf/XkmXW+Em/A0+DOeJtHB729WsKYEvMWOB1nuITkqPJShf8FVEunHzUuLKsG3Hf5yEc3isB5rWGO8hPCueVUKgiS/NSCxQ+iinBTO3gUl+hzK+yaajQUomCx7+N9/n5HTLM5kFsUxZ8gfG3LMEK1iaza4KZeS8Hmb58NU3e3MI0FvlZHa787LqNO226awx3sX/nuTMX+LXx9v8/AMrkRdbzlcYbe6xWRWcBGiTirbTV/CXMgCdop60xfRqCskQPbfj89zpHQS/GiTJjhUwh6XKc/TpbjQJ6OZ6dAQBDxexPa+sjr70kLARxeUhvDUytp/zd/A5OBpuZ0aUz530aQEj8BCAk18vdUks7TWcpiw+/Lq//QLu/9uLU/rLanu2DFUYGXo7bJzy2QpzuoHqKDqa3anK9Gs34NfcIjUbeMUyCzd6CFj+1vGNIk4zZi44PZvmqxZXI8XcxboTpnheNRksjw36FbhIKWMWksIIq+mh4XMnkQcS83PB9rwMHsYY4nKfCwddYfRlbVjcjX+jSlz0r6Oh3KxVDP6dt37CPo8DGMvXSeU4LFMcYBkZ/Q57sH3/gyblyHK8OqYX3pzbnkCqoaOwAseBrQYMel3OgSLt1nAxzhN+ZicCLhpSYHCcHYDcg9xoa/1u4uEMJ0JC+/OzU7xp3nC4OgSYxVzL+gBNnqX4Plep7oikvE7+qymqwtoEhEEuaO5pbOdPG4I7NknL+u/RazjXdy3IGyfUPCCQKsjAEbAkD6OBZZf4St21e4sSgV/anAYFGr87fHMPtXhBxH6QTQPgWqrK75Lr/RaOLihrQHgVhcQHYcTD7nTtPNelbJKx5aGOFtcqykaVizLzrflZWXnk+QAjHo6Hsn/edm7Hbna+JTlyVsttp2vcs8kHQk6xcCpi2kR7nJwb+6kntEEPZAyuFQVwvdkqyC5nAecdg==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 03:45:43 PST 2009',
+ updateDate: 'Thu Feb 12 03:54:37 PST 2009',
+ accessDate: 'Sat Oct 24 02:11:45 PDT 2009',
+ currentVersion: '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a',
+ versions: {
+ '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a': {
+ header: '####',
+ data: '/mnLRePyLGwPaZ+EkbTRHdE4jz4gY99jnHcIp7AeMfcktEpPmUVNWLwGSJUH3ANP/cO1znxACVQPzC+g8IVIK0muJ/lZ4Iw+HkpsfPtBjPZc+bfhsY5Mud00YBsImleIMlbbJGv3l79eSPcea49OwG30xro6b6I0KK3BmSgr+BG2AmBrKVlFRTPFCHRbO+hG/LgW/xqYgwd9f1dnbeVYCm5lA2zdAnwmMwlUIi/J73MbnsSO0Qg858iF1SPQ2Ne9Q8SCyKKEZwBY/YeSgDzoO76Wvqbzk8uPdmZldaF4zql3ffBeb9ZS9KIyyk2vJcLk7c3DUc65vaT+w25+2GSpEXD4YIV6VSr6Brz4w4gzcDMeLve0U6oruqWijz3CDe40yhd4mMt6wTVs4xo0KHc6yKjTuC1ZUQwZvuCiS8T5czaGpc0+fLyfuE+pVBxTlpOjkoZqzk6NsH5lcKMzB1TCscJ8fbOdtJso7DRUvijIE5+ayY9IktZhMeHsk2zurKV95A==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 03:54:37 PST 2009',
+ updateDate: 'Thu Feb 12 03:54:37 PST 2009',
+ accessDate: 'Sat Oct 24 02:11:45 PDT 2009'
+ },
+ '4ebfe3bec6d419d61eb68a1f25407824e404e3439c23fccde1ac19225b40cb06': {
+ header: '####',
+ data: '6VvjRN9LKi7tt/HsgqmU0bUdZQNVjVAYNLdCrfKdRJCx3W/GZHHR/AQF0FcvuXIn0MWMUypHpTZW86V459OEoV4W18HXEisQKEiqBnUCBaxBd1NKZDpYsThISXXOhZSbXylbLoB+kBaYzT+Fc7utDheVvVPeMo+iEb3ih42B3En3ZXcgUAdEjfbRUm6st9Jiaz4onwXWknVhkF5QewA0GXDhT2JdakFxfUDay75wKvspq5IszbEYwsu+TEgsbuO4/R/bktgsQUrbhtKIEIiNSccDNx1JkUKvIxrRfp1m0Ar3XJsDfv7YSJSLdyVheOEdIpBkeZ40LN83uzGRMZw1bQsKf+XOFTfacYZBBzwVj8e1rJC6AWlH6Fbn0jXw3JcEljA4zUh5IrYhWtyIZW338UVsMSIp91USeM4uCvPsOLAdyCXiWu5H8MMYGz1rJxVlTbMiq0tn1w1f+CL14v8EiUft7l8kfZzBZzdLvzdedD/wHQ==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 03:45:43 PST 2009',
+ updateDate: 'Thu Feb 12 03:45:43 PST 2009',
+ accessDate: 'Thu Feb 12 03:45:43 PST 2009'
+ },
+ '7ef137cf242e00136e57ddd262edfe6b418b6f57f3b5e5e15f3ec1232867f6c8': {
+ header: '####',
+ data: 'N5eWFfsQGHR1WytyXuVySzJ3zenJEB6IaKr2vgWRHTlJFzexXzJmSLoozTP9Z4TumDOLsNrp+EUeIa3Yo+RqSyQKQRFDHXlUYa6c9PPLPXdexSA9JO3AHzMSpL6K0E4gN3BybjL2rbcQwUqJLvCKy44OdiJvORGfIIpTPx2LQ1o4P+chcpOwwe/ZhgLWmNC6FmkTvsU/xJlNuApyD7tPX7Cj3lP8WBfYEPr68BqTKAa9cxai6ZF4BRC//rFob/4pQNHE+7qjOSY9HOnV5uCtZehPYBwfpBiDYhaxWJxXN6sxtpe7GC5CM7gAAHs5lgVaFSWffOAL3zeX7I4vh3j1nYdXoh5KowZJVVUUfhwqJo2T3YDVsaXNibZIaPd9GlbeBBk2HL6c/ao6B8QNwRU7GvMHAdJKta2I9mtU2NCnr0Uwi4rZRR05V4k0HIMLEJxRo/IYAysAYETNIAXzk0twIokOF5JPjP4uTXRZ8LdiS6JqfoUu3Jv/7yq8wrKZM7DaQA==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 03:47:39 PST 2009',
+ updateDate: 'Thu Feb 12 03:47:39 PST 2009',
+ accessDate: 'Thu Feb 12 03:47:39 PST 2009'
+ }
+ }
+ },
+ 'ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c': {
+ data: 'zbQlGR1fT8HoH6KvOPBoaIjMUsVMh8MSNIzPO2muIMJDVfXB2rEcPnIFl8fNv9BtE9OLecuex3BQVJKGXdVGFYVNiSS0SgPoEpyD6GJntEIOaB7GnhVflTm8fT7Ba8ArS4r+fIL32Jx9F8sYrL6jKPWeuImGHK+x3X32uORI6znkRac7J727TiTPlbj03X/Fj3Of6Bp9Wa4xbVMwzi+R6NRKD4A6Za3mqhoSpYFeHWld8+ChJU/w2wFkj292OjPBzvvz/SR2Zth+AXTChreQ3Zl1hWNGmU2Ep8ijFCYwcamgPkQwh4vBk9NJlzIgadORcb/0EPDxn638VNA0dbpW8MZUCIMWVe3A8VgdllWxei7dDy1ri6xsKlFovLYjRRPXgAqRSqVATqwyXqhBWhoV6VZ5NaSUGvM8okC2GQSweLuz29py0F987MISmLjav4gdvcMA1wn7FOIaFTNg7oy2CxZefGhHT3sHfX/PIvs/ovfj+7TewI0k+HR414az2D5reo7S5I4+roCm1QLVpPNcXUxbAmEbjF8JCsTtECZ4kdpG39dN6BaMlHoHSN3wu05uTSn+sL7g3Cg0pVLlnHo9baw3fUnVJp3MCEgZJELaiI/WF1Om2y2S9UeLur18z5T7hHFv3Px28D7c22HEDdF2CObeh2uOlZGAa06lp7YlYeoNtb4CqLlZAMK0xIHfNUceC4OMNvqyGswd5WJsYQEnMry20OkxY6YinnQfjAml54B6WlvNVlg/YaKjw5AVinUHjzEFfQbcBFnFGpqg5qJk9hZmb1VI6Ujhq73fPydSfkvfScTImqxCNPD/BR8ovoaJtNpE2gmcoX9A5zhZgu5xUnUnXoaQu0l7K9kWof/UmCCl0O1A6j41aebWr+aoFMalaOPzNJ02vfLuW155IwjFQvRuAp6EuktZ2dFKyFl3QnLbwsMnitReXMoW30cqTYg7ODQnopE73RIb41Nj07qdx6FQMzw4gAIEFBe1iRvlMHQazZCb2ndVvgtK3ZcPNtDoahuPRxMLaKZlRnpa8E5F4o8NHYNivshawZi36Hk6w0dOimCiuk/zvJ1mtx8hhX7B5dsXlNcKxLSvI1onEm2x9HL318xJeT0y29alzPYVFuQs5kq1+UV3h2hL4E/H8h+5mWtTLf/MjaTZ09okW/etuHFFjCmLoKwugk70z2yLWEJGmbjw',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:51:17 PDT 2007',
+ updateDate: 'Wed Apr 25 02:14:05 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:43 PDT 2009',
+ currentVersion: '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926',
+ versions: {
+ '3895963f82854530ff754c8e2d1eaef8d884a8cba7cd058b8b7adcdc12be3da8': {
+ header: '####',
+ data: 'rXmjQYZgxv9jpFus3T/qa9Qc1lxt+mDF+dmZeDmDG3IiE/LnonGt2MqL+YlbFzisF99Uv0IQGOZCPigtBwOXB9m6R6R3lEy/YhD/C6b10s80OBj3yr3PoTsoTmbnmZMYd4r+qx8SaoLLkR0aK6NADYZXebR5QgVtwF/a01EifI6YxH1wm1RX3kyRhIrMzOtL8zHbstPvW4sRtv2YpZqlZqBTdoiqztDUZTKEcCcU5QLnHYMNAVpDHE7D9WvQy8Il1taAbxg97Ir+2ktZLjqfJdKhU7ZLv8fcJiRgnQKPqDWcqpjA+CXM6Ak1HCf9SRJh6Hl64+fk3jEVAPmHvry/xq2RPCG2YnVNWZ+uL3QNuH4zt+IbP4FnrxkCAprmEiNwvuEefMgliGRd+FowIaiFWXcEtYxxQvRDujZN6eoTUU0KVnuy85PKi3ih0ZECoDM88MFhztwCG9/nJQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:51:17 PDT 2007',
+ updateDate: 'Wed Mar 14 07:51:17 PDT 2007',
+ accessDate: 'Wed Apr 25 01:37:27 PDT 2007'
+ },
+ '5311936f6a95cf123007ef867388adb5c1ec5b2cf1173d66e501daa16488e42e': {
+ header: '####',
+ data: '+VirbcZ59SiN9UJKrQkjQx0Z4avHIhvw12Hq7fs+Qnoz4RgCS17fqzYyJe+jYorjlMPjzUcALYOTobqJJp4Sp8v5nOilHW64Gny2XRp59PQPg0zE4TP22l1PzK04+qJusR5NLPU39hYbW+InkDapdIhdf+nIruqeA311bRLg90A8xmpzio6PkZxXmhZMabbEVfXsYFBQKVBFloTMusBG2eaxTjeK0hOAk0uEc9RGOEwCOvZvjRFCP8DyZ5T6QV1pYYgBFBwSFrB/koXmBmObj8zscJXQ4H4UWC0yw1B3ABbhNX7vC9q+vgZTxnGqI6GvzLcrzaXKTEyfa9twq+vKFX1hqDmM0UVLw0dPOy0/3tabJjFrYbz5EEKVin9UqWhuy5YIvHEJlMkH190Zo+lPMuHvD8TiAU1M/n1bTQSBQb/8STD6uqefbKS/s/bXcS+bdVKBmSgCuutBznYO',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 01:39:26 PDT 2007',
+ updateDate: 'Wed Apr 25 01:39:26 PDT 2007',
+ accessDate: 'Wed Apr 25 01:39:26 PDT 2007'
+ },
+ '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926': {
+ header: '####',
+ data: 'P1LfM+8PA/kyelFsojabLfBW9D0Aey5qDClz0OTdSamMT2Mv1U35eKcr6ilUrbtW+dKJotAzs3B1dYGzaEQ1j9HnhiL2pk4wgT1JWGe5c9frmFX/3YGO63c2ngnaC/Rrv3LC251cLVS1aoWNPskWkjZLzF7EiWbAeNYTplSa6MWm2LdHAm6xq2dcgYx53RJVvjnsCzpghQdzL96G8ScJjnUx8FC8mHW4Ds0rkHTeoM344Ao8J3o1XwoFqFFJ2X8+lSkj8LVVdjff1EHIicjrMM0oJG8VyxK2TxMvg4mnLWP4ALfh24Wrb9XmrM0NjhQXBo07tL9dwa7sHHKiBrM74644vBR7NB0+Laedg8D+6FmgNoR6icB+qvxCIIvAhOpJ0er9f0CGDDS06knx/lDtVVNewzxx4ATuG0HQn8M61eU83EfbKWG4Mg+9jtRcW0/bdFW/FQr/OeKg',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 02:14:05 PDT 2007',
+ updateDate: 'Wed Apr 25 02:14:05 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:43 PDT 2009'
+ },
+ '5c622bec0fb939da012beb98a858a4e16bd670b3e6fe1f7c92a247f88a65c747': {
+ header: '####',
+ data: 'XGlplDTD1xamZO04H6RiqcLd7XaPwxI3MqpKTCVHPBoMEkwE4A1izGjFKdPqHbQIuYYcT9xDgPOknlkP89jDTfcR4UfENtKHFgFaMee4orSER+MhldJRxMwPLorZmMNNZzVmTmwJS7FI9jYiXEvDbcyw41kN+SA0mxzWpc9emaX4TmZHzlBpY2zXKJLyN3otYYzcTWzuu7DJejWrB+CnNp925X9vVomBPfp/Gt4tiOFsE2ZyEf1B/7cDmMszlQgEgGJONS+C8Qyr+X3GEh5iPoYsGpMNmF7aYnZNciE/B5lP/ABVbZIi2KfmRlSf7Cc+kMkUXyHxOeZHuVv1ZlzfIe3gXlD0/yUJFHNju8ai+F3hpSkhMatf71mLQzD5oFrTmKatH+zQZhGPP9dQxG1cgZRcjbyUQJMazo+0TJuNXNndi/oiRzRJjYRUbZKsfRzIAEU=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 01:51:49 PDT 2007',
+ updateDate: 'Wed Apr 25 01:51:49 PDT 2007',
+ accessDate: 'Wed Apr 25 01:51:49 PDT 2007'
+ },
+ 'bad48f8ab053804a02bec678db01baf24de35ef04a17b90e1362e67fa352e4a4': {
+ header: '####',
+ data: 'SXl3D4C5Yt81L/117xsHYjZxT/fANq09VZsMNAz3Gcn2+2gopG+1K0JFg/1Mbjt4EMbe5Or42zBlJPo5EAldAfWu4MoTkQzo/wKPzgOWlIi3A9QwZegw3yCuHvJv8iNcpjGfpY0OCzTZKNomTtwc75l+8FqgwPDW4wDkPG98275ERDR8mFSZfUAiQxlTnCbskFneUQ6hdN2gywkyJKuTEcrMkIpzwe9uqPaQg8GjUvvy162/LVaSQAVRIiTbW5URCD+hT5cKOkmFeBejHar8zR3SQQ+tIJlKERBwfE0sNR+RebSboYxWPECYPp0DMj30FnHbfYIVTgRCIlepy2hfis0+9C7dop0jK2nFREjcxSIqonF+juCrfJDt4cTlpn2SmcoMJQsUOedSh6ZoWweXm7lu8buCbA2Q6SY1L6jz7okwIikIinxGDq3qT1pWSgpntI8wvYZ8RD0umJsoAzPYH9zlfQ==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 02:01:21 PDT 2007',
+ updateDate: 'Wed Apr 25 02:01:21 PDT 2007',
+ accessDate: 'Wed Apr 25 02:01:21 PDT 2007'
+ },
+ 'c03d1fcf5b6981741f5d4787315534641c61daee9aa3c063540fbb704989ded6': {
+ header: '####',
+ data: 'sbn5IDJM7VtYov3sqW9+/0USxZEw2xq8di1XVPMMZ6kN6oZZrAY7ukxXHYh+mfuIa1/uV4i4v1YCaKZQShLgUS4cchlK4nnNVL8zejGwB+PaY0E8Um/Jg6E4UAFAZ+haZwzWLQS8lJ1r4hNMTeFqsDRUhC30awJRz8e0rBejLZiS2Hk/jgpH3i8Za1GwDzogw11iHXejYI7MaQGB0E9eQsYYTxGjmzcLfVYkd4AKj5pSEHvsKZklSuWIyDzwaFiIO7xqcJmS/8Wkm63JGNOW3nLR5Ao9V/2vthFHBqS2lQNRnkPWXbmNK3v7vi57zu461w1Nn1U/70EvhHRMk8BdML3XI/U6WgDARjQuVsB8FnTkzapaORG5vUd7nTtWjPdyQzOqacm2YKWpAiG6fUQTZiBusEd8jdnv8BioGUTbXgNVG23zcRbbbEdjKc1aizXHQE1LnROvoHZHkwg=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 01:59:57 PDT 2007',
+ updateDate: 'Wed Apr 25 01:59:57 PDT 2007',
+ accessDate: 'Wed Apr 25 01:59:57 PDT 2007'
+ },
+ 'dbc283f49de6e303c06a52725b8187f344ba7b433b0158d704f094edba782710': {
+ header: '####',
+ data: 'fbNrpIoYF+gpMUjSxoOc9Y68qRlE2yk7FPPkrHTu07HHWkAWy7H7nFw4BwGiFViMkyEC2orUrMeDYhKmMYFj8DEcALk6452BtNutGZSoqDhD8xnSEPF6fP2Xyy+vZHp4JWDXZt/xHk4vPbxcwTTlmRz5aO8ChXIH5iqfRL9+Dx+gJDKgKmCRMZYMT1pyOUewmsT6QDYdGFJTRRiDmoLfCVAXhJRtqQSBcx3kN3kuf8gyOMAeJnFGISTAj7THzo7eGuQol1omTMgGbDZoL7WJNfZIDamiT9TWwzp3UmQcKIsRvA2ZKtePWRmpWyq6WydJgFXHUuUDVpwT+kc1Rn9Wq2zwm1VBw6gqKCp6W9bZO86rRMs2CtuLT+agSpqb4kz4SEYDCW0+aUsJDCYBXx5yWRM26r0XAbU6X0D+xopGuaVzsV5G7chkCO8mUsjHzZCK7hOAz6OgjR2+',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 01:38:17 PDT 2007',
+ updateDate: 'Wed Apr 25 01:38:17 PDT 2007',
+ accessDate: 'Wed Apr 25 01:38:17 PDT 2007'
+ },
+ 'ec525dd942f72b71b5fa1aca0a36a9960b71608bb27f32bc7923713bde021b12': {
+ header: '####',
+ data: 'AHP4MFiGukFCCnjLDGoqJUDEr6QNL+KoZlcwOqJIYusRtl5qmhZSsODHbAEpmadxLGogDPrWoH5/XLZ85ASGRF5ALzDgrFKP47/bSEzKVTDABY5BJSqvKgS/lCf2LdR7+0HWUVJ6Z3GOb9GqsXC70pMxDo/RfclOQPa+k/sXCW5u0TmLb/0i/dZEM8N++4umXsyy2WPLtUVzQZ/VdTMDwl50FeQxu3aNGy4qYd4XFk/7gxBH9skBD6/GqpNajHJrcbi/WZt7PZiN9skoVZHhm3YLmteP5hJnrcCGBFJHWuQpXfB7NR8rNmd2c6maemKYmUlX25wQF7JPcROOcyT8iYpF4Hk/eSPs0CSkaDdqSD0Nj9E4kqZrHfVGMwBbDFyAzdHTN3EyGuC4cBXdfNZbdBqwghuB1x7RLXs/pbXg1xqukjRdPLTxUogPdaQBHGo=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 01:56:58 PDT 2007',
+ updateDate: 'Wed Apr 25 01:56:58 PDT 2007',
+ accessDate: 'Wed Apr 25 01:56:58 PDT 2007'
+ },
+ 'fda6581f0137dd641387a7be193b06edea4451835817bcda38d22ee24ebeb77c': {
+ header: '####',
+ data: 'QwDMobl0Kds+J8mknphumnONOIF9gH+pC/AJpxGmuy/rvKfHSeEuuWAZ/yWj8J/I4V7OjpyTs9/uCWeKs9khpdkcxtObB36IfcbWBHGOgFjvqKgwMa7eZSIUPZz9k1NsqJC9nU9U7w5EBzQKVIjJaey1EdhsggdtNOpQTzt7iu2mWKo33dJKQCQ5VEwhpGh6SH1TgKFbdMkOJJY8d5xPYUxR66LVFpFzgHP0ML5M5U53PK+apT95UIAlqf7N32BjPK63Nsj1WPsnuuL0vWA3KmefHzwKGeatTdsgck+1mwnCDJncPWv7hTwMLGPUaY+Yww3K3YPihuyCUtUdV3fer2VHVAn++JdzerHiLI/86T8gHiLAi/anFFh6i2kMMVxqzREh+62n34MrgdMqbSFQb0V4Dhm45FVJH43uuEaoe3OJPtyvj1HbcSR4VEVgGkDeced8aAK+Dg==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 01:58:33 PDT 2007',
+ updateDate: 'Wed Apr 25 01:58:33 PDT 2007',
+ accessDate: 'Wed Apr 25 01:58:33 PDT 2007'
+ }
+ }
+ },
+ 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:06:54 PDT 2007',
+ updateDate: 'Tue Apr 17 10:23:41 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:49 PDT 2009',
+ currentVersion: 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf',
+ versions: {
+ '12bd9887eb84b99ad40c1e413cccaa9ffd4deed340c71fe53610088faff349bd': {
+ header: '####',
+ data: 'MiAIw+S6GDmLLMcGtkl+wveV7dZAFrL1zGZh/FPvG4kpOBbnyaolRynNrL1yeUbEp4gLL2cK2BGYiVc9196PMOvKPHR5Rqp6GlT6h4RUJ+nFFF5/3LNGzQtJbiY0rrYKptqyPBC8mhlqtdK7sQkQonj5LPhKeCX6AyE3juBPEuFYhvTv9a/iRPub7BdlAocz+bb8ObpbVHnNvbGhiRpx9MpUg44JRxLQYhtDUMi2UFtURidKaK0k2lP81ckPDCgVgxy65FjCq05vSaCW0hanNrIwl+zAgi+3ChriqmflvsZYC7TQzUBPXrAQ8bKmzppZWlArIOppRF7+paWrHA3Qcz4uO5Sw3DvMwbgl+XINnmkE/EbA6VJOjrWYJjsibvbCw6vNr4q1A4Yxwy0a7EXbjFiwpEr+jMUhsq8+d0DxP3tQTusV0l9wcT2OWrDRKdjDUXLQOV9BVw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 09:27:40 PDT 2007',
+ updateDate: 'Wed Mar 14 09:27:40 PDT 2007',
+ accessDate: 'Wed Mar 14 11:00:21 PDT 2007'
+ },
+ '35af99615d1be9d9841b4a37488fde9aac291c73c8c3aaa570cd05b3fd0baf5d': {
+ header: '####',
+ data: 'lv0pIfnhZZ6ktahFGl3AgAfdcveIcUyAh9x0iVOCzmQ9VjelBztlvxZEo+uByaFh1ptM+eqOFT/Vk9IKhNjRWTXrDXioP7oZ8IZ1kLfk/XuMFH9AgYzm3H1T/yLq5lg1WqqZ+OfO9m37Z4kbTjK9+adIAJ3TwsMxIDpIHYz+qbznjJocubYCbi+DC+4wo6qu5C44gf8n5QF8DOCGaBCyamxFvkqrSMo/Y+3SG3yt98MSgeMScGESuwKKGDHZX0v3ZXvl4UFbxywUtdbipDv4PAlzh0aadMsGqYwO8bPKEUElCWBXd6kASugaqiJaZFtb02EnC+nncv33ZSx+WyJqwKIBk/Kpd3/YDJnX9t3QU60j0YKf0my9oX1746F5u0XGX1DNRaw/1g95zRHoMu6j2cSTTX7CJglzIlTU8kglSO1LOasxm3Gt8iT+8+Lhh4Dw86ugqHXl',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:09:07 PDT 2007',
+ updateDate: 'Wed Mar 14 08:09:07 PDT 2007',
+ accessDate: 'Wed Mar 14 08:39:40 PDT 2007'
+ },
+ '7cc6c6f2eccd8bdefddca21a59669655d7515f440b025144b9ba6b18472cf189': {
+ header: '####',
+ data: '3W8FqWzBVaEbMZRukwXcm03WbvITt8WVKKuJlcSszN0dCJEsIZ9vLAiDp6dfsFF4PEPcSkiy9Ww4FiBYSg5OLW6snRNdA7Wo62dJ3lqn8TjBzv/Rt+khf9mj/WwJZZ4wum+qdwTRPyaoZcAWgA6PAPPVp85iDBP8UBdiFOs+y5kz9GiB3psvOvqC9LZ/RyK3J+H7ierfWecnbqB9LT5Yuhfi8SO/gw+5vve6z1v8sVcexI0o8gk97rDV1W2gZz2WNtO7K5+233Z7aZlzouEbDZEOGG+zEYh6SctWCspgUATElf8vZ29fABsk3uZQO2tnBvINChs6jCRxnbmnjb2Y9R8u2QRtHjjvRro9E+zhQf3laJc0G0ZJp1zN0wwKx+sL7uM6kG1aszNJkzpykR/Uz8bKvoOfG9vkz9+4Pczh5xR+k9rCE8nbu6Yt4EMiUfdfjZJHAhST',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 11:01:05 PDT 2007',
+ updateDate: 'Wed Mar 14 11:01:05 PDT 2007',
+ accessDate: 'Tue Apr 17 10:20:33 PDT 2007'
+ },
+ '95ef5754f9a4514e5bf883436d60c38c3cbb15c3f5452d512a05839ce20125ca': {
+ header: '####',
+ data: 'Rko0V7wG9GEmH9pZtXSfxKGDLRhZr65ef/DjkwhsPoYfLryET/ViMjcZcM2blyiLKOxjiS/avGGcXUmInz2AyD5dAFTGge3qAZ3QtxTcNn/fvfJeN+JyGJPIsTIQ7P+jd0uJAb3vPuymISGJluTsP0MZ8zxahSSRUV/VIYwm10tiMVvWEq0+8FynKfWDqJ1eU4pnI47CAdN9CuWhxi12RkMBYgiUzNzTh/tbPTFMc7DIyRfR+si6TuPS3PmtnKt4FMFAX3FznGBCNsonUFf/n7Zy+EYEU/B8wJO+18mqbui5YvmPCPPKiW/pfVuaWarF7zcIcthYoKQfTaCaulO0VRtTA+Wg2LtJv+QcWWWTiY2A9FC/PppLZ8+nFDeng6LqJYKoGnn6qwtSVH38s3Inzbs4r8mSOR099tqwfCnZc9zZHisdIbVm82H3gnqelPmc3IXb3nHb',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 09:17:20 PDT 2007',
+ updateDate: 'Wed Mar 14 09:17:20 PDT 2007',
+ accessDate: 'Wed Mar 14 09:22:06 PDT 2007'
+ },
+ 'cc7ee01d38e4f1de010d2a235e3b76e838ca05fe70223b8358a5e41975bf2b7b': {
+ header: '####',
+ data: 'TJ5ClYK5JmZvEuNCA+/UeUJQ2rGXbPnFqWP31GAGXqhZmC0RuDNjl3sv0nFKmcdMa/BzvLSywJhkidoRhfKGwN8nZc8M0VpujFkpvdXgNsod6x+5LTMP67qCyvD67pkYMa7O+aosKi/ZWWnYBavZSdhyuWnU1wPxxk+wwcjjIrA5Tm5zTXM/68nLLnIWs2bQbUtcwHgLrBEUshG5oTUFGxrs8zYwodsYUuT1CVwODZrzMxvvbHfH6Lqt94m4hBF0oIrDCd1cSaXghS4PiZkJWQVxJNSsuYF/4PlPrV4ATZS3Jm+DqOxLOOnU2Xu1Qe9DxBppnXjs/WpohYuMV5YeD8iOJLXTQbFKhBJNSCoLp73QywWazuKkasC6cbBrTHYykEKXpt74iE6oKg67YrPkIZJ/jKEGnZ7wsY4ObeDTS7OUbHKxPHRM3ZrmB672R/8ktglg',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:06:54 PDT 2007',
+ updateDate: 'Wed Mar 14 08:06:54 PDT 2007',
+ accessDate: 'Wed Mar 14 08:06:54 PDT 2007'
+ },
+ 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf': {
+ header: '####',
+ data: 'CiJDd/ShGw3rE0xCNZspkdH6hRzvSyaNiuQeMBI0NR1MReaa9uVMV6Ymj+BWVQ8FaOziQ94aolsWre51EKwDWC1otdovPXWHxBXBBI/Y5A4dyQisBeR5E456juUwDtLKX5En4iIuOL14IGt+keUtb5JyfBGuTTA+EnohYzvDxu9MDh/7nzCcWzUxh2zHEBSyowfOwJhx7G2xEvbBgTg+TkejMudbq9k3Owebe9QNdhU9rsY1UMxjL8+HgJmgyo0C0SA91tZXBB3i5ePvg++ze/SW/r+XO/nnVzcEwCJE2UWAL+vNh8tUm+sEbWaqyKwjHNSquxV4cYOG2Lzo45Wp/vZwiUR/8MK9THf0FO1mn3QCd/37AMMneI1Gqk0TNwNtoQKgLVBNhhgX7dIVpRxB2iiSBYyUK6N9LlFahW2QVDS7kdnKH3vk1cP50dj21E45jEhhd75v',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 10:23:41 PDT 2007',
+ updateDate: 'Tue Apr 17 10:23:41 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:49 PDT 2009'
+ },
+ 'd65b23008b22e5000726db3fd22b074b08553fe82245c3526f708b8d89f70963': {
+ header: '####',
+ data: '0y9WhoXwZSfzfxuql8LBc5/RiclPKQxcBYjcdGv7v6B+WuGrB6uu6d8pjNoUtsZnFv/25sefW3ggVgDuI5iZNg2lBQVIwgcvK5jPM5foit49d3RSWl74XdHY2XqykRNDbboKAiNfro+abo/YYQXjkhNBOC0dWSUUw+HmgK/Bm5NmJD4fDTV7OYFsvX4ExjnX9pktaB6aiLZWN1cZruW3Lsszx/ryHpDtcPrmK2hgLQ4FjRSXunbqXKJLOADQiMbGZ8DKZchB5NcEWlE3AfL6ybJzTyr4jXuS7A9PyitxYNKFHAHpJEhxGkyuhUE66QMt1n9NKzkNx6yhhGdIUF2zVGsBUb/pRrL2gt0X2lsZ+CnWFu4jRAeSi3KfK4VrvnoYkVlJImxPiLrzJAvqkuA6TyQRpJ4yFVJ0dgxBoxZVSN1fp9Yvkph+Os8LZscJtpYPPwVDlCnC',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 10:22:08 PDT 2007',
+ updateDate: 'Tue Apr 17 10:22:08 PDT 2007',
+ accessDate: 'Tue Apr 17 10:22:08 PDT 2007'
+ }
+ }
+ },
+ 'd620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045': {
+ data: '+iiHiN91FfHKOXC8Z/tg+YynPECa5sgYGGofcoJeXt3FAAkAFu3NsLuwjYIaddJiB3MIxFccrCrB5eDDL0SzOS+j63GcoMCeeiXss9YfVunA4RQTTktiU1BknPYfsfHj8EOPDSVHkPFs7KhAnBlgyaDiQPjYko5Np1H2i7F7pRmfC8W5LGdisaqxFDa+1ghu8K6a54QIpbfOmolQU3w7T5qiOdoZv8GLDDoORvMMb4P09IzXpk/yDEZe1GJ4g1a9t+lHAhiKSvdnZf+MhK0jvs6R6ALlmO84lRP34DmT/35Fr5C7D6EJl0OxXkWgYWelTlfU4b8+SStYP5LPYeD38fodSmObpKmpp653T1v2yaTybI1hojgLbH2DuA5VcQAM5JHMjoSy6s76mf2AZZeRnej1dqdvIOTf1Q6CR+ZNIqnkukrtGq/6elF3eZZh1Ln1EZDiTzsMxUHBngtiRmRDofqRSJUGbEAjw90dBoiaIO/WwLAy4cTec0nJxwYd5M7nchEly8Cb+zz7naP+vEGEAWq991u9NFZhrw7WgNgHnG0E3km+X+SYvv0i2MkqjYs6ItDkBNyi0Udnc4CqfWuKa9q04t8mZiy49LU34Ho4/ijuez3rdOeCO/oIwkRkLZYfFO6IxO56tAI3d6iJqmXY+DX0YUZrJ6FT7bDsUj0umV1htuj/uEgQZyOnKOyA8cSjOTMRIkodI12HrtdrIA966BDznsKW4F7f31VaSxI5ezHsdiYEsTqwaZlFQMsjfZX62EvDLJksJTe3JG15BNgsDUUh1mqIDCmVswFTpUTTb+50ap56c/uERSET0iXP8mb4hKwJkmngrBEir3btuMEMS0xSFQ2jTRjlnWRQr9eZT2biarzgEhKHyu2qCUtsUj7TiieQJY09EXCP3g3Da+61nBMoAwi/VqTI6vQaLGtuDrA2+VYGc8x1SiahmAkRPpQS+5N9qPvxxFRbKforMOvmeboFVxdKesub7BHIXQsSOKsHFZnFHswa/oLBITomp3ewfp125RjBUf1C3hMBNg/tmE5pgLqPfQqWK7IOnfdyt0jc391XWb6H3CVcgC8DcPKJ68o7DBucg9xTNwlIxBTafupsBa9JUkBigqYOW8729lNjj/QTvTUaCxWub9SDT6/y1wQUI1wyyg+EaR0fHqumMhIMbuvIPd/SvKMmZ4TXtBc1U3H3IGbkqIfx0f5rI6AuNMD7/pXTAy2Ot1ZBohnQmEotXRvDwxPMqBvPU74t3USTrysyXfJqeFtHi8GTR5X0m/PYQKWCCHgKvjw3d1CJk7tTe3iV2ulk5cnO7tOydTMJFgPuT2oyDDDTp5jYJPRE0OzZcpAzvRSjELfJ111sFBOEzTqtBUHA/E4BnTIM13md0ZaMr33E7ii8rS7vaKrQAI5moonAtAEOVbx/ZrcZ3kGzHpRCISeteHgnM4I90x391HqDkc1A7b+iDQF8OY0H/0as/3gaVaqs5jsuhIByj0+KmoXsdq3ZBhEQRW151QDCdMKdulNUxbKTYV/t92z3slU6lO8fiy+ON/6sTtS6jgnM+oCLxTfpfBdz0uKG7jiSOyunj27QxNjLyu1nF2+mAcDhtMN18QkJGLXKYv39kx7ny1H74i5rba32/QEAFl5eLJNIQbJZfZG3HzKMVS19ZGwgsYNqV1G52x5+bZUTR8YcrLWmPTJ322UxlhTmyjQv+fVCnpksBtjLGntsGloemFF5YVlcl1AfyHb+KlXiAZn+8vpfVVBddFFMeehokzYE1G8Doa/3huhqdtC9qvAtpP54G2p3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:36:20 PDT 2007',
+ updateDate: 'Mon Jul 09 06:10:15 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:17 PDT 2009',
+ currentVersion: '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130',
+ versions: {
+ '0bea892da673bf4b3d3e4e97cd3e1645eb177a8423dc761583b876c5ffb1e2ca': {
+ header: '####',
+ data: 'BmZz8j6Khuz7Q11xPA5zSECcqn7BOcMtLx8AmX2iE4OrIwKWcZ+u4B5kCBxtFPRZWLdWcxAF8VfaedkHx5jxPNeWNIa7NEXXcFLYQv9lwUaxmtqodYtVapAg7N+onw28UnV1vB/h7ll26u263jWYohtd5eMnXhEjIEbrQYpf84jQYlpMKjUDhsVQeZvTI/KfiXa6O38ygO9R+xlq8xKgPPX2bkXfPJiyzlA+GoLSORc0tdqseGGOK4BFyp1V/KRUQ/7uQmGs1yNWt/ijaQtJXpWkWXmjHyTjXsi0z+1s0KH8TwSOfu8yjVshMyIyEDd+EsmZeK0QwMCm96v311cRhMgAkQOqL8xc2uRpGygtTkV2frthF237GOV5vwO9IoMZQFlvKZreV5mPPPBeqfP+o4QRpdnJRRCaP8Ds/MmzGBqE13ntwmo1UVX1k408ZtMCO7h1eQVTgCZ/Y2RD',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:51:02 PDT 2007',
+ updateDate: 'Wed Mar 14 08:51:02 PDT 2007',
+ accessDate: 'Wed Mar 14 08:51:02 PDT 2007'
+ },
+ '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130': {
+ header: '####',
+ data: '++u0MEaILPK8riF0UzCnb+MnC51GYcdqCFRKOP7XYt5QvzWtxhDMOvq8ugCDF8G9sYPAoBLiCxFcuCtnkG4fp563VeEeC/dRnArzMDvjILYKAETgpnLQAfyIR+D8RfUkCbr+aOJ4XEKcy9a240OQJFDT0whoTKuX/6XVzVM/D7F0r+hJiOD1ELsVEi/+U+dXXO/VDxoyjFxfa1+M+Ygk8ewecX4nVqwOiFWHNK2lXW90inip0p8yqDsADx0KhE2tjARWVsjoNdf5RSUOYr0Sb0syyjBMi7oF4jpbLvHpu9fe8vpIcve+aSA/MF0Acxh0/gToDcO8ER3K4wcJgNPIs9lXiSrmuklK7kmS+uhz/rWCtZZH/OB/ov5sez5H51EYLmSNQbx5wZGZhtJWNN+AkJobg/Nt4XKRTe98CutbeiiYUGPxQvwG431Erg4y/q216n55FmCBIHZcUsa6Hk7ezF66c52EuAnVEkn7TZLl7vvym+sv9lKev31xpAGwX5Gy0tx2A7cSE55ZoyqOS9kf1s5Kwprx6RSBzfy7sffLSWHxyOSBnd7B1MNZglVSsbB1r4gMgZdYG//MZ/3IhTFbUqqw2xXHzTvBPA2Hl96g5Xzx0dVx2wHWcPcTSH23VrLscQCwyiDVINwmIzyG4CVSW/6gzA5VM4QYOrUDX2ZA5ligkZpWs0HTqmCB4SoqYJUpafaF2sEtCWHUjuVdw+rQiTBCcRTr8f1Vah2q2xbXMedLCRS3Vq4vlT0a/3wGgVD05CsAom31ZzmHQm94hZrx3FTPenhxLtTOHtDYXnbzYWufWEBSJs6VNtG9F5Md63NZvzEZiggfxTREDRZ7I9MBOPhrxz/3tAo+xInwvLXOEnTNOHVATm9u50kDs1qkJgqiXlxi9pZKmrTu4BeXS8cOxJ8O+Yb0Nh9bExfw+CC8X5xiWE58OwalxY2qlvuoR6mOqdcd+L7YPbGq+hJ/7WgJlrvtQe8IjGF1sJg6jfO8ZeGaPMF5NnbQVxGAq39g00on/z6dW0BLZyA6uglv99si8aRLpMk=',
+ version: '0.2',
+ creationDate: 'Mon Jul 09 06:10:15 PDT 2007',
+ updateDate: 'Mon Jul 09 06:10:15 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:17 PDT 2009'
+ },
+ '63760358c7f5783d11fd769c78ca3f1ce787113368743655ade89bfa67d0d30a': {
+ header: '####',
+ data: '7lG/UvX5KjLbN+OrHbDeqXmweYeOL+0p3/UoLi2K93mCYdwsvx8mg+zghxwg5ITKPiZ9D/QWIShqiPpl+dvQJGWgs9EcP5W7k32CS2RNFaZ7U820rSpahHP561HDcBU1++5wHWszLnqFFiCuDja3OU90dsCTLI3g0igFgqpaRbjLcRTddI/1N48xNfV1YieC5Kei+jZ34zzrfKRn1f0F7mTkCqCSfygjnpRBgZyo9BfJ9rHULBvplvpslUUfFTShkLnCx0UbWPXog7DIZUCOwvPr3KJvmcZtCJp/1nW7gm0E5PaueJF10+ZlB6pKvueu+5yEgVmVu/lctmPX/UwTYZDgY5VWSWS3C+JNAvV87ZQKKmp8N6aMFMNOLCsOYL5hFN9uWGtMmvtgawqt7OhO9HukSUs8pDTgNeXoWyrorLM0cH2fa6a78GxNs3nCSUmqSQchJf5eWmASZgvI5xXmHXsNbuc4w5R9BaEPzyrrSAIa6r9D3rpFbUhMm+qPv9pZE2HF9liJVdWCBOSF8ZfCjsq5suyYz+YCsFHnwwpYmKAqJNXUMIhxkjgOTi5lNIsvS/iNSN9kdkeWINZk5iQFta34uJbGgjUhRy930ZGMBEV36T+Vb5tz50M6/MnlzAoUDeZAu54btKcrIpIq1Se+8zldwd6UKGq5nG+dMPk7CyKfZ5LkM065KGbgEJfHO651AMWp1sMAsbIAM6h1gVKbRjNyNwO+UK8eDpIX1nXHVj8bDVh96160cFbZj7htsUnXZh2AWuY6ahwdrGwYeSFoVAnd6xUF2oH+zFz2coLmLjD4Xm9IuQFsFO0U1Vo7EKUJHkPgIsXUT9He9tl8/K7UYQMXGgPTpercQFQ1ctFEqlPbFoVNO0j7Z9lmeSBcLdvY67CCbsoBDVJzj/wLRdBQStfeSUe7bEI6ff8+0gVkEFFACc48fWWA6NLLtvJkYjdojjA+C/Xf6EGNeXU/VENMJokB10EJUTueVWKHCLGI/JDBQBBB3HKX2VNFcEMJxES7Gfcbhysm5bdmltyRUJAIdXvw',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 04:56:43 PDT 2007',
+ updateDate: 'Wed Mar 21 04:56:43 PDT 2007',
+ accessDate: 'Wed Apr 25 00:59:58 PDT 2007'
+ },
+ '6e0dbb3c582039d985e80e10d94f424a63f0cb5b2ffac6388fd806ef89c1da40': {
+ header: '####',
+ data: 'f5hBUeedsvb1VBTpmpQ+XgGbnuVDMVEAdbEN7ZLK5k++4Iuw7l52zX6AHCWUFMDRfT6joiD2DMj0O8B2g55SeOQIAtZb4PZnbf3+ZEqKMOOI7iYSfo2PctLbzzzztma8EUXYkg7sJKCuZuyXhkWZxikBqVQIp9WE/bhRxa/atnB0jJyttnDMdTAN8kxIizrHFfT25hSbcPI1cSzsmF2nLabO6hLlm7mdLZCOD6DSv9hMeOXgqXo7XdfLA4k8swnOA/85HZFmhaYjTyoDGsK8yoJny/xBbiaRij1HQcHkbG6k2QKcs96pjmiJPoCv2dmsU3Bh06l1O4OEXl/RL4qBGJBKsDW/TXy7Qqa5y6LCEnlFAfefTHVgzuEQjJ2qb/z//oIrmujt+8hEa8F7Jyn6+FGqMNRxDvIQn5Ty/CPUStS1lNL1PEb7TA3ChYkYvnuhNVq8HHf47neGMpUwC5ppk5Zzb/5zEP0XH4XXkNbR5/TYjcb0Df3egNLSQLdO13CO3mKeoccmtfcmaFCtOLXWc2xNNcu09s+/QlZMuiu1TAzhWXU2CAXT7K794mTXHXjgGEaEe86Pj1nO1zHN7QhKDN92WMEdYasRAVDu/XYdzpsKJZ3POhNJp6pynotVBOkPk+2g04S8uujLVSIPZIwu7p3RmPQGGvfMviswhyPvSsPqND77j5msYOLCnXXjeXhOe0E7fIRpxPK1F6/N0R4tZCYNJe9Zo248XdqBvl5ZQWDC6aQH1E4djPK/08CS7/kAECqGqOCDPRvvMUNkGOnxsMx5eofr1YR7zWOZajr2GnfhA9fjrLv6KxXPVU0z702aS/Mfnf87ckGpOKA8/ssJiyZ4fzP6uN4pEb6wEta2DnnacUDd96nMvB9HvGCDoYZH646+n4oev+AnkYTy+ZRpmnsG6/3Z85iH3RwN6P2I3DWvGuN2e+1zQ2kaBMDms8qeXVY1+8qWr75ihizHCJr6E8Rd2Sw7xM0+6mKpu6gVGIi09auHg1+6Q6PlCr8Hy/pc4Exj9Hx1m14WKSF2SB1SYOnm',
+ version: '0.2',
+ creationDate: 'Sat May 19 02:26:44 PDT 2007',
+ updateDate: 'Sat May 19 02:26:44 PDT 2007',
+ accessDate: 'Mon Jul 09 06:08:39 PDT 2007'
+ },
+ '84f3b8571428014d04d7c05528af73c89cedf17e23b1f9541fe7060512f4c1a3': {
+ header: '####',
+ data: '2/zsq97zQBq8wE0oAC15HW5pbbzgokoDkLSEGniP1VL+sW3b+tXYOQV+VSFJo8ERNlCSoy679G7N8tPKgA+rO2/roGP/iKEuE38et9R6v9nhCPfo1vKt7XpvzJYow/qDwdStylXbfW9QN12Yx12r/nkPldVTXCYQDF0Vs0h/I1XMjbILpq1smbNXAUdn9I3W9o8KpREvac2H1ir2vYOzq9Ubhq4jggX/9s+FGm40f5MX/OM+lJGdRPCMG3rfWVeFeWEGWpmg0AXpV7eEuKH7sPrWy+QLXD1IwNE03QLhuOh0qEPsEi6kcCaZyLlCHYlzJ/hIAR1CBlCtGm+vqD+WRr0mGQtl81MMl6/BoW40dya/6aIKNOWfmYNgdfplknkVqxFsJnwVqjQJWfCzbW1KqBvMHx/7oPNjbMS0KKhd8ctOsTLSvq4zFI+mvR6BggwT8rwcfa66shJIaDDC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:38:54 PDT 2007',
+ updateDate: 'Wed Mar 14 08:38:54 PDT 2007',
+ accessDate: 'Wed Mar 14 08:38:54 PDT 2007'
+ },
+ 'a4218c7ece0287ebad7f3cdd6510f424245a4d7d42ceb083b664a4335bcb7690': {
+ header: '####',
+ data: 'hQ123ZhZ4AiXD25P/0Laq3MtRO2oSIrY+GoYe3UAiyEHc9HZDCvR+POEEaARXNyh+U6z8S12P1GvQbzo23ZCt5byhqC+UmbfF3Y4FikM7WmHaRPtWjv8JNf3X0iJ9a2IBLA1BlqgJolnVDtrLsFx+6rBIU9r8pI2jdcsw9w9feRbE9/0S0filh66azojT5RM1qLcIUVWGixROY6PALSnA9PCjA6IG5WUa/DX7DyRrosZ9V4ZheMlzlz8CgEKBTN/HREIbPrEocBOvmnbupIEpOvH3OXKDXf39KAGVBAU2IIkOrGyWfT12p9dK+Zf+MQUl4DDIdAbF81Lus+LQmqtQ1ieyV0nNiqFhPuglLvKRj7QZRFfHNyejkMTZQWjQhBdHRmfSxyEgmFrM17yVVz4cMis/44g3szHMgAAfFIc79wq09oNDEV+ZUMS2xyBCALjRmhedqYIMGRCAG15',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:36:20 PDT 2007',
+ updateDate: 'Wed Mar 14 08:36:20 PDT 2007',
+ accessDate: 'Wed Mar 14 08:38:12 PDT 2007'
+ },
+ 'c6613ccf0c1c6b65798c6f35657a10d4c6033aa32204a90d9d0274783a1098ed': {
+ header: '####',
+ data: 'ATU61Uq3Fe24JAEauMRtY8vMjzaQcPtnt1fshTD4dGuptFH9XoZ4bMC4XKHI7JKbx1NUEbR2ySOj9K/NJuWEGZjRgZbNI/KtuxNedlm/7jEpHQx4ZfhXQ8OiUDd+2bB9g6V0Ck2T1gM4IyaZMJ1QfOlYmGGv8n4flhHC5kUzL2OIiAxNHvKQjdEOccnEsk25Gg6FveKHD6NqVunsiCqhxJ84VBNzHJscuCTRcbt6KwR1+dw7Y+nhTjdDFq9UidlxTO0BKYsqj9F4Kq1LXORkSyab7zKooFH5kNd8torb5UFto8dfI8/+DOVHMxNRh2aWSn3O9bzwi1PfYO1nky2O6OKR48Y65Hp1sm3Xj4AAVHWSGakYUSV5M5XxKKzvoKY6Qqhz8GhbkzM2FC0IKTEcmINMvzXdzKRTqBFg6i0t7Qo80i3sQSoju3/4CYRozI2RrF8W4f3/0XgJf21oUAdTXOmSePSZoqhdejXeNQAgb89v+ZextxA6NJNYqvrx1NjdKmWKJIU+o3AgPYj4UIwWHwVADHITKrIWl/SbOsGP5aERtSiLnC+xqfRUOpgfkAYLcytspouHxvQjgNY4I1U/2S1DThG/N2EzuPl7GLYQ+Y3RAvLObFbrV8S3DS6vXIkigxyJT++MotIKoPBq0xDq0ck6joyvwvg4jXUMKlJa8/LQewJlbH8Lszx7SwjynzEQUJcpCnmxixzSNfRzpzgEBQSiClEEqArYykew3rjz9lc9nkdXUCzz81WYsvk6rGJ6ZdDsfKsG9+kaybuLL8huE0ERhznKDJW44ehDGQLr0phO3CI8n/9Px0PhPeZ1hvoiiH8CFSW5f45ZrFaaQG8hNyzWCpCFoX0/dNsNPsAkOJnO4v0PvO0HDOif1JjgPjCS51vBzxu8gYhkWlPo2hZxHhnnrbhxeBUU9jhLAx+NmxxfTjIWkbtHtVjm3ea/D2nuL1YrZKmQ3Qs6GamKlh3WwkRWRAVU3+/mbSGOISxo0u5v8QSmh/IPIXltniaQgWweqGNnCLWluuTyhoqnqDo0II7q',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 01:04:29 PDT 2007',
+ updateDate: 'Wed Apr 25 01:04:29 PDT 2007',
+ accessDate: 'Sat May 19 02:22:01 PDT 2007'
+ },
+ 'dd2b4cdeaedfc97c384f79c2878fca9a981efde6ebe212138db235e51b80c64a': {
+ header: '####',
+ data: 'd7ZpqQ4CTF00+/UnTvNnnkMXB2Ow/K9dys8V09Nedq4sgMUk08E1vqi9mdWbzNfRD7aV3blru8PfoRrxXRLTG/bjQ6xncecQoAJeUtSplKEO8fhuzGqbMqz47/y3aQDHBbygMAGV3wLgJO2Pv8p+8U/P3cEJisd9OqTNE+EYQz4eiq9dllMNUQjDY9aLHE8H0ny/5r9uohGNjXX/LfFMshjeS4rToCG5mzRaJPaRs1jkjzSntpF0RLxfU1acpJX4pNSuaLscdJ1lIwc17vygg6f3xexqvCeeFZBot1RwwbztZKbMfap4pRF5KoftD9bXJwoFMXigeMGLy0scpzsp1s8zBIwLhwUxEE0IBh7qeStg/3eRSW9slazuIR452O3Rysb+n/jWMyAhIOCSrnncjjH4XHbzV5GgT2d4f8jfBPmOT7l7C1ev41D3FGFxEb5TZGcJTaIW6ofLi5T5',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:52:12 PDT 2007',
+ updateDate: 'Wed Mar 14 08:52:12 PDT 2007',
+ accessDate: 'Wed Mar 21 04:16:29 PDT 2007'
+ }
+ }
+ },
+ 'de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4': {
+ data: 'ZYvHAVCnw96hB+0XxnBY6p+vwvup1BopHUeepu7yOOSdYNFFOFEvtCbxXXoyVaKZAeSd2Vd7YEwRP4TTJjjWNPapT0D65AFqM8x+0rEjhmVfQGZAS4L3QctzRAgBoR1qTr0iqI/46ETkNq6vHz9mPLHEL3MQ/zoh4Pp0T+uMsY5ptzuMPcG0YwajSm5J8XXV2V5ZBEANpgL91xjgh1I9LiKJa/Lv3R9HAZG1uuCvzqjA2LWYeH+6ZcSpadk/UPxDw9c78FUnSNbHAcjuYZ/yI3v5SaZTjEzsB1MtAh6AFiHtvKIMWpqoOs7XQPhz1xXPoGZ7VR64A+/bN2h+Uqn49bQrKjTRGegqkEWFcBwhFH/ZkYfSHCGmZQTVqOakqyofJ22tS0ief45gYaO54YvIliTNTY7SZMRCEhUzz6dz8ENqP7FxhUVcQRbBr0JTmaf6DAwu86iDgkvcp1cY2trnUmlvrgz2GW6TgXoFjFlchUkHIByFeIJ02olfJg4zP8PzgYp2zhwmXL8iXHXnwzuP9bQKq5j8o+UhR11zn4MFvWQyD1UEplK6vphMdS8iXDViLrOwuMz1XUf7RxNdW0gqXwx+qLU+CeypyWLMIlgTlOr1pBqD/S5Jx+Gbn5GHQViuFZHJUjJsU0xel001KjB2Wf1Y15OSdLZ5l0tn/4HYKmZLufTYpub0xrss5r3Z72RYz3wvAWFXzkxWa+oBiRQiF6+ix8DBPTc3tm+ORnQBYcV/VNVRziimV3MFSsD1nHgIF1zu+eXIKE7/b3lzY19KpvtiBio94dejWoA/WO7KXWv2sHH0JoZnRh6lzu0HRFgYqVm/052nCGVA6XSfrFtfIupxdBs22C9wrwC5/Rwanf1S8BQIXpm25P4dv9Y9cS6c2/DUHcle4tsUJlqC+LpRGKXRdolFkiL9r01V09Kev/K2oXaWGYmBLbRfIyvEHyHNeNXv5fnaZ3pTlIwXjJ9K9yKA/1AKAsAEuKlM3N5ep9pfyuyfOWj1I6RvBwVqKvcBZtYJ4u8n9jrxiyq3ZZ35eB62D+ceOAD2s5+LL2IylYjiJA1OO2qpu4x9rt1NHXM6LYJAruBnUrJ0Ylqz/ElcJn/lXAzY6RLqVcZ+tuV580AUkFiaXFEDcqdJbbzh0R15g9DtaeiQZd1PG0a8Xblj9aMQoRDRJeksw1GWO7TfrJX1Cu4k+sgARWRzZ0DvB0SJAxPcmhg2iBByn2ESlcxPvMOpzuJI11BUQsZZ7dcynubeMvdqBeKsC6HMcm+8DLEUPmzsC3HIfARlNbt1fOrGJNuKaLvF1AAdwllELoPf3lQ6EVZI120=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:20:58 PDT 2007',
+ updateDate: 'Wed Mar 14 08:47:01 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:38 PDT 2009',
+ currentVersion: '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28',
+ versions: {
+ '201725aba7b4dd93531e40ee08eb8156e3aecd3db4f11e54d4d88ed5508c72a2': {
+ header: '####',
+ data: '4ndloDtoW1Mhat41ZlW+nN+WkdEriCn/z/oclyBFQSljJRlMwUFvzE/OCVYc2fQx1D1GBedY/O13v+SCAiJXUrr0dgrMDOfmYy7ZtNo0hYshjaYQucJovt7UQLeFAuLO6rNK9CrsYA/AWoiT878z2iCYCqVq41sL8juCm9n+d9aR0eyjXAKj8QJzVz/uvdudoGQ5xL18x2yUZnemY5gQklYlm0u9zzCJ3rLOENnnAggFnSJ0oysNjB2UwQY6P53bqXzF8E+u6Rv3OoIbmCIZMaoK1G5ivnWHwhLzp9UVdIj8ipfLsTJnGMk+aZ3nnEJ7wQCaaLy/lY2RYmSeUTTZt2ImK4ZLrSxRC21QkD+juyIiaEBJdhP8UOfcqE8Hw+etc/Cl0QgBtv9AgXD4BiZs3HUTXsV/PhIzP+6TGyr3/A2kt8dv33V7Gh2Ba+28wtsG/+HwCMk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:45:40 PDT 2007',
+ updateDate: 'Wed Mar 14 08:45:40 PDT 2007',
+ accessDate: 'Wed Mar 14 08:45:40 PDT 2007'
+ },
+ '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28': {
+ header: '####',
+ data: 'eSAwxBi9CLckMV3o9PxBjVZZ47g2AOIsbPt8QMPta7U+6KKUm58cXHV7BDfRkbin3JYQJGYfu4HYHmayGt4IcX4RD3riftxnG3UFNqG4LQQ8+fwA3xTMBisnUSq0JYc/PKdBKzxH9x8moSqZC/cgFWe90p0PxdY13otjd1qvDL2ALAgY/uEDboTcLTbSEhpGIYQHtQ1ZjDG+KXI8J7atuMvS0KFreNUm9+uMZT0yCXwNpGy+ez2+ZDXTEjZUKaFPLI7g/vyySn6VMXmlqJftGXZ+fW5UWGaxb7WFa1hh/nI2okPuRlUQh50xXQJXVvanw1ATJbN1PRfYEfvQKLlAAwYuoB/qL0y0vU+3OktAbgBvwt9prs3IsqjwMeaejVTo3Yj9pQPJ14a+6lxQZQRFUaLePIPdYvq9NRM7chkNYminW0JN6umi6bvJ4KKTyjAglBQ6X4s=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:47:01 PDT 2007',
+ updateDate: 'Wed Mar 14 08:47:01 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:38 PDT 2009'
+ },
+ 'c7398bb27021058c9965a332d678b0070287b8ad12694bc8732346e6d84fe9a9': {
+ header: '####',
+ data: 'L+wk8k9ejeUeVz0offdItFpy8drMl1hi0FODBMKlPIAmEcNjnHU/IktOlyLrK0YHj66DaplXw2EyRkJNcMIbfACUtavxhWBH9VTftOPepsbsrU19aP6Xk7R1pr1sC76w1TgKCjE6IyBnK5qk1oHqcGv71GJLMmiqGivKyYOXQ45SH9tbHC4GUrg0YxoAYRwXqg+SlwRHpSZkX55NzPCEZn9eatGKCznTZs7pg0uBoM546fOIEBMgGndNk6gnsAH7At8yYxDMnkGHUctsSExL1O+W3bDDDx7D3uPkkjtd9se0exPru0fmsfcKPrcRkx8b8MAdgcylOtMdYvSudPdR6foSIqKMqktH35QlH6Rr5E/ire3O632QlmCieKDoPk/cB/qL3gKedxT1NxtC7SNR3aumKBAKOBDTVSjWWq3sIImQPZz+RUdRajeqkryNDVVPLFyjdC0=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:20:58 PDT 2007',
+ updateDate: 'Wed Mar 14 08:20:58 PDT 2007',
+ accessDate: 'Wed Mar 14 08:43:46 PDT 2007'
+ }
+ }
+ },
+ 'eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 05:35:58 PDT 2007',
+ updateDate: 'Thu May 10 06:01:21 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:31 PDT 2009',
+ currentVersion: 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec',
+ versions: {
+ '157b5933272bb6b8a70bbabb7fa0369eb2660f7f0848dcc653f592f5afd4f2a4': {
+ header: '####',
+ data: 'z8BUTeAbrs5GeJ+SxaV9ceaAoqxtW/touC8xhjkEqbG6+IgMrfuz6ABRn+vwiN1/Vmfw/tyad4kB2SyzKgaYPH7rXyBir1mzJi73/oHsXv5wWNhEePmjZginGGcWQ0P4AnrAoxlaI8tXo3fbsz8e40x1b56N5J6zIdvX3eewgIMU+J+iomZVPDQq5DNu0aGUL1xs797FNm4vLQbVRF+mzrZlT4XZNzOr/W/Br4vG/Ureoq1QRjAjj+8HRt7ojmzrpDX3RtmSbWqUPQqx/KpFGqVUNw0zs09MomVIYilRawe/zegW2KZKK4rmqoUm+mnWQTf/I31FYO2N8dLrI7OV71EWlVN4FSO2A7NRUd92uVxHzItMQPS3CSQ57FYAC+WhJh7k+/ikJumVSf18pZRSRaEeKPxbJZFJqrWsWk+SsqBIJ4EklAnBBU7zLmMVe3GO/ml3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 05:35:58 PDT 2007',
+ updateDate: 'Wed Mar 14 05:35:58 PDT 2007',
+ accessDate: 'Wed Mar 14 05:35:58 PDT 2007'
+ },
+ '1835468626573e6189e5302f6f354628f49900efe08adc931990d1c11fd522ef': {
+ header: '####',
+ data: 'Bv0je7USknogpb1ng86CEx6GbHlysuN3e5Iy43kg1iN83AgRm0Hp6/yMivQe/mEmQb+67cjHfKKrznAESYzY8uv3b+ystxoIaQL7tKJ5HYu2NUVvZxRC+PE7AkBhc+O28OzpZEHXXz62uZFsjRDw2hC/KP1XfYW+Deuulnpz6sgjuyWIYXF2486DzaycCqX0NmYXKE7oXAthOlbo+Zsm8Y5MWh5ploJFrzhAm0CCzjsGSa7NBOBWU2o6vN0NFMcOG2pdjZGWpWo1QQ5G9tx9UvM5pTamwcg5TOr4yOd16JmYTDjK2Fd5mdUuG3zIxFR8StIKI/Sd1ah8U+DGbNlVYAVb5OREJxQxVv6I5dxGC43CGWbpx3fB5wuFT3Jek6tv+LgBJaI9Ika79NFJQrLVMFbQgD0qU8YgCmLbxIJ4gxMBUgTN+v6PraIDHleYlpW3KVIiNxv2Ztc=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 11:24:49 PDT 2007',
+ updateDate: 'Wed Mar 14 11:24:49 PDT 2007',
+ accessDate: 'Wed Mar 14 11:24:49 PDT 2007'
+ },
+ '47f73115ba2079f4b3703f502e3455498900a21941625c25d52ebb7da31055f7': {
+ header: '####',
+ data: 'pK+wAHWg4IJcixnFodLQ5EH+SFQIOMOrthx52u21WZ1ziRWJLSYGwA8CNNK8/welwzPHOPWu2El+zE6cwLHrzmL8EARLvvJ2fEK11ZIvF2C3R06uNrA7QFZr7iu6t67osrpfljqbjKQrMECUCUDrBywRvlpaeIlThfA3XByezK2HtbyHD1/xnyQSenUFu/6Zq1EkVdm9iCkbej2KxZSxA6qMl1WcnplBdOqBSmeGGJ0+Ikn3LZ7t4ztqflsug7QYyQlrmI+d0UB8MFWpf6jYjZQwf1rMH5XHFvrWUCi5IbFNJBUPF3n3IfUlrnjUSBEcW3tmodJa16/biK9/iKqh5ImlnpbQgK7CStgQ8ByJqddJre1idCiK/dyR1z+IXHTu4qm24cJeGUk7la4WMG2O5U/otFbXG5wTVgbLsxfXlE6fzxHAzvEftEE1ZPNOBpRZ+LVYEHKFESIz',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 09:41:15 PDT 2007',
+ updateDate: 'Wed Mar 14 09:41:15 PDT 2007',
+ accessDate: 'Wed Mar 14 09:41:15 PDT 2007'
+ },
+ '6564169ac5bce1a632c602c51e9e5d637bfd4e87c1fa276e2cf65f39405fc4c9': {
+ header: '####',
+ data: 'fs5hydWDsT/FxWTb57K6zYKwVF310zjHHHtRS/AeBN8XZqTcirhV9oxJW6G6TdDkD7nQfWf53AbsivXn46Tx7oarzoU4R+1mz94TRCkEe5X2X7Wa3HbTj38+QwbkomF7np4MUkVc06aRPqkUE5hvSDbGn4SyKCjo/AnGhuW/QJIqnWVj70tf7CNTb+GR/y41JhJd7yk6U3cIP6Imik+DAvM5pE0KqxGLfLs4c1ChuTFNHfiQbYjs3tANqJCO185t4S8UIY5VxMRcnqgRoloFK3uFACIXoyDGG3FjILgxRCw2ePFsrm2Jtxv+JX4BsM+KDk67OsN91rjQnK5vBP72SzSge4EDCKJXYKdA8KJGYNwRIzk5d5ycbZgW4YCizVw8v7sLMn60v7YrDfBwXAJvvlTP1chA7HoE+WALqXkfBW29AOCNodE3eTXbI7iWz3vcWOCPvSm3hho=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 11:25:28 PDT 2007',
+ updateDate: 'Wed Mar 14 11:25:28 PDT 2007',
+ accessDate: 'Thu May 10 06:00:47 PDT 2007'
+ },
+ '7674ea33b650e84f9a461a91928bfc259de5549ce905339fc3b23623c6cfd09e': {
+ header: '####',
+ data: 'D7mLcDpylLnklOtIw/kvYX0M+CR6Si2t8CB9bTT3ZR+bTpXP88OtI19g1k9iPEUPdgbtFKPVw4oNmynP3x+pc8R/zzn4v697SvVtQxdF39Jmry5dnB4SMx6oRkuaISs0nxvTrHJe8U+s5ehzvQ2WWxWZ+LaoBWaYR7slgUFKLdJFyWEalPwMPVu//DoLZeWg19n2C/0Sy8u0DGdYHJVserWrQqxxg0h0m0x1wuKhF7IGvqgyJ31T5w00nMHNZbs89cUuqB/2doMgoUD9BqV7F/53AveuBDcdCc6jlEe8NOdoUyMuhwwwTyKONfjY5e5Cu5W9I36o7GpeKlckoKrTIWFO+NLG8XZvP/f2WJCsIOrCk/LI3C+bxBP+bK4tHRH13iXLeJYUlMK4ibcf8WI445qNoggJSbZzGr7Dav23KZWPcxzRxhI2u6j25/kKGnu4kcMB8ke5N+4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 06:46:36 PDT 2007',
+ updateDate: 'Wed Mar 14 06:46:36 PDT 2007',
+ accessDate: 'Wed Mar 14 09:40:01 PDT 2007'
+ },
+ 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec': {
+ header: '####',
+ data: 'u9HEcfobxZhG9BY3dVG68ZUYkREFcZ4q1o/xWyt3qje3icA+Nu9yCrZip/4fqe1daUX/MHyzUQdulIfjSwATjj3vvDSPjuGvrtx8oUjJ/K6GFsL366ozi45LkqkOaH02/nVrb+ik2HWIgcne/OzNrwf1mWLJoBF+8ZwQ44xqQK7ikG1mblNWWbZFFQE1B0QPmE/I/1ovm2hAr1ZsNj1l+N96hwGsdsdVFTzn+S7Sg8GTbxEFAxDQkBYEw1k/R8i9EIBndPoDZCebr8vP+c8qSEk/YmBXJ1MGVVvic0/Utn67iNLz9aBnv2z31DvvBj8bIwOxQpB+tom5Ivwe84tFkwwvpxFqYccrEg4bbMcevUo67TBVe+Lb2wzcK0zOr7iHhswbXaLzzOEQ6uF/v2ibTbATP2zNq09AIJjynoSDmrisGHsBrHgeXjiDspc9U70PVC83EsjPRwA=',
+ version: '0.2',
+ creationDate: 'Thu May 10 06:01:21 PDT 2007',
+ updateDate: 'Thu May 10 06:01:21 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:31 PDT 2009'
+ },
+ 'e699fa287c2de3d483144b48064a47cd0bc56a436431ce23b48cb8d8c42ce851': {
+ header: '####',
+ data: 'hVD8NOt8g/DIe48JbUUo77e2hMf2UBN6ah23PrIzGTpq0LifC2K/0/s0yeL/PHUOncdT56NccKpF8Fp6EWJqDKoKZPWASuB1vHCEkdbcxlqzqo98VS3A7p2JFwQzSv+5t6y909hhbxobXMCUfZ10HBqGo6TaFc6+pkYqQ/d7MEnj2NuAXC9X9TLLuZSrZ96NCKGr8YVKzxinxHdiF3TdRvIppFByXPlbZ3xiielEnYm6pu/GffW7Hkwd7Vou6jwyggxVqvoVtuAdiIy67l8GX0gQUGipFkvvrAkXfm0sgtWGQvpgDuV/bXq/L5vX/sFpWI2u066lMUOsJQmptNP/Nkp31+ZNk1nCcUIYDDa6vcOy/gRrOFcenPTUQjRkE95KPaCqYBSIWsjoFE0EIB+iBnBCTK3laBSC7pplOtuLCY1YJcJuOkzCVQCVXjhWrNJM77s7a5OyTuE=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 09:43:29 PDT 2007',
+ updateDate: 'Wed Mar 14 09:43:29 PDT 2007',
+ accessDate: 'Wed Mar 14 11:23:51 PDT 2007'
+ }
+ }
+ },
+ 'f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732': {
+ data: 'vxOgJv/v3pP8GFqbFLTcgtBqw8V3zhCN9rRXUuWAfatABtr3pySWvt74ITeGw+sDtApBsu+zTY/95BFVtK3y0QJkC5cjJYhLDwvMwpqa0lRfCXWSYmuEhbPETwkW1MN0kAEOMqsUD9cQCH9GDD4A17W89AoTG5Ce//X03YBG0cDjbotgENsWjQpK88LXABHBQAoTF0BPDjN+xai2QPCgN0l1IVpUzI87oZJS7x/4r6DjGTOgcc3+vtEujr+8dGNaq9xTEfAFs1kv6GMeT+R/VkIQLVO+vSxi2fd+954EAXQplt047+aZ3c0c78N6B+GhSi9DgNnbTLu6sl332Zdgo9R09uucS8nvRp3HcTzxriKpx0ZMDh9K9ig5NT9Z2H49pDjCJKTukDU7b2ktOEUNZt58s+uIlw1bMFY1TMETGAHbTq+hld8Szg8f7nJGDQF10kV2ykVEQ2oUBMC9y9VCLyYD0BWId6DUcTNXyI+MqAC4j8pp0NhURY8VSjtnV4Rlq+b48ahP/ifJdq+xrSiT9ykGqc/EyebC1uCTIZewk9MtIAndVYPckMIe0xQ2xhX6/m2bdNboVa3dnS5eKFdbd++un6FD+QAjgtcBkXQnwfptottZoghclKL5h5gPePCQL/66CLYy5+3xctfCG9u+VkH97JKL2hW+XZ/KuxLPFkIAYmbFKsNdIizfpbk5WJvoSzacpo1mwNjZ53zn9xhy/VkSIz3lGl83a6FyoHuR9VklyhTaKrj2JNWzjLaQPiR9Sv2eFNjLTivxtxLwKae5Tz14WU2QlXATC5xdcLeF9nK7yYVarcKlRsYkkvetrVpRiWUVfy9mZQIHOWJtY5AcptKso2Q0v4CuD1C/wV18DMDXzwMXeOq0cKxCsZOuWjO6RwWKzfeZnJ99S+EsFmdI/wxqiu9slJ0xXvgLvjiJhJ03qWwZV45peU1qmvKQrXS80QqLp3kUfRGLbZNOvkZbyf5OK96MA7lok8PuCZGg5jZHFX4B3vxSQ32P7VGSWO5CqHpF45YwtlONZKB0cuvKTRazZ+B2zJfwMYRQloj6sL5501oPqmjVtDg+0aoqKe5DmTf+fHV4FwAxQ8RuW7/BVL+lwf+zjtd31I/yrlDdb/Scs6yayLV026yuHxdQRl+ByogtrXbY4ViuU3NCkVrme7K7meRHnQdXyidhjzHdoJnRPa0IoI4VW3VwWNENRRNDTta2whOdIKsQYtscWBWZnQplRmDChGikERYQVCWejDNgvnbnGrlyQYPF0/vcv6PoDpIvh7Pze9y0MLBU8DnWqAhpdqHPNVdjdq51OKlSitUk5TSN9kxePe0KNFZueLjxZHUFIZ+SIkTxoCoaRWYMJIWvYkcT5S9Y/7NbdapuUaLZNGDc6tgD+LVYRRvGEdPWaOHb7G+qOmdtx8vYxZUqq5mtwnIBRzEllTJyKwwK/kOfAxiRjLxf7SOXsubPuA7bHR9fI5rROSR5rcU+nOfSV9Wf4wZkYBlSmQYqzQfmwl0UCiipJVa1DwYwLimgo2RqhI0M38gEH+mrknnevE8zlUIaEWzxoOnyWbtCecakXS2XvE9j64dswJ3bbeQ3fDQr1308x9qKSjFdDl3eNcJx2e9YwC7wZnTmHeHzRXnZwXsJXqMPDQV99wEDBr71BjlDjMx7vG9bOWrhsyJ37EOvO2X41Ij3j0X4MYpbNgxBFP6zJSu3gILrtqQRpQq6mQJ1bWHyCN1ge1zKNT9pG6rGTRPE9LqHROQuROpgFM1R+DqW4XnGOBYSOtznnsnj5fxfdpGeFq+v/ftvVuN5XsgX6dnT8R77iNUs86Iz2mkxLaQokkNzXl5o1rnQIse9+kcKVZ72mf5SG9s9DD7cZ7bOtmkuZCexJpieIosqLV8jc0IA',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 09:39:39 PDT 2007',
+ updateDate: 'Wed Feb 13 06:29:04 PST 2008',
+ accessDate: 'Sat Oct 24 02:11:28 PDT 2009',
+ currentVersion: '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74',
+ versions: {
+ '33ce5a03b6d36f59d0fbc9445dd01a515cb56eccc6d854cffbf8aa66f3e4a45f': {
+ header: '####',
+ data: 'pwMmqFOwpW/uSys3hm/AcoERF3eDj4dO+O5SdYsR2mJtmEfXcjhS9altLhVOsck0KMQJdxE3rNDFbduF35yVetXuQrrL+bSRlXMq03EXETyrRzIVhFEM4BjoCSS9nKGgixp04Ve9WSuwD4cXRmcN/L9kCJSCqflXqhkYkjAywQoj1KxHPdAqMaGRpEWioUIfX+NiWbO/qtOu/USAhHmWFXla6/A9kKQeU2d+P3zl9KF2Zm8qm8NXjPKmh2dkd70ATbdzxt9P3BafoRf/Ud8zLIVdQYTbv0pn6UMIiUDRK1ryvgfSY180zg4qkP5pBnxhEgOxbjT8JO6hCl8n2jUCRJLdUXHwgpeuHcKYDyZizc+p9Kbc4+d8K/2UEKgSR6gza6Cpw5TQbZQq+2LxWUoVb3HM3lTqBKUPM0FdY2/3twZm/1bI1uBMPnyp9x/JsQV+xOpu0ZulTA==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 09:39:39 PDT 2007',
+ updateDate: 'Wed Mar 14 09:39:39 PDT 2007',
+ accessDate: 'Tue Apr 17 10:09:44 PDT 2007'
+ },
+ '686ea579db132287e8e322194652ec57cba6e60274c00f734db7a0b36702c817': {
+ header: '####',
+ data: 'ilf8U30hSq2mqje9kZkKQAMiEFV0aptXrm8fOtoOR8pp36V29kXyUX6FEOh5eXSRr/jbqGytxKENJeAGxnsv5U+8GgbvlYaR4MPM8lbKcpAoBCc0+CCOiwnp4XCoXFCNttbTzfb6qgR7wqdK7YLnrvfzJieQqJukQZvtWtsVZB/Tis+5niomz8Ca8lo/FjFOIjAq6xtwrW4CS12+yZdTKNbj8e+HwoUcesF9RbCKQlpVHuwhZ/8ghdzDgjEE8z44rDepEv3Lx/aUi+67velLH3j+1crnxBUz7wP/dWzftwWgIxDkCR/vW63yY2Xebt77swDg8g1Qj5OJdYiAq231HKaZjxr10y88JI5HC1EvbbduDN6pknKUgM+qEdojpi2BmjK+9MtV7sVhJoWqwHG8q9z03kgGoFnWEb53HyMVes1n6HYfzwnw+idPFWGZJ4IB25WfJLfQuQ==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 10:12:39 PDT 2007',
+ updateDate: 'Tue Apr 17 10:12:39 PDT 2007',
+ accessDate: 'Wed Feb 13 06:27:04 PST 2008'
+ },
+ '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74': {
+ header: '####',
+ data: 'l18dnf2TRfinuu9KDraIo41yvG3mNFqiSCOkyMI6WZZD4RnF8R2Ob19fJ8zXv04eDx7TYyyGP1IlFWEdT3LBrOmmbtUmIvtYanIfKTkT6UGHNH2jh1HyHqJbpgIlr67mOm6Es/AgF44BiyJrk5R1y9tA90oeUQynMufiM2MFLpdalDYWEh+W7GV9WCmbBIU/soioTJ1ep2gvy4kJvTSrXENaxHevKfYwn8ucocvY+hjkWB4GWOR40qtaG06wWMLeRsrTBH1jBG9srzbBa4u2IQ0+NJjQrYdiu7nfu6Uyu7Ya/4bxV3Sukao91XvXSFIhcI2OuKl0njUshv6BDEfHwXIQuPtn7KaTx2uYl1pUeTv/tAFvf8Ng9OFNgK0siIMkeg1thFwRiGSmxjP0QZipDtcCekIxj2k=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 06:29:04 PST 2008',
+ updateDate: 'Wed Feb 13 06:29:04 PST 2008',
+ accessDate: 'Sat Oct 24 02:11:28 PDT 2009'
+ },
+ '7ee6a662d1980467eea86a58cd7299ee02000740693df2a7ab9dd64347dbbaa4': {
+ header: '####',
+ data: 'ZnwtGdkg72+TQKCJQhZQIqP9sz79FcptnmH8VJEDQY9xTburh4cyhgbgROBis+awp1C5OyiAAoWfPnuRAN8Ai3d9f8M8yjnDGJ4BAJ6OjQ5r4RDQxNycCApXWO3mJpBrx56wMsCVWT6Z8a4khzPrf5HlDtus4lRV4GRdhU9FMpwuaCfgVD38MhlYXDaPgyu/8N+6eQHuFxquXjOJmptfO6tVhP1+/tEHo6iUAX3sXMZAionssRgPllQJxfzrsu7GQk3h66PakRzgStTHUCcdyoEe9c4VnvUgaasTbhENA4x8xPrxjo24zwxfFpWNEb1+pe8N3+dOXTsIdd3CMKrxQ5KkwzyN/Bj9jXNk9YX8PC0geJiR3bCGtPsAd7aEFB7E6y0RVX/RL5f6x0utSYw8mg6lfprlr5A=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 06:28:28 PST 2008',
+ updateDate: 'Wed Feb 13 06:28:28 PST 2008',
+ accessDate: 'Wed Feb 13 06:28:28 PST 2008'
+ },
+ 'c860f9bbcab5fa70854212e18c11a3e9bdc2382f91cfbd25636955c443a05f8e': {
+ header: '####',
+ data: '1rztZ6mKVFVjlL1kEoUsXEMketdElGbOpYK9iy3g1/WeMcTd4D/UjgHvmQHzzNuYJc/yx6cCMMU9dofLe3vWLKhqDAPAVCo49qiH527hP9rQE+0SNO1v2Ymk80hL/gqBfju51bIYxPKAD0uYA+GMX7OdL+S7qdealebERcnVa0K1AHiVU8lu5yIKk55U8zwitk0u86J1zwcraiM3RGXir/x3oZRIKDwT+lhUJPr8GbVjgKlPu07Ii8OdrAGdHefETDlyNnaKPJHTbGXkd3HZ2CYhJCQZGn1Hwfs46iRd5aO+3UErYtgIHl6CXuXd4E+DNW4UJZedP9YV860DBkpqMiQokEMYTh8Y2sOUyf3ZEOshfGvJUhj8O5p7rNm4+2BYO3XhREdV39tn4vUj56wYj+GL5CekEl0c4Mx7ViTQA+gLvk52V2w/5gFyFNQ9U+jUQpb2n+d9cw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 10:11:33 PDT 2007',
+ updateDate: 'Tue Apr 17 10:11:33 PDT 2007',
+ accessDate: 'Tue Apr 17 10:11:33 PDT 2007'
+ }
+ }
+ },
+ 'fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6': {
+ data: '4zgqvaaWm7nJO09LKN6o5hbWwGzOv7VVmXDu5T+JCHTSOXbteogax2Zrv0uKLkfooGFThJBk0rXfXxE64vMOq3AeHXGw7Chg7hz8Z2Lpjr4FfE6q7Em7UuAlAuL1PiyXXJJK5iSsRY9tkizuYl19aXW+CgpPznYD/PyXgeYxqt9WLqK8cl5iAU87R0cQDhwl16ivzVgiiFeaB6B5FQqWBAHCEgXhqTsaw2gv4snbmPOqcUZbHy/Vb9hv4lPBJwGFNxQzeZUad92VBC8YbIjmbohDsXjteqD2/k1qOgpUB/U5BpyVwsi+5ahgb8gbS+AqYoRDYzkaj83ksPI4JzWyZhpqjhDauaI6M7hGnJ4GB8UZc0M3WPgrlf1r+TXCgpcfembqL1MyteM+C+ItPRP/QdaIXxLOmvGFOBKQYEI7UceUWBCSEzORlS2S2lltlqt+K4B8QTULiKaXCfRmF/u60FpJufIkUX0pE/rQVChxswSWvh7uJFDBIDx8MplTX724A7DN5d4/Ad4Yi2cj3V8X/DEErnHTvirP3tZ2F2oAe7kIdu+JuCqKcMaGB4hVijzv+yim2TCPvrGTFaMmg9PvcWHpik9jEIabCkdqAR8EGIkD29+yvG4vD0DTRKv2vPIfr60ZQnsgs8nlPPoNa6lNHvI/EO0nBGBYBc1TW+syV5h/zOG3rHX0XCHhISZmDMjra7eUETWChncR88P7ciC4yJQtzXFGzeXp2ktzZ8m5g1EQfgtlUVZsHN8e4OQ9DjKt0unfq5RFBj2jlG8TBZn6ZpebxWR2qOxp81KQLHJND9zRTy3h65+k5wo3MnnxE3GbeXg2dFIORRvGUT6bWsqW1fqR/pg1GO8KNtrt3CryZofgE52kuk6hlcmSk9974JR5523+1/hbts8n5VrTi1C6GWhnxpiJb1XIvICdag5g7C2iYppzLKVzbJcFMegwDUrapbmGhkqnGwSY1EQSDyagPr2xlziWhdWdCOVAYcyw8dOpdD97QhVef0OWrJ8nbgFKD6wn21475OFxooheWiMCyZwXqESVG1cVCjeaCsymBtEVPpmQdSkOfMdXpKVF+3osb4K2XDpPeU1zPWVozeMp68YhLztQ/g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 10:43:29 PDT 2007',
+ updateDate: 'Wed Mar 14 10:43:29 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:19 PDT 2009',
+ currentVersion: '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a',
+ versions: {
+ '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a': {
+ header: '####',
+ data: 'QfC77EWgmmnxz9JqLdn9Tw7mNztfQZPdNpaML03EdFpphsjgLloqBRX0UZ21oozjQGHpcUMMOsaJgzCuDlfh7T7ePVV60Ps4AJtzv7bHSVGKsj1iALU1qjtesOYJayp8bA/3peo4HEnVgP86jc5NTwJxpsUhNG0Ae93xVu4lPF0gL0/yjgZUHqYZXkb+oXrcybL0BSOjRnB9fRpA1dEhcwJwoelLTvg7il354qp/Wo+S9Cz5E/K+xnlJAuSXCRXboWea/ZZ9TX88q5uUcY5jLF7Xi2HoFVZw2f5tbycxwGtT1CKXp+OAKn6mQaBAYM51zoMNDT7MvBDXD3v4Cidjgh24GZ2zndfkYT0kHCtY7OVIVSTsXTR+5/XMedojVvDlX9LBa9ST99NLCUy7Di94rJtX72ev3Ei3I1w3qPvCl3jgD2VbIwLogCzqLtY+2IkLAa8M2EpX/D+h',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 10:43:29 PDT 2007',
+ updateDate: 'Wed Mar 14 10:43:29 PDT 2007',
+ accessDate: 'Sat Oct 24 02:11:19 PDT 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+
+
+
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'test_test_offline_copy_data': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ '9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8': {
+ s: '55a27b18e8fdf1fb5e5bcf859cfa50fcbc69c9a41f04e371606a86411a98f460',
+ v: '983a6c79e7d5d490c3f13645c49760180fca05cc677914bf60fee009ead5a65d',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13":"0"},"data":"Ki9chN/ker5c+7zB5NinstllVq1Vs+N5pezZIohKVVa15VLSIyre3DRilRoldy/94LbGaEM3SZsMlf28hYbWySln3ekNMIB+MItaYb8urw+8U6n8+QaRMAClHXukfi8te2d1OIlgjbrBQNMmzBorjIs="},"directLogins":{"index":{},"data":"54KM7x3emxWZH4CQDLBj4SkT"},"preferences":{"data":"AwOQXmReKkLpp8qZa4zjaWcY"},"oneTimePasswords":{"data":"YgSYIsDeVT87bfiASQqXA2E9"},"version":"0.1"}',
+ statistics: '6Kupec1ZD7Dw0WzK7pPesnLE',
+ userDetailsVersion: '0.3',
+ records: {
+ '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13': {
+ data: 'dXql3HZJQRpvwOe56SgzbbpMoYWRBjEp+E8uMJT7tprzYJ109H1SnxRWWiXlDOzH2XfoXahP3S59K7rHeJ+/icX+ZrsOvp3YEW7wdoEDosyvrQuxrmHdusZ3BeaFIhQMmK9wqpAzpKCRrz30l/yi81zNpLgTXLLK9fiAyksmsfQL3VHgQg==',
+// data: 'bXql3HZJQRpvwOe56SgzbbpMoYWRBjEp+E8uMJT7tprzYJ109H1SnxRWWiXlDOzH2XfoXahP3S59K7rHeJ+/icX+ZrsOvp3YEW7wdoEDosyvrQuxrmHdusZ3BeaFIhQMmK9wqpAzpKCRrz30l/yi81zNpLgTXLLK9fiAyksmsfQL3VHgQg==',
+ version: '0.3',
+ creationDate: 'Tue May 05 01:28:36 PDT 2009',
+ updateDate: 'Tue May 05 01:28:36 PDT 2009',
+ accessDate: 'Tue May 05 01:28:36 PDT 2009',
+ currentVersion: 'a22bad10653a70ec3287917bc23d642fe698042cabbcc1074b60122cf2bb9d4d',
+ versions: {
+ 'a22bad10653a70ec3287917bc23d642fe698042cabbcc1074b60122cf2bb9d4d': {
+ header: '####',
+ data: 'Pc18C1A9NwNlecbOtOOAEymNZD5oq20ZvPqMfiCyNhkcmaN9sEnifF31epZSjpDw4XM4ex3HFhhITttXlCrossDVYB8z00k6XsFruCkdwFRmBjb2PdrdZFAkGQeS/8xTarYWgiflkfGocGqVm6EUq1gh8QLE173Jzo15LOSuzuSS90BTMvcsqzzRrIEe+9jwF9/ehLyQ5yYxNImFGQQ2jkW0KiZsjyEbQAGry7B1/AiSUBaGYHYzcB3bFgXnzC3ecPwL+ENZ+azpTd143WneuVMUJrWNp3S+9ZRzboRzcYV6Ax3nOLPS7LTc+e9j9s4CrPvc1L6pG23AzNByDWst0JrqhN37yp67EVVrFQfUDWcKgZyyA/M82q1TVScx+I4A+g9ASC+PdQ3+M5+EOtEfClkgYJFqzXqwPKYwBv4CBKxikS2Vt8x40271kjmVYyGQOIRTo1UKn6u07TS5hxdEgEI+WdukG52813USiD8bQFbN0r4VhjFSqKMAJoItjqvafBNBl+OXYQ1p1zRCXP7wHS4/F7mvrK98gSuIsBgfL+/q9rExXaxIZJNSbs1HGAXR1TxYSvyKZvLa',
+ version: '0.3',
+ creationDate: 'Tue May 05 01:28:36 PDT 2009',
+ updateDate: 'Tue May 05 01:28:36 PDT 2009',
+ accessDate: 'Tue May 05 01:28:36 PDT 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'test_test_offline_copy_data_withExtraVersion': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ '9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8': {
+ s: '55a27b18e8fdf1fb5e5bcf859cfa50fcbc69c9a41f04e371606a86411a98f460',
+ v: '983a6c79e7d5d490c3f13645c49760180fca05cc677914bf60fee009ead5a65d',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"75b61c51726a35d1c12ac553947ff9e974d1a29339f87fbeee0d831b59938a53":"0"},"data":"YjlNzXUO9m0EXdi5fUguA6RjR5jc2mwuHkpMsHAheExR2zpoV6OJx8tBTdUGqDBAlbIn6xUx2TT+dzgjic/XubgKNsv6JpTvnfiW6ZMWiebKXVigoZw7L5EvmcHjVLI8aoIhVEj4ADwkh9qHm0Kt1zFGQPwwJfo="},"directLogins":{"index":{},"data":"4W5csD8DxlxeXVRROk7wVbXi"},"preferences":{"data":"/DjOoFcgquxUbW5ye2LrpsKM"},"oneTimePasswords":{"data":"DEqkd74lLAGtG4YKRPniBNBU"},"version":"0.1"}',
+ statistics: 'EkRr9wEXi/WOlZfCXphn9kfx',
+ userDetailsVersion: '0.3',
+ records: {
+ '75b61c51726a35d1c12ac553947ff9e974d1a29339f87fbeee0d831b59938a53': {
+ data: '/gtNfde5l2J9eeg+rlBHZtqO4RDaWNQwaMEluOVowKdUlGAYjo9FU0NwKsA9CM3ST4sTYl0mylP3C/AGybO8/9sTCkEn20wi0slharA61Rk8uB2lNjCICZB4l3ZGvD4AHKucu8YQzxpWop5dTN8f4us5eJ2VjvJPLqUzSKZL4g+6MiKbjQ==',
+ version: '0.3',
+ creationDate: 'Tue May 05 18:47:53 CEST 2009',
+ updateDate: 'Tue May 05 18:48:59 CEST 2009',
+ accessDate: 'Tue May 05 18:48:59 CEST 2009',
+ currentVersion: '2c913151cec0422dfa51c5bccbca6ad09d8e195bff144d2b5f7a2da3bf55c11b',
+ versions: {
+ '0311012a897262b85b60a316f086f0576caa3c11a34779c02ad9e60232c79564': {
+ header: '####',
+ data: 'MZGx+tQAecxJNl6UbWHIM8g416Qa8DfWtGo7f2vLkPBbhsr20xnZ233oPqIGceG5/6WMssQd9c8U81urISK+4Ar8zHGUxTdIYLZaDq33Q0uF5vO7OsaBcjL7m+tX7zB+e/eu0ABbqvt+saMsZKKSdIZv2KNbAg5VTiL7GjWuowM23tWgiUBgX3eO5fnUUQWVkBygk0qy2O45oNfb1XcbsGMCfS4YPF9GB/wGSQKG8keMoy1ZWZh4nG+Pdx2ymIrYKLv8T+i7jtWEbyhvEglb7TadCMBBF0pnkYvG3F29skWooZC92dy5213o+3/uSKi0od5tAbvSYZHjT5hDulUtmjRFGq4ZRERLqvrZs9Sg8G2mjtf8Ta99Hob8WLxyGF9x7s1LcLPERtdsP9qCD+I0WtwrDiodl/sPQ/5s3G2S+M/YejKXBvG3AWwoO1gkdhec3+d3meFNvCr0hKNzotrHmDLC4tGyZIaAcBmPQ8xSD5KmNJJFU+V0QIdiEYKnPjo95oSmKyK1UtIoPrWCahfYSKXh+aW53XnzY4JKHRER9vWwdJzz',
+ version: '0.3',
+ creationDate: 'Tue May 05 18:47:53 CEST 2009',
+ updateDate: 'Tue May 05 18:47:53 CEST 2009',
+ accessDate: 'Tue May 05 18:47:53 CEST 2009'
+ },
+ '214d184d75418af71d18f412bc6bb153fd6435a4a675af6bf2a744ecbd7a53b7': {
+ header: '####',
+ data: 'Y38v4jhKwcsW8LDTigIhtdLJ2zgv+1rSutqyu0AilBQeSTe4D0rnapZZTW/mNnD5IGpWKFoEl8+WGj1zvGzleNdkOa08nWJEYDNe2h0+FjBSHBUAgH5fraezomRWzJ/Z5HHFiZuFfpjt2BHd0Y3Not6AuL3aBgjjkEai90r2o59Xr70maUwo1UqmtVg3gvX067MC3hlqhNIp390J8LFiSj8Z4US9x/WzVR5Xx069+0PFMBwipq9WJPrcfTPwvP6xVa+J8BCJk3HtboRutq1ZhhHpibm+TY3Xl3gFTTCHWDZCSJ4Rm1dWkyqpx51u/AVg2TC+ljFLKv7hq3euVZNMLNMY2BqoCkcb+w6dFLDs3WfPAW0aQN2P++GFa/eVpN90YxAeXufjsXKaArTMjGWKiHqyU1iVVI8N1QEiFYjjBV1GvkJxog5PjtAzJF++qwHDIa+gJ+NnOfenVF0wIRMCEnpGyvbg3SkUoenKFoHO0IcSP2CW2RWV/GAmiEZEuVD393mKi5B6fpjdO9JVPNyz0i0kW++dtzInwPnglhOAY1ywT0ExOBLIEr8=',
+ version: '0.3',
+ previousVersion: '0311012a897262b85b60a316f086f0576caa3c11a34779c02ad9e60232c79564',
+ previousVersionKey: 'f45/Sx3jMC8CgdT8cjfcC4ApA8xMXABFO48jiTh5VjJfTlVqw3NnHRO2KDBIhy0znPvP2AKlpKQHruW8LQno7YLyhEIXh4ChjMUjJsFFwB/LUg==',
+ creationDate: 'Tue May 05 18:48:11 CEST 2009',
+ updateDate: 'Tue May 05 18:48:11 CEST 2009',
+ accessDate: 'Tue May 05 18:48:11 CEST 2009'
+ },
+ '2c913151cec0422dfa51c5bccbca6ad09d8e195bff144d2b5f7a2da3bf55c11b': {
+ header: '####',
+ data: 'tkiW41JHOfbYOt2KHx1HtDJEzxbfVS1Y2HJQqdQZ73zhvxnkWLw/X6FMiBexLeoKXO1H9NIWS884MzEO782vg8QRxTizg66Yye+q1Hox+QsaEoaD4UQ54XV1duTOB/XS5P0P9DFvtIz9msEu8GJrvizAdxu/7FG2b5XfENDkwqIzydI7JMfGC0JzDnfGvYkWqoL8jx3Joxa7TNqN4he4v771Ho1ZoUv3Pp7ZGwBU+btl6Q9mcycSf5KXdTw+6nDjfQh8qyts/u7O5xPFh2Yn8zS48x95I4SA4yFKtERU3pLAxIkcZWVb17xT8xlbPESreZ0RyYSR0CgW0wPMxkLHH1uqWycTa7yIxUhyn+JK9jCl4eDa/KUSGbN1yb6pOyjGuev1vHEZv3bOmO52RVVIdMHTe3LezCKY8xpDqtQKSfAvFg1TmabugXePXB+KvPbDDWI5otDEIwLYhDFcSn2FyqUEATSzeU2o1uXO+ffbU3QBrwr27tsreughWSP7905FQbEEshsRUc2Xt92WhTnVM6W74Y0bMLWjTrXbu+hNsjtFYYN6gtezcltnB58MVw==',
+ version: '0.3',
+ previousVersion: '214d184d75418af71d18f412bc6bb153fd6435a4a675af6bf2a744ecbd7a53b7',
+ previousVersionKey: 'XtJ8Ub99GXIkxErIPr0HaIrRqlAO0Naa/tPwUA51K2D5R6R3CR6QbHd3GpkCnu+y+bcEIRYrQqgabi3LROYT+1SZ9B9FctX6FyaTjYEazFdCvg==',
+ creationDate: 'Tue May 05 18:48:59 CEST 2009',
+ updateDate: 'Tue May 05 18:48:59 CEST 2009',
+ accessDate: 'Tue May 05 18:48:59 CEST 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': ""
+}
diff --git a/frontend/gamma/tests/tests/Components/CardDialogEditing/dragAndDrop_test.js b/frontend/gamma/tests/tests/Components/CardDialogEditing/dragAndDrop_test.js
new file mode 100644
index 0000000..e805e34
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/CardDialogEditing/dragAndDrop_test.js
@@ -0,0 +1,128 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.Tests.DragAndDrop');
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+Clipperz.PM.Strings.Languages.initSetup();
+
+Clipperz.Tests.DragAndDrop.Tester = function(args) {
+ args = args || {};
+
+ Clipperz.Tests.DragAndDrop.Tester.superclass.constructor.call(this, args);
+ this._user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.Tests.DragAndDrop.Tester, Object, {
+
+ 'toString': function() {
+ return "Clipperz.Tests.DragAndDrop.Tester";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'user': function () {
+ return this._user;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'run': function () {
+ var deferredResult;
+ var proxy;
+ var cardDialogController;
+ var cardDialogComponent;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+
+ deferredResult = new Clipperz.Async.Deferred("DragAndDrop_test.init", {trace:false});
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(this.user(), 'login');
+ deferredResult.addMethod(this.user(), 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addCallback(MochiKit.Base.bind(function (aRecord) {
+ cardDialogController = new Clipperz.PM.UI.Web.Controllers.CardDialogController({record:aRecord, delegate:this});
+ cardDialogController.run();
+
+ cardDialogController.showPasswordTooltip('**********', MochiKit.DOM.getElement('Clipperz_PM_Components_actionLink_63'));
+ }, this));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'saveChanges': function () {
+ return this.user().saveChanges();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hasPendingChanges': function () {
+ return this.user().hasPendingChanges();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'revertChanges': function () {
+ return this.user().revertChanges();
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+init = function () {
+ var tester;
+
+ tester = new Clipperz.Tests.DragAndDrop.Tester();
+ tester.run();
+};
+
+MochiKit.DOM.addLoadEvent(init);
diff --git a/frontend/gamma/tests/tests/Components/CardDialogEditing/index.html b/frontend/gamma/tests/tests/Components/CardDialogEditing/index.html
new file mode 100644
index 0000000..7cc0961
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/CardDialogEditing/index.html
@@ -0,0 +1,133 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Card Dialog EDITING - test</title>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/DOM.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Style.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Visual.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Set.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Toll.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/BookmarkletProcessor.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/DirectLoginFormValue.js'></script>
+ <!-- script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Field.js'></script -->
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/BaseComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ComponentSlot.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/FaviconComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ProgressBar.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TabPanelComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/Tooltip.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TranslatorWidget.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/RulerComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogRecordDirectLoginComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/DirectLoginEditingComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/DirectLoginEditingBindingComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/DirectLoginEditingFormValueComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/BookmarkletComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/PasswordTooltip.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/ProgressBarController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/TabPanelController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/DirectLoginWizardController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/CardDialogController.js'></script>
+
+ <script type='text/javascript' src='./User.data.js'></script>
+ <script type='text/javascript' src='./CardDialogEditing_test.js'></script>
+<script>
+ Clipperz_IEisBroken = false;
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+</script><![endif]-->
+
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/clipperz.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/compact.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/ytheme-clipperz.css" />
+
+</head>
+<body>
+
+<div id="tableWrapper"></div>
+
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Components/CardDialogNew/User.data.js b/frontend/gamma/tests/tests/Components/CardDialogNew/User.data.js
new file mode 100644
index 0000000..dac8b45
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/CardDialogNew/User.data.js
@@ -0,0 +1,977 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+testData = {
+
+ //-------------------------------------------------------------------------
+
+ 'simpleLogin_001': {
+ 'users': [
+ {
+ 'username': "joe",
+ 'passphrase': "eoj",
+ 'version': "0.2",
+ 'connectionVersion': "0.2",
+ 'records': {
+ 'record 1': {
+ 'notes': "Some notes here",
+ 'fields': [
+ { 'name': "username", 'value': "joe", 'type': "text" },
+ { 'name': "password", 'value': "1234", 'type': "password" }
+ ],
+ 'directLogins': {
+ "record 1 direct login": {
+ 'configuration': "",
+ 'bindings': [
+ ],
+ 'favicon': "http://www.example.com/favicon.ico"
+ }
+ }
+ }
+ },
+ 'otp': [
+ "12345678 90abcdef 12345678 90abcdef",
+ "fedcba09 87654321 fedcba09 87654321"
+ ]
+ }
+ ]
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'joe_clipperz_offline_copy_data': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ 'f527cdd90d0d47f8524b4e165398ad1455eba515d04abd101d1e93b3c6ae0674': {
+ s: '186f0c40bf73f2af236eaa6c429df225efa933050c9aae65240e93b7b362e3ee',
+ v: 'ac61a6e325ecf329926a86084f591d8852d0ad3e4a6080f2adc901b82395ecaf',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5":"0","13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551":"1","062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80":"2","ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c":"3","507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a":"4","d5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d":"5","de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4":"6","d620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045":"7","f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732":"8","36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113":"9","fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6":"10","6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18":"11","9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291":"12","6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a":"13","6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728":"14","8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39":"15","084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d":"16","7bb69b6366a8012f181c01e368ba18d4f7a82bcabb4959189736ad124c4bbfbb":"17","5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4":"18","c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065":"19"},"data":"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"},"directLogins":{"index":{"61e87fdc4f1d9112e3b30c1f6812d095dcdb24f014c83319091eb6c9899ec348":"0","989593d4c48929f0c8f1581aa96969c622807e99619ed4732026e967530a68ad":"1","9f7979368fa29f66c44bd97ecaf6c545abc800b1c7bb21b7655a68e1514c3906":"2","dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496":"3","aa18149164302d5dbe7e2d3724565b9550e00887b49978559783b2e38c625584":"4","1f9bfd677b531a03168d3f8bd8afabb5357244a7bc355dff50bd6c0a072114a6":"5","a48e38845713462ecc9f827149eeaae87da882031f98ef8ebbf9ee9537b63468":"6","6f7bbc4e42ea462b5246e6f51c3f86056bec50601ce2de6067c8c1d26f21c07f":"7","2df54059e78f5771f23bd285cce19595b38331b73d67020424d9a1b2257db09c":"8","065cd0c270e5e8ce50e4ea8e3828dccdae18c01ab030813d756a87d03fe68784":"9","ddbc8d01300a4f10631cbde09e1246332eade3a877a2205209f9eb9e5bc9da0b":"10","9b7a30e667afc9f76ba77600658b2c13bff52432d444261d39bf3d069a160afe":"11","9fd2929cde3d32d9cbc5f1d787f2f64729a5e12a14410556b31c0c099762c46a":"12","f695fc36ac56bead80c0d20a88e01e382819c18dc268f1679551b7c83db7cb14":"13","f22dc41ffabef4b3bc8f7af804fec975bd50718098322a673cbe4aaff9464ae1":"14","03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c":"15","a7b32e72502804bf2946a2a8856139cbbb759c5777e6b3e673db1fdf7e3bd06e":"16","cb9ae0bba1957075ccdbfd3b3481704d62087687a2ac7c411a4f07d444bde0f7":"17","7e1d069b7fa57c03bd7bf48807520feb953157834503aaff8c9d493f37dea69d":"18","24404059cabc63b2dbff0f42ba57183108b8189ef53ab62fa25141a1caea824b":"19","33cf9758477460a8056deef0295a1ebe65b39b392c361ceb920a83edacfe5d78":"20","e9a16316f330e3d150f6ffd194f6fd8acd1426757b097de4b88ca0db875202e4":"21"},"data":"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"},"preferences":{"data":"EZMrwxNFFd1sMGycoYE7IrlGGrfLixLUnLZmWMkFysfISe2ay3ueO0PGCApuKqh9hA=="},"oneTimePasswords":{"data":"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"},"version":"0.1"}',
+ statistics: 'SfGy/4mpXQdDOv+Bcfie4Yt/',
+ userDetailsVersion: '0.3',
+ records: {
+ '062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80': {
+ data: '7sgxSQlqR+wh3g06M2+sWp7raQxjjQ9jLIz2OcEB7SckuQcXNrhMlDCbL6ncSljtzgqhioWrOB409kIG8lc7h6ekghOE/Mhi7rVwAiRfNGB7r3mYxpEXRe96O2RG7E+NcSp8ezl+5gJ9D0o1abXPeFQYGcr95hUioCfyY+xrxY8TJVwdb9nHkYvBdKV7rCl1dTxgsKWK3nlo1T7e5uyiz5YUAE6BrCtTFAqtprLI/xOpRti9C+llohS7D6s8hkCBPZfp3chKFDrgpsCBFLhXN8jrBKSjHi1PJdRQzpJsgrxyeBj0dZx3gTsYOXqrYgdIzFUo7K1Tqb30yNprBiDMr7j0YYXiSvEb7OuOIP+HTXGN+yt09bk9LggyY6Fh0e+tenjQQ3soySN/XznOBpEjXbzXoz6fR1MXVnE9GgaX99LVNqwWfq2rIBdSE/FfspRiWP3BY5jIrEkNeRclS05U1zw3K3wxOL+cB9r2IynSXnK8QcrDNNRZ0W3PhsSFfByUXuviLSEOPuJa1mYP29L9Lj/WyHL1Gyl8xLbt2H41S6+wvIleKMuc7teH6wPXbnYphvbwBowoI6HZTEFkz3dQKhhY6VF/81iCXsuaz6BjyrzFX6SkQ4S3lN1tv4opQMJFvnmHb6EkXqVWfeIXzJIJO+owL4vDOf4okpAD+HPjjlVXhq6fvyM5UBIK9+tzJW78X/zifrQOfWRIhwjVsfUdZWmZ/S35vnHWNuXkM8GBYrDysqxanDtah3U8XLAiIhFtBOzpzr6qGaNDOKKgG3K8QXT4bYHOq1rQVUwzQuKhlCyStrRMQrC5Ry251xmLy6dKfppRarVeGDtzB/30BbtFNdZmzMNG2g+Jj5tFCrEtCMvMiQEWZHMU3tGMFxDef/KKdv1fFTJC16jmaUiCHUZmNjB3EO9R6xPVcMlAVKf57n3efrpRk/GTmm9JhAFkuF/wsveH4JjPpDUdkHYFu5tHbb30sbga3ufBAXbQL4ck10S24akU/cKraFGLvuKGaR2U0i6ih911TBSf3pAfZ3RFbBhVIl+6rSknC5+IXoBR7MRstBPW/xC9pQVjN5Qyn0g3aUjUSI+q4jcTuvMl32NtTJbWRMGhfkrpVzypZTyPnIh6XJkyBghlUARXw23MlbjiZxmY4ScDmcWZRZJWIknHlqjDKFDKNnwrfnEI9qWyMDno+jA/DEQz0mnpdZYEsoz1/qAmAeDt89vx',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009',
+ currentVersion: '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3',
+ versions: {
+ '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3': {
+ header: '####',
+ data: 'GCNNIhDQjMJQZGVSf+95fPtU6eOnFWVhuGm86r8WZGVR2Gf2EjbG1OJ0ZIGpZ/AXgirCMpo5AFxJe0Bay8IYg+xmBqMFhwFxzAgJBYCIts+raSaNRipuY8dTEqDxAqD1cChcG8EhSoiFgQ0fG0I7nNEUDJi0pIt4/ygBcwvAhuAenEp9ZW+oQA0+YysPQRqkz3IieFaOoSEbe5/SqpUilV4q1gTVyzNXvrxzxx+rlvEyGFgFN+vgtUZ1NrwlPk4gVksTpylvv6CFaMGEWKhgMG6efo0rJckKosaJTu1pldJdnmMK4EKNMLOd+jZ6pEhEhYyadrA4+zYU5TlmZA6ASzTaps8piSwZodoi9qY0ch2StK4mAbzeEGe2HdfHuAU9Tyq3Ppk3+VfNdKgpQfYrQOiSlXbKzK636tzXTN/gyrfOTHjBrRl117ywibgSX63ayAYNfcLpKotC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ }
+ }
+ },
+ '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d': {
+ data: 'fGzBu1On7e/6rAoSB1a4fq/CkS8Be/T8UP5cQ93asBTWndSYu2lW4DQ4SXQXSindIi3OnNx/f6SNv/extb7OrMLREF92wXI045ipPwy+DIICb+cQNMJ82Sh4cXaIcAWcyrm+MYri3qq9LBKbpwkILcebZidJ86lmKYHJozUezmfbMcwNCljHs/gYkHVzVcuw9L52Ugc6wC7sjsshh+UH6i4/2Frlrophtx+b1vervNd8eoYiKnedHVXVfW7UJcQoF27eHFgzwYnGvRW0KNXFFhqmPb61TSkIvNdCCvBKDP4SXrWvGgzU89wipvWdUPpQ+fCT6Mp3hPRrbJxwMunmjujZOzBld/HkjnXoiNfBb5akA280WvdyzWYATrjV1ZFx8yQY8G0+lRt/MxjKDc38w4y+Rf5WeRbXboJMvFatwooHUggk6qSRmZVvgOmFmNuDRnRYIFzqK3JclhJeVasnqhR6RiGSowc1Ffr1HhcZCMnXpQABGBkZcHD/zw6YjHRyh9Plw7XAm0xb16HMDtiwt7WLJpxLH/HP99j/A2hvMGWiUiFCaYv7AzyEPTmYbN32D1IsAEE/GC3FG0HypGTBolP8wpAfTRdlvWpJz8oRRdwuLV3Pgpu+kXh5sQyeZI6tnuMPQFmRDcMN1oo3E5V5V585nVMnKTFcXhBzD4UnoV+DQNkG/+iSPybQzz/EZmucEqGEYyjI3kl4MAX8UMEUxE4JO0fF8MzyBI13nxknowAceEammx1dGVaJCoIOdhadaPVPyOzXM1Vp1erVm5k4TsxSx1pll+GOm6hVoNHIuQLDueaMEpRxMhfwc8cDyXURqRGPTgTc0bint5xVjo10fnpX1gcdc/AWL6y3tXM80NW+uFJ4GI7VzyzfcMRzTiRaGi19z8MIx8PbIVGh2sw4FhgGujNsPrpuESvUVT+17M0+v8oEoABNlcizTMFs/sA1uqlPumFASltzmViAzClOsDuCh069hFLjdk/Ex5jy4vPYlwOT8Uq9DJC9ZWuZgiI1DrhWN/8QGAEGxxbvnSZPNCQ9kpD5p+iabinLLWOAirVNgKwIRJRyAu/uR9xKd7J9Wxq8q/ii+y5lGilbo2g24wbDwrkXYVhqp/4J0g+p8Wv1NBjCTSCqV39WEizUCRHo3ee9HnQnBJQDOyTBRuz2odTJtJ5tLYjWXZRdFzFSJrEq+Z1z3oq7LnhZy3YWaFXPeKmBCemMthtNt0nL',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ updateDate: 'Mon Oct 27 08:58:49 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:39 CET 2009',
+ currentVersion: '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac',
+ versions: {
+ '0ae362285f103722abbd046eee2b7d10aeae6a1d05cbaf2081392ce9df882bcf': {
+ header: '####',
+ data: 'sG6TUmPSEPFpiJ5YdtghWHmHbvUK63tZCZ+Q5iz2ALas//jN+lZCBhZcjEwPEJskBkK2R0MyAh14wWGh2bBHMjsokgTe+L+x+0c/Zi0epE/IC9gtOBhsTe/hZ2e2xOGF/SbzET3DAAYXvxduZ36f7SvvFnrkkKvpj8wGSdTFcBmzqMb9DL2bRyRCLGLMzE3F1a0q5CufCIRz2TgHm+Uw+kfvvwC7ig/F/5iLW90Ypz3vmEtMEFYFHZ9a8Oh0rsXGfevbMhFqALoywzihQEe/NiB8dwn7GEdYKSQ35rhvZh29ULWOZinqmg0ONe0HYaxx7DbKsVoue57S0CIUlgHLajzHfLfqQg2sFI0OT8TnHsGg0YZ6mM2EdKmEjJiER0cP',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:00:31 CEST 2008',
+ updateDate: 'Fri Oct 17 17:00:31 CEST 2008',
+ accessDate: 'Fri Oct 17 17:00:31 CEST 2008'
+ },
+ '10f45664bbd979a92f37886f1ecc6e52e49798b16dc997aecd37259ad9b2090e': {
+ header: '####',
+ data: 'RdKVaV/WWWchrCse3KtcXd47Bfm6IAwjqVUpaxoed3HeunI42AAm7xYYSjeK8edHpbNRJbhobBAX5OZtWIp/HmgkobKM8CIiWxrWz89FqyrbnPD7+fXdtgF2yTax/0sC1l0ibncdOuJKX6U829oPlXCpXIOjlomc4wEEAD/5V6FbORvdZ9IE/ME3LsG2y02cT2tIpx6+R6wC/PKXhZA2UDsTE6R2Op2BtIzpVORZLXsdyAp/4wvWQxq90i9cEpbsVQsMB10JVyNHNsRTFhIlHi9MVCaMxQvcrwRElMj/Y9x3RbsFzSGKqFLqdg7Fn/U+KYkpYtsgHv9hraPIb9lV5FH16+iItU/HBM6FGezIj1ZkoQ+dgjPfSjTZzgzDYwyb',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ updateDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ accessDate: 'Fri Oct 17 16:54:23 CEST 2008'
+ },
+ '2fa7b67e569d5e268d2b70b3d4d3a960d7e437e1937bcb324b67d0b9441db8ba': {
+ header: '####',
+ data: 'dpnI2qKjk0+bfyKktw4ZCWf+rWZ12hO5bda39CwD29JH7KtdpLCLe2LoLd+KKF2wOdpDsoI2iTiwRgFpt77e7DoWJABxq/0aaRCVN9XpqZo08iHiYhJyNlIszO8CdEhX+M3AeZqzTnd6fs91VfIEWggvku2Z+jwr0CbclY6FnOcNnS+1fj+W79Z9XC383GOm2ujjfo3SX/fyNQSw8aX+7AgJIRGR9uHK7M1cVfsNNTbmDb/HDgLlYZ1Pqm/9poHpmS7G4HUoRM2/WjI0R6F48dy5s8vZRi11SCnlnj5oRykScJj6wh2DltbCyesiaTpAjP6MQjTXsZzKpaosaQcQClZw+w6hDD2cA54IaBIv2j5KAHyhxDh2ERdwbdnCsDKPz4+zP+fmKfW295d4OY0l1NCSdcY+75HWTmBWRAooZeDTo7AE8m5sRwxewE0Y8J2MLUYsrs7Rl4kbZCiRRHU7cs+us3fq2DVn2OLGEbkRrK3kA9swT9W8ABqINoA79+DmDaIr6TGxe5AlHkCAl5sYAN4g42UX1NKhl4fWI1Scj9O1Ixds/1UUvqzavld0mE2cR9yt6LntjE5sQSAaexvymAJbU5IIM5NTk7NlY7G3PEvAPjcUsL9SGw==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:00:13 CEST 2008',
+ updateDate: 'Fri Oct 17 17:00:13 CEST 2008',
+ accessDate: 'Fri Oct 17 17:00:13 CEST 2008'
+ },
+ '5a17723c34226d8cd663f91b11bfa14979e694e461818113ec8abf7194b46b6b': {
+ header: '####',
+ data: 'yRTvhkoY9zDRBwFYf0G5U8zhfS1XWIUfwes6ADNnFyOrHOr7JZvZZHSgkOPnsmN/f5ngcvFaIV9X3TNTmmPLzD/ewgGVMR+ofMLyOIMGhxUDzosSd1+HKqwDZWneZ6xNsci87W8UCfJgoEGrkAtAwktqyS04pcAas74XiRGBWNcv5mHZONwGPckYUnnaVG02Zf+qif6Pp7ugdvXrgncO5oi2AMSoR8GQxMP+tX53YzLwOpabA32PDT6o+aDPwMstJNQjWCXjeYLDIlb0GjL2zgjglX5CfdGw8vNT5hwGEK2D1FkvHkw79m++9sOWd5w9WdGgtS4mrTZP3JHWC1sPqvsIpq6PsrzRrbfCFH7C4X/ya5ciOIZTCNl4dEGAif94zgN74ueY5BF31PNFtaRaQ1waKkbsrU63MrbQbBar9b0hDZoser3BdgDGb1Ecc2GbJM1HbDITttmFDrzy/Ugh2kistHx7Dci8IGgfT7K94TntRFc5R6suEqYRrmOn57YJTZYrwSgbeTqAt/KOE+gL9LawiLJ0IdSC2RQnO3yu/aOEThHxpdLIKiVJoiEQXYVnq2UpnO79GNtplNnUe1hETQ/JT0o5X1bbENyInUsFjPuitAfChXofkAysIhDOHAdifc0Y+pxOHbQLkL65ZOsEDXWSlwMcduMNdQm4LVx26GLIV6yVsaDN+hGta2CxUuSvEIMM6T5xhaPfJ4K57LVw9MbOjRXpmFQz3QgEr8ZZdUxgE+Kj6CtmsjvzXtCQ3Bv/SccTLJSR/LQ8XRdIcPoOlDDy5jSQDF/8lxkgV1V7M3+SI1iWESPT8My5C+RH32F2MNZzthYq5hIFUB3wsM/AaQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:59:31 CEST 2008',
+ updateDate: 'Fri Oct 17 16:59:31 CEST 2008',
+ accessDate: 'Fri Oct 17 16:59:31 CEST 2008'
+ },
+ '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac': {
+ header: '####',
+ data: 'RgIWPbNN3sPkIPBE6lfvf9/EoDFLemTZe0Qh/1wZLrKxLRNzFpUk9+NmeGUp5f1hM3XjXw4cXRvP6GrWq69mz9zGja+1TA6RoW3dFMpSQkbONcrSD1mIjxV2zIvzA/Pangz0ZixbEeHCfwXLvgnevbTXXFjkti3kLHQlk2pJpM3zMl+rMJtcsefszuJ/0tE/bO7sBcFqcYgKAht2OyDQORBAGiW1kI9USKM5OOfJJIZDQ0gDhRgl2U92l3kIOO8hdnj32oRedwfKFmdSRkuMY7ykU0bMuVEVkLi/FWmhHxi66C2ovAztVtMd1IiyoNcHc4UH942GC4pT1A8YQpIHxBAJbrQVhpl9LfFkmJ7xUc6Xs5j0Nv8+z2JGCnJI/D4nDJqYW+iCYtRWu6vUmbg0vGfaYWQFGRZRk8zWfHzHXBvHU8p0QsIjYgCLKiUaU2SRRD2P7JCjeTUrm3I1OI593iPsEH9J2PHCM9OMQ8/Fsdgd7lWgH6P9jLdGUwtb1hGaq8mg3JGrHFXcrVkUEBfeR7xljeSHD7j4YahYrua9EeR8nvq6CNaOr406AWyHse9SXhaOxt8qXRLoELpyQPsaLgafUpsdLjJqHz7J76Rp77NSOtXGplKjAtU1xj+d/agaAKYCjvUJC8/APJI2890Pn7VSXr/TPc5biPEIopyVYEHFqaT4e5nZW1Ku1HXC9gwUwUI9rITG4GzIH1WMEm7oFLNUaSMrdK/UTdTJZ66ENE3B9v9cTUpR0NTkbI+iGKDnc8GHPRlr2ZJwN4KFTxi+o/kkEOBjvRHR55nRh2+dke75LS/fzHQZw5wlyqBv5ZeUZfRA7QHfkj9acR0fJSqqNX25AUzZQnRL3oVpOxFWCMU7QVf5VpnRm9OIOd/5F5EoY7Be4doM/UV9U40F3E6XPZQ8S0GKQzrDjc7jKyGPLNPLUWTmGB39mTNDHZQHh5Xv5Q==',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 08:58:49 CET 2008',
+ updateDate: 'Mon Oct 27 08:58:49 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:39 CET 2009'
+ },
+ 'b57a2d2ffafa8029123362071c09709bb9192f06a17140440f0e41d22143148f': {
+ header: '####',
+ data: 'PQ53T2Vo2D8PoLI1qNX//jLaVZFTDTYk6geT9+4RoThTxvlJ+beDPnQzgYhd9iASaF9GQEEL8JxsBnNpEPa6JPOY4ndFLmDLyFDKXMprxq1UIbzFV6kFoYAk3uCCCa3UCDzdr1KXB2CiiF9HrilaA+xkm8krAvH8I5kZD+j23gByz5cAFvXg7A77KEURpjujURL65DW5M+ceIjo6OXaPW9VO03xhqGt/M47ayObpoEGJZn+X9C8s0SE5wOXHbn38YZlRI480OMvtDAxbEYUeQKMmzu6lO4Nw5hhOUjoPSLr/i3tmDx3nPcDwnSafx6jyA4y31eW6yazqTEOP5I5ArC5mUrF7mAAiFvbHIsMoF8PLj6MONlRIOZgbf9HzCpFdt8xBrX/TXp3LaSAj2XTWgSTFI2cgmU3qqPyibvIfUsB5cVHQCXi692JpC+B85axJ0FLyMl5w3vq0txlPkf6q+dadPYDaLHGZEmDjkWScA1GM5xPJHWFwqGE7ejgXKG0sMYsMKWYk+F2LEUmMHtEvSlpgJBntvcQ1ZjYQxeu4hg5txu1ykkif6fXgkXF6wn6qu+5caeJeNhWtAB4q7WVD47111woYMdkmX7AnDTXSAQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:57:17 CEST 2008',
+ updateDate: 'Fri Oct 17 16:57:17 CEST 2008',
+ accessDate: 'Fri Oct 17 16:57:17 CEST 2008'
+ },
+ 'b713e0a1e2664ac7bfa7ba887329ea023204d10298973e322983b82b222debf6': {
+ header: '####',
+ data: 'H3gIieYrH7Oy8LEWCZpl9vGp9qYdHNCoBNGijYqlcfXt+1JYvPj1abPp12xLNrDUHfaOZklU2Ip4tOf0CDNhgAan7LYyPqFoy9ss2f9/5RLcbjwiIwSduySIL322HTAwqlzlBt/qaJdHHPUrczmu0fb7fT+0dO4gCL/e/IjcHLefUUgNPAbpHG0Nv0+4lNwKZkIQM3tLRtfJyFBIgWKcMcP1XMic33kr24rwybR8Pb0CHZrOOvvUiGqyoED3ZTZf1twUDVNXO7MWCAC5dBc6/Mk/vSmbbGhppXAH02N0g8G5qzZfp3UVikls55VNhRYLHByVsgpkbIrKXyZnBPTwzm7qefpYAXDOgO+164L66/Art2FYGqZQRZLuh5r8oF38',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:58:00 CEST 2008',
+ updateDate: 'Fri Oct 17 16:58:00 CEST 2008',
+ accessDate: 'Fri Oct 17 16:58:00 CEST 2008'
+ },
+ 'c4cea1cd88a86b05f48a99896a37967c3456228283a0406331ca9f67c6f29f97': {
+ header: '####',
+ data: '1znWPwc9JwCe7iOFiUd2iGm4xJd+824B4VRqEtzCQkW46tg25RWfo7XagvK46USB7t6pC8WMLU0M/EC47KucsfpWUqHGbseoXT/8g8E8GoLnIsk9qFyJG7LGd1sUvqBgszLZwjWWG3t9zifmpW5nY9GialBYNmeSLS3bg5xDH+eCEilUUfDe7zGuVSuu/XkHacv/DYUst97e+6u44F7H8Kv8dTywJZpqbmveNPeWfCej2aBXdVV616J5lIRaj2uIYuQYG7blYJh9KZ7yLStdPndl6h65hIJpfWo0PM8nLJuo0lWNHz7misrutnmxJEjkwVIZ5YAmqp1Zz3VC8zw4IxkXrC/sPmp4PaNXgKz9ZJRaY2KV69WmHf7BUQ3QneGngbT0tN526SS5qDFwTGiuIlnYGWvTB2jVrbns68n/d8Fps8sSWfJBvvXJUEkaZB+1WqNilOPGXvyJ5k2O/iucFbRlxwlEHDny+AgsbtXZdp8cHQ4C/O4G0mnUMZuS38gn6e2kQ55mUhxKeORM+J6Rx1y4Iiu9KKNbxyS5eBpAlFB4xS/o35CS4g309vyOEhi37F24bpp4pM0xEPG4mcc/IyChHzaHUGEp1IX1ZO/r3ut9RIN2QWrGLUlZV/9rFKpLLAy6BkY/g8VYNrV8PztOL3rqy/qwqNZouONwPw8w8SA=',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:01:59 CEST 2008',
+ updateDate: 'Fri Oct 17 17:01:59 CEST 2008',
+ accessDate: 'Mon Oct 27 08:57:58 CET 2008'
+ }
+ }
+ },
+ '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:53:11 CET 2007',
+ updateDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:25 CET 2009',
+ currentVersion: '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854',
+ versions: {
+ '106a1116d22c2395906a346da4d830c7afbd2da9a46210d0b7a11de238016783': {
+ header: '####',
+ data: 'jgDUvByveAFnchBQKhiHGYDNDtj/7Aja2RePMer0FCOkkEu5GRAiLkxA3/DD3eiU+g+mCxnjnOaEIYL1O5o0+JP08XapsblZHTRKfveeFfs6sWwuqEHGYULBaXx4XSfK2B12HgpBwa5aD49489AkuyXi7t/aAXcKKJcLB1sC61DI3NsmajUaXHBi31Sp7nKAUpMuiWyguW0JVfH6KUPqyldVDBTBqHAis37c1qoR6aFHFfGgAfb35+syfmPRgemujMRkj2XO6dbt9zAYlHVSYFp9393rwPZoyBfXMMdDtSTmq7H9qbmx31GecHZlFN3NymtPPDYUbQ9mpPVRbxE9NjtiPrI5eGFvb++OdOx75PKjYjCAPWWFZ+4aryNn+h+yqab7pAuoG03ACVVrAFIOn09g1ssol/vqvalulEf3hAIviedyiNAC9D0UDHtzUwyIiELvR9qouXLZ',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:13:41 CEST 2007',
+ updateDate: 'Tue Apr 17 19:13:41 CEST 2007',
+ accessDate: 'Tue Apr 17 19:13:41 CEST 2007'
+ },
+ '111a8a4b6b912b808a93cf5e8785ca223112628d05f0bfc5dfe1eb40cb72ed8a': {
+ header: '####',
+ data: 't524etHmXljCnLC+IM+WPD8Q5VE7wDsSHVNZzFU4hQzk119t/N/vhtfHYz5HgNstU5T8c7h7RHKvFk5f+4ZwgNgDqSH7H2PrH+7/bV8+uuqbe+/3GYOvELjTF7v3xMyYs1B7ruHpT+291HVNZqxajqCl/+9nbG0e5feqNsTXWUTdLzF0szJuCTNr2I+fhxAO0LRVaf8h+MBPYyuBDnfFDuKm899IsgF9YoYRvjaYO69DkElvf4VP2jrXIJsRnGIUfUaIS/wQ54+X4JBZM/9M09MVOw1SVe+cwG+P3xyPUkqnSb77ECo86C0MktzeYFmPnPv2SM2KFA6slctXsyudoaNlReh1k+6no5J5BjaawTfqYjYrAtWSPsuhxYVsZym/X2CVbkz4rMSn+J5Uio9N5uZ6AqgCKdhAJlwzVb3fIIJwvFpVpy/0LMskb7aG2i4eAxwzx1H6rD3Y',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:53:11 CET 2007',
+ updateDate: 'Wed Mar 14 14:53:11 CET 2007',
+ accessDate: 'Wed Mar 14 15:24:35 CET 2007'
+ },
+ '144d6eff3eb5f1cb70c8906741d88018cdeeae3a618ac4066598ad6b04242364': {
+ header: '####',
+ data: 'NPgSZF0eSOzy0/Ns+15Nz4bjSwh4o7fWYgKgwXLRFrF8y3EdbiOH7AiEmmPrCpT1raeYLWCcDIrRTz+/9uvIrz6kK6BjU2emr8YdyLai+PTCRY0SafWS3QiYixX6DJiKIt0SC2F6dfmSHwNsbfTHilFhVXn6wXTJpWvC+sRzw+h42cYpQp0BoLSuFV7vPz/+wtuQdl28BiBgLzGsrtPud0tPcfldGox6Ia/1SrOPcqUr0tnFlNQiUvPU7N0JZgRNyr1PfpAEhmYRI7aEJidsZ36vGQpE0ZQMmQE/9tLS/InALRZT1YXfMsytf0o3y4QlgJrvRgBL7fGiQOZJpU7igLk15xAwU+OLIaYIbr2xlKDJvndHOcrFoYKry9/A/aZSnEYv79wsaf64bBgIVD2WJGLuSFFmzlFnbg/O4kGTin3A8XBpvFA9V6iCMvnEMkrqxD3Qgf7WhxFE1A==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:33:00 CET 2007',
+ updateDate: 'Wed Mar 14 15:33:00 CET 2007',
+ accessDate: 'Tue Apr 17 19:12:56 CEST 2007'
+ },
+ '1f1bdb7a21440ac20c6d913d676aa30dc360252d27059e77df51a1be36b2e263': {
+ header: '####',
+ data: 'TaOHH6IoHPKLLoyLyvsBszgsPPcDs6CiLVXzXuXjFSTrhPxzUw9suSsisgDRRs0ncjZ6BCyqoCxMnw6QVvGN4viUwYVR8AWdCg0NMQZ+LkNfq/2WN0M3KyASI8sIdMCwTb57NzOn9soB1HmmmETZfjr7HpY2cc+lS5/4f5rxI8XTEK60lLed+aEuJamAjeZUdgIyu30mMKKjxPfY3Y9iWMwn1OD0zF0mAW+hyEoMhhK7EYlWKCy+4qN0QM+yNFXQyERb04o2n4XrM+qr9df1GtbQMH8igK5VzXIrKjdHjKoLo9G7D7mfx6mRLsmoAJuE0R8gyzotgdBpOgWasHJ82iWEa1dLRKBHJ1d0Lnumv22tvYfasx2DIR5Tmx3kIQ3hFieLSXq48cYMiaZH/IbLiapIOlMgtWDow8JuySBLei/8FAV8jCxSc1Ui/SjbuK/kCvywaSOhDVIxGw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:26:35 CET 2007',
+ updateDate: 'Wed Mar 14 15:26:35 CET 2007',
+ accessDate: 'Wed Mar 14 15:26:35 CET 2007'
+ },
+ '70720f026f37b571e9765d27c51d3d60c7be0293c3266f1f987c8de9c6b5c416': {
+ header: '####',
+ data: 'NYaYljcgfzrlN1DVgrbyj4AeVhXGjXPho3IQwEKD3ZOx/yEZxldCNSyFsrk7PoRB8Q1T/6VV4CGa4HLRSB7QVCrtVqWyu4KbbmFoX8NIQ0H3xv+TSo3S/b3dldUeyW32ScaGbspaf8nFf0CffsgpGusd+kHdiE3gSLJvH9y5j47KgpyyX4TteVzqgez4dcXIs5tdzJq2eUlknwU4651QeKIuRSmRaDRhhOP4yRgUo/qXMlTJFmHviCh+IumvBdmDoPe3Vc1vZ1r8PxpDJLvDoB8GTDE42NhqHfVrew9ym1xlTD9wswwIEikfOyTq3JM857qPOHRqSqthEvr4WHbm1VW5PReIyse0lugGyOzqtCnADp9NvNI440VjaTd4NBQqF7XrRm56+1u1uTdfYGFV5BRiH1KmrM1sxXQ6PlOF9Lou45ALo20xxvJOLKG0RKLMr8gmVT2bNtOSJw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:30:09 CET 2007',
+ updateDate: 'Wed Mar 14 15:30:09 CET 2007',
+ accessDate: 'Wed Mar 14 15:30:09 CET 2007'
+ },
+ '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854': {
+ header: '####',
+ data: 'xI3WXddQLFtLVzxJaZWQaw8wAgSuXLjLnyoNXnFuLecTH0BzU36PatglVh2HK3LM8aDLzzbHILdlLNnJ9CY+YnhmGh8hswF9oKTgq0Wsesgdc20QhSMNFFjmMljY1LSXmcAYK04Q5mIzi6Pe/04DRdj+e4zbe5QI4vEBhp/ohEpxZnNqc4BoX6J0eVf6LA1pwrKWvxzMxorWsJrrr+mn3svdlF437n+MMr89k5sQJogufes2GZ9tTvVZ4247ITxXqxgAhwXtbuIs/A5UqqnNdsxlHfpLKG5KjxB6F0h7TtFA3gkZCve5UmAibBnoBCFaIVWQyVq+VO9iqDm3DeXsK2pepvgIvpSID8Poy+uwN7T95mivAsHG5p7MtgN9KwQzNW3Iu+BfO9FlPBMngSk8L29So2CIXe6lEsXSGEi5Yrgyo6hZi6IkGCXwIQ7TCEMnlQEGyKnnAVik',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ updateDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:25 CET 2009'
+ },
+ '9588b523f39cdfc14efa1e15ea7716c2d8eac45d8efd7bfeb19d716f9df72d66': {
+ header: '####',
+ data: 'q6DKkxhgDFs1XkqOYf6dvojPF+yhJbniTLFpSOS+I1sum3EZIJfYxJXyi2Jx3KOVNBMILw1+vrSLe/fh5SSWj8ZBoeppkPPLjyRNdiUyd4IfcRM5OSv2YcTxCubKCH2kIMFAzY/29A6ZGPG+AN8/kxkEHc1fxKaNcj2Cs8qejNR8yK1iKT1Ut9VfEee+Eqy2Ohgdq8wL/xAD5mUzdqHeQl8BY16pXGIYncLxMzR+EJ8E5jJTuGv3O41UbO31lvBSfCt2pfz2MrtsuqNoI8LBHJkcR6t17Bj+rHZUniHlyxSW/1rQJ1NnwpPgUJ1fhfQJZM8Faoif+0bvWFY4xWs/tCCD7oEvf0xM0I3FfcJLbYX8M+wyO08t9BmGdEjnr3VUcuS9qKaJRpdpMP7aQf+vJvioeQDXdOJ6Ceo3BDFc6JdNta1Qc+agGzN2KPbIPrLDL+08hWl61yu3GQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:27:35 CET 2007',
+ updateDate: 'Wed Mar 14 15:27:35 CET 2007',
+ accessDate: 'Wed Mar 14 15:27:35 CET 2007'
+ },
+ 'e5b71df0d4d79a195c7ec3288dd7738069837a7c4da3bccc1ebc05d8e4f19d79': {
+ header: '####',
+ data: '1NvK9Y5r0Q880BfB1W5IqdOR77mmqQU0d1GL1XUeQT75R2EgYE9rK1X1jLygCXboPhxzegEe7TDhUsn5XcHN0LkXcLYz8gD/7+He2HiTFxoHd2oQbI3ceBxDJ7+5kWA6Aiqy42QSCuA+TWIQcDVthSyFU7nNdqNxeBYeXiI4jgwcH3xvm0+pBf1OYLtywjUK1JwntP6o68b1LMQJFinDG+sqRcm25ggaZyxDtoLh1IBdSpmXk0papRnyyTGNgsws78dLxnH0Iqxb7FhqYfgLDIvN3i7+IALI0lF0EuTS0hSPlr/1fTz1/6bVt++wI9GpUsrdafUJJMPerXoCK+gAP8EMneLq4f5487HIkwWh1qON6Hvpg+tB95NOSJpqE72VpVxN4+wTQWyDMhfjqXBuQ1wKvTsD/mUsdinU0Wb/YT/zIWBNZPdqur0rjOC+mrOtSdlYSCH89Jj2',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:15:09 CEST 2007',
+ updateDate: 'Tue Apr 17 19:15:09 CEST 2007',
+ accessDate: 'Tue Apr 17 19:17:01 CEST 2007'
+ }
+ }
+ },
+ '36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113': {
+ data: '6fhueIibbxKRA7Mtb9TPcWiUKajnikM3D7PbOROBkE39Vw9E/nG8KrtJlwwPQeOGCFhssO/KX3ymYehCR8rfaEL1f9pfdh5x69mSxKRlOmtEknWqUgPzcb1yPenRbQagERadh0LF4zu91M4WjXK9qynEHoxI/pBhwQb1IsnhwtXl4ELtajudv+2Hv3p75v4XOXFsGQMsHPY+Zw7dkFFA8EXhvuxjiGvnxCUkFwNICFRdHTEovkW3VSerLdrYo5lDgjY6ebr/g7wDGuu4RLfUK4+HpzFwZ0+aOrjpFq2ePg2xObvkkMNNjZ2PcR6Cue0sf+aNqzIHIlFPpY2Hmrob8+bwxocKA6aagBu7z5GiUmZNXGE/Vtr/WWBV2+xIJyzXZPet0MLmSnGiALjPJveeKnnFdDtA929ydcAb8efc0/snfU/uDoXDiO5SWEQ8DDNjj1bSo7VPTtvZyFormE1KjqimqSwaUJzbIS4CxPnoDezaBtQmlG4z8mc8jXq1HfPu7s9PUzcbG30gbF0ch2pDj4h47AhE0ZoeiV+VYZTaYateSifQXKBQKjPcuh9PQyDI0HVua3itbbwxXpRubEM4fbvlcd+7gu+Zq03slYICD07fP0I6XGrRHVTfYpDbEb4GJBvRIeZLwRTQzOeFbPLpBU9Lv3zXxfHfcHy9oK+giIxefPdY1ZR2ZFPKOO0xYJsTr0vmTuXeXzy56bKl+yP2lFst5l9QG8j2JcQEotDV1KQS6mbcLjfIpEnltu5fc2t10Q25Noh+F3kF+LcMIYsDjwanojYlOC93mZl01hmSJdimRTk9otjlRTyC7NWwiyy7fe5IyVi7ACNPZyeUYJUPtKWcPbT73Vtf8W3/+HdhmyYNyMQ9PDCBb9WKMon+qW2+ZVH5yv/KqMHRY1fflAfxpHNhrCkwqcAAGw+G/cetbvQjpkfVT2/u/uLupMsITN2Tgvr/8D2IMm3cyDBUCshrp0AfzARRygHFK4x/0uLfCtQSNjw6zMK8mn80R5aS5bZi5gRS8JBMZ4Q0iG4kBlLpIYtsXSBwl8faljjdl/4XvNNWWrdGJn2k0eM4cESlOFFk4s3Yu0Zspo17nKAHINjHAiP3VlhuKSnk5C9hMU5i3vZO8anQmx9UEwUgQVm22azCjyNtUl6jVPYSNsal7A==',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 18:39:35 CET 2007',
+ updateDate: 'Mon Oct 27 09:16:14 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:35 CET 2009',
+ currentVersion: 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463',
+ versions: {
+ '381201fd3b67549bd6630841e8902be1499f3ff0c3514dd464ad9679f22f3561': {
+ header: '####',
+ data: 'DgjIW4YcJAYnckuEUzBFkfEC841LuanGopPgp+YkyMn3xuzdpGq/ObLFMVQaeAuyErh1B0REHPbq0E/SRUZbeXLXWN720GU4GXvY5bnen2h7pHvl/H4yz+kvyKh3EHJmmBjuz8s0kclFJQB48lter+G93TEmUaFke9c9m0IkKlgzwZ/PQKZyIyfZA09KFaozdSxdFRbswZj2Vq8Df2PQsKLapZWX1wYQ3lXOcyvNdTULy9MCXwPwX6te6hTLWxQOiSPsvB8LItlhQUsSbrJcJEvWPlBupPu5SeI25zDnqKDETPep63Ks2GWf45nXZzYYmQMzL0l2cenYFxlE18TcOd1Ms24TQ/iDKMhi60zZoo13qjVT5AKZ80KNu46t08qbACxjv/LeK2aM5TNycTFixGskPywpnb6MCo8ibRe5rs1WcTJRMD04sNoiuriivO2fiyo4rxjfdyfueMlOz+Zeztk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:39:55 CET 2007',
+ updateDate: 'Wed Mar 14 18:39:55 CET 2007',
+ accessDate: 'Mon Oct 27 09:07:56 CET 2008'
+ },
+ '99dc86ebeb20a3db0c5393d6d94bc1150187b04316a876970dbbcf517b55d6f2': {
+ header: '####',
+ data: 'AJwqCWNKC9z8DC4TUI0hWnqHvQ40Y/x+jXylnVAkyO2QYQcqg51odLFSfgP0GiGEGPYwDc+kUxRrfO+ITgTNm+hHi2iIWkP/ljAC+AQ56MAEKsU/USTbvl6ShZ0XTAdRpwI/oqqOhYThVs6jTm/J8+lx4tWoMtNj835py88c/9eW26pLQubr7VysLSWuIMi+iDp7zXZZz/0gxGKDe5xNq4MGIYw8/OK1iJCOsjBdrRygLlS/Mz9sRlKkwdrDsohtRG0F/NdsIoaU4FttGs/rY91SCedvHy6ovh0zXhxOO44O6MiMbP085D1jCjWJn9S1RBxjxc368MGfMJeZja87nuvgSnLS2tGDL6zFtVJMNcH/7GqQPXZv/sNEykDNWpypchCnwYUJxvBVb45FcUzagPm+SSiekWK1hrEntZkZuEhQZp7Ud9RcENpa5h7wXUJSV1vPl8xBylx9HWmxez7D9OYRqbOlCRAEDqup4ahNhYB9',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 09:09:11 CET 2008',
+ updateDate: 'Mon Oct 27 09:09:11 CET 2008',
+ accessDate: 'Mon Oct 27 09:15:58 CET 2008'
+ },
+ '9fbfcd3e7fe30d549a813f0e6c1be58ed45c3ae7305d7367bffefa097b424ee6': {
+ header: '####',
+ data: 'nZ+Lc5LWWLxnPvUrRrHhxG35PHq7GMbVENHfV1oS0Qw7/63NecssNoEbiOwFVMjAshvfUK7IjnzyvfQhNtFRbj2yzHOTWCd0eJ0O0MmvGzjpUntSDu9/G8RFeEu9jDKugwi/NhOa5legjT9pcsEAqR4s4NN/Ac6juQb6D/Z6Wd6wO0JQhT5/QPk1KllDpDeo2i/GPUKvEi/dXpik0KQcVLVylU82rf6hwEgvRQi+j0O5hnFW1E4ttxClrnPBEBv60jkNwcIpD0r+rvomDe8+398xUuB4DVDJoM+WUYfu6Sm3qI0yBfET+tJvjn8WsHhKTgZpOc2BXC7EdF99nNEg6kV5pSxV6AUA1XUz5kW+YfcSzAXzUH74OqroC0SucHe4+BtRKnbJy4h5vRfjTD+FJaj1Va02cxSR55tQhxm/k67z0QeyB98dnU1l/pPHwBlIWa1eR74gswNSeQ2jrzu5JeQ=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:39:35 CET 2007',
+ updateDate: 'Wed Mar 14 18:39:35 CET 2007',
+ accessDate: 'Wed Mar 14 18:39:35 CET 2007'
+ },
+ 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463': {
+ header: '####',
+ data: 'm3yhZu81UAjCY6U2Knrgg8mK+LX35Y/iZgIEm8MuRDAlg6UUz9Z1Anu63COFV08YyYQRuBzTgR9YQ8wrUD1S9FG2ZmtCDemqvd+5OUMgdn4sK7G3CuzAc5osOa5neU2m4y19WuobkGnhO78ko7pVVjO42q0DeMT92uFL6KE/2UCkWlq5SdFyS5qXEJEWs2IO5C8nVpdlO/eZ36Pl2+v+afl3QQMTthCVIUR4/zVP2ajbO48yjDXhYxzskFjtXMYLApEn0wO0dcifcsYhPkozz6Locrt/R6IZXnfZfuW5XXHbqhutoJFPK6L6t0Ib3B2r1TNkPaMsVs2g5V1g3ENRd0IlbG/uBk2o5tgeu6gOYlA1scEiL+/ad9ZxiqYB2ENCGZ8DXA4VNMnzxVPbO96OIUCb9suV0fldGOg=',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 09:16:14 CET 2008',
+ updateDate: 'Mon Oct 27 09:16:14 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:35 CET 2009'
+ }
+ }
+ },
+ '507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a': {
+ data: 'ncSFmp/+n1pYUKi2fwhMCevSwFYO5irdcpOlSxC6YPOKYavK4iUbtBsilYWd0hpvUHW2ItaDwiyNFxs2Lwegex6dawKrpMYkPBcaZQDa746yACGgCkhz4MAGnUn5HCmz6xhpCVXMMKe3w2nEOjRB+pOMOeJt2n7aw0hCJ9tQ9JTFNrZOxeXrqoexrd210Rmr9FnKhLIvhNTN1/vXRqP0ys10omJ2mowzF4KoEVmz3ET6pS2d7tGjt9M/OYsH/ETWWc92doF5PO84g5/3HePaCo8NCqq4ul7AWJEbdnkxxmd7urJzIscPQPcoLxL7GfG5LhHTFyHlfFz9dNlccfA+OPftjyfjXTjLYZzbxxbi/nAB9Esqj5AoHfqaJM1ZOrZ+qAvm8Am3+HAXrqtiybDITrCLmGH9ukWDsx7R3lYTlvjArwORBUH+4w4/uYGscVm9kOYj/Rmz/ZMH9JibYFcPcOnr3rWXPFUL/XsXTrm9lzOvPyEYJmkENzd54AHC4Lr5vHpeuipWFLiJOrtn2WcgDG/DdLaYGKsmISXj74XDtP6Ee5lKOtbwwcmVNrl11UCQBEFHNybhXvpil5laKddOauLJDKtaDL/mKYPbr5YSk7HPCzRyE7HM2dC1MpBHuJ8g+hDkgU3wQcxYduKLRpuC0uOqrODigGWhVrdiKdZanlWUq9EkE3eH+E2A/CA8mHl7UNaH89XSvgV7uZyOmK7iZ+1kd9OzhBLQdJnK9qqP467Y14KsTt1E1+tqlqVAuK79QMnllaR0e3ztBRAQsyf5SD0KuSGXWz+z9/RjbhamW1s0UFRGh3voQMypU5RcYfYUA5KVg0BiVKFaiZBZKLo213hKbrgE2KoqVDEmIBFmwsu/S3EDzUY22tTB+o8ZKQiYesAUafGtnvsOLa+h6weF1ZvQVBerbD3fhb2o+d4ZyPkoRAsop+5it0QxsWuZL+J2oWybaikxIP/1ZM2ow4QZLaAVqihyHxqhF5UxZ9zrWxfp34BIPzzU9esSifrD0gXZ3mwutaCukZoijnGODJZtFOy9Rl1gyS1IbpyRbwz5O/YRl4BsD2aOk4InajT13Sa1BLPblQcrau13aeg/IzQhcUJ6n7enkrqiJFTP8N1aFAuYv8ilu0V2ymIuCLUtc4cbo7KyA+gnHhZA+DjjrhG/izOyWtQY/WtDsqvo/6ILwFk37JDjHfkchPEVcdl9qT7goG/4zTGX+lx8UTKKZJjJhLjA',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:01:24 CET 2007',
+ updateDate: 'Wed Mar 14 16:01:24 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:11 CET 2009',
+ currentVersion: '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b',
+ versions: {
+ '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b': {
+ header: '####',
+ data: 'sgq3FGcsnlbhTLetMa3TQQE6uFZv/JL6Awha1066IimKoAtQGbAr6E1+mxRmvJle91sL7oRfi6suvDanYHfAI+rrG6qCOtESn70ssS+aGFyO3XwFgypzG/Qa34bjxJ16Aqd93H8IdhzdtOxs2Qmou3CjyxbT7Cq+YW/fAo1WfctL4yE4GBNPWC5lfebxSmINlBY+zTjhv9Pf2aK6vL4p3obHl+zhz0YdKAMBwbDyCLa9tYvhGBnq/W6lFUsyZCPVJJP3bQCQww0TNCcLJLm+SYVSiC0NwCQJq+yNqDkWTvv41p5EDB06eOQ2VqC7l4i/JLE/ql9h9Z++gck74/Qs3ppdVdG7sTzWyPya4v3RW2OTc1awFRZipAX5Zd7I97dyw6Yym4y+/9UT8z8iMDYykQ4+QnOhksDIE9a8q6agDF/rbZ/BCRcMWbFylGTdudk26mu0GdPiuLDu',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:01:24 CET 2007',
+ updateDate: 'Wed Mar 14 16:01:24 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:11 CET 2009'
+ }
+ }
+ },
+ '5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4': {
+ data: 'Xs+z3VzIqsWa7dGBqepwq75lTsx3yemNhTdRYYDDc3Kzpycyp961SgnKXHjE51266mfmj85ASFi/FKCOwk17lbD5UT3iawtc3TdgrQ18vBhBsmOA2F4JAa4yC58bTaXbyld3c4izDp7i9+iyRaFN52NWJznN82SXuRtPdWRtAxXB1V5Tyg==',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:45:25 CET 2009',
+ updateDate: 'Mon Jan 05 17:45:25 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:21 CET 2009',
+ currentVersion: '00b3a4cd7400cfc1e7f7b369bdc3dcdaa50d6020233e131b30d755c89249ea9d',
+ versions: {
+ '00b3a4cd7400cfc1e7f7b369bdc3dcdaa50d6020233e131b30d755c89249ea9d': {
+ header: '####',
+ data: 'uGAV9pZTjrTwBy24TX/OUQwGmgzTnXv1JBIxdGkeoLCUhP9tAjbpUVylrUI5+VRrFYkXYyZ0o2HEgKrun2f3PODTxlmAbfkUldOV5tyV/EUxN0vYSBtgsMpqQm3bOKRIAo/uzrhSE3iwMjvKOTH2jUrkmX6hmqhXWZfa4X231GovrnOjek8c7t+LUBmmIjXEr2GSc/UbBoFnni+Q7ZArwtU68xoeCjLame1e8Y9wvCO8gIfAzXQAHsDgzn1MVeiWIqiCBTs8YKCO1yaxZpkzXV0yWzX+bHyXlKWwAk7Fu9w0CuaRULZmRCQhv+MMDw8DEXciTm0R5dRiVmSCFBy8cL9qlSeSX0GlnKl8E4/TSqvhMJblwJJsgmGSZ9cEt2u0E08tHxKuoeaaT1rpAOoiqx+z7BdhqjWOQZOGM4gR3EwqvOQoNYFUaXjAdmiUzW+e+TgE1IBQ8udRFl/D2zCcqFO90Hgc7hHsTDI3aGYvi6bHADu8hFpmZtJAjOMv1JgCX4Hm4n+SsbHd0DIfkEUMeGlVO47lcGWBZNRRm7xl8luZ4sZn',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:45:25 CET 2009',
+ updateDate: 'Mon Jan 05 17:45:25 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:21 CET 2009'
+ }
+ }
+ },
+ '6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728': {
+ data: '3oUg1TD+Lu4ou06j/MddOTXDqRM+qSKD+6Iuzia1Hop1w7v/BXidqeoKJZQI2VY9oO9B70Nr3B3wDROF+ycy6Rq+FM/xqUGHKXn1lAaSc6Wgj6TLQ6eRF6YZKSPqTj7TDWyw/2pEWk4HjcT8drTrCaC02tzAXMhYWlYPQPW4fUdq4hawoHIdopUN3vafQuFjY47OhqXKav3bNao=',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ updateDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:33 CET 2009',
+ currentVersion: 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc',
+ versions: {
+ 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc': {
+ header: '####',
+ data: 'fehYRMkg/wFj2t/aWu7szbXwrCyCDpjQN4UNck4/OiDlth70a2ve6ow5lAi2jgdlV9WiFrPejfa8dD0Z1g19jx+BBsuUYnBEKD0K+NapdJBBeI0We2nj9nYIij2dfZVx7cuvhy8sN6+DdylUQLsFHbga+Gi5hWcMuULT4GOAIy2WanSQL1RSR4ruA6zm/t+VVboEkkm7PPT+w3LuRl3wRaD4a8ZwYiSV/SzgWooFrh2S3YOUeshdaGCiYpTbXscsOxsCxc11i6wQGBqYSjksmtZDvEegdQdzCmxvq4jaVWJElYYS3av612nD5K/w7Zei6RccBiODBPATjrIczYg7HwmQxIM/6QI9/LQn0LP0yqRVUUtfzaODf0uWNpFzml9l/1lwXuBJyQFBp7H7Th46ekw9yEuPD00oZ+eXvKwbwfUU0JshT4hnEBtIjM8fH974PU0y95f0yLAJ1+M6DVXCxGsBix2aKJx9fuZP4KGpaXg6qCb/6327rph7MGomcrGPIiDjYwD/NTMdGluc55OZfGXtOZUaJCUM6nihqDwU7Ly1ZzYorgcvkX/t/0RNcOkFzGYNByp7mdcotyiHqCDKspqz9mEXAd7Noz3HO5GFpPqbRo7htDigGU1f7dvgbbfRoTz17Bt9Mw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ updateDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:33 CET 2009'
+ }
+ }
+ },
+ '6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a': {
+ data: 'b2mcYUi59l434kGl7ij6dBu3063UL1dToMIu3Zsa9RV9RzeLKnezJhLKunqoAm7KwiJeqDo/REexHI1cshGYtHasVXXuyJfMx1grH7yhoWnkSRF4Sax6w5E5wnGkEpGJHOxXJ9rOjWHZ7yqCUUCB/dqLw4FwPOtRb/ynkBEYztEJA6EKGJuz0vrrTOsT8HMXtj/w6MEZ7qI3fPs=',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ updateDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:08 CET 2009',
+ currentVersion: '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3',
+ versions: {
+ '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3': {
+ header: '####',
+ data: 'pZEWSdYIkrX8/r6OYmO0GEuKG9baUgn40Bmw7hXZBd/kfWuRjWsL4/pc5F5Ojrx+N0dxmQn5ZqKAzOOri29Rm4ruxnCbyK+oDsCDyMSnWy/VJcvystnDKzKmBRQVAOSEJtzEb3OtGzvqm0PQ1Dhx1YUAx7L6KlXysmG9h9+MjOcErRL9/1x1LZ33ytR+zK4LvTAb7gN5/9QgwysFyCkNP8bG4nyCzPMiUrBnP0odMTUvDkJDlY0Oia6VjGW6oNxnGIgA5fDraRrW4JH2oejQcrL7+X+jpCp05g==',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ updateDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:08 CET 2009'
+ }
+ }
+ },
+ '6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18': {
+ data: 'jzjPgxRHApIJA/6hiY4XCtb5+eKzHlOeoiGwfVDvip95zU7ThHbdmxOUomeyCOZ3S1SGPT4lHvqZgfVG5m5RvH3JaAIa8EY1ZElRohoX3rETVPJzI/Ov5Rp3lZjtWlu5meNrcJz811HBHrtBuJxAmSjYcY3CCal+oC2zcK2fLZR/iOQ+69ONVFhdV9KiOqzNf8IisIa1sIgFopqsdHXiZ9oLe0a7Y56q+OplyU3A+TmxKLI+Qq+WkjvdMzZDDqzYH47me5niugYPdkQwN6WQUE0sK9QPs0uU4TOwqCwN9nPH/DoQ6oXWAu2+R4iCyt6ZjLNkClbps4s8Cwz6wfFQ+4T8bcldjveJenmrYwiUzxSd/4xa34yFVXVw2OD0n8yZhtvNFvfoPy+X9z+Y4f5HlM0qzL9zYya4KwWjFQzhOxFjni9JyGM2PJ1BctB+q1J+CHuhlVjUF0Y5zIS3zFTET8jjDGBZDWB+Ao9E8fUD+0OJJUdKJ4kUfn4ZUZUG20eLBjmJqWBGYZX7UFaPv8ksahoK26Ol6FnBE4KpPStQeDgXZDzGsiLlEsxHJLUFkNtAUXozw38bWWQvi2VIFtkw/ZViPIenmSNT14kUVWdrlKQC8x0+wECeh5ffv0i8UUw3v8QC2ZE7GV0OMl4ySlRCuDCfZ53YFoB3HIR1hSZMhHlHJDPUz8JOuXdHcUQaJeNrfWoC2KkKb0ZecBj9iXooDh9yGi0g7TS7eyhlz1LHpzEWB0CPsZqhNGMxmfFWur7v2hrYzoHQOeB19ZSmWzfUwd4dRpqMp0x1lZaF97jr+yyYhnuQvuO6lru15Pg6FqjzhsNiLtaqtyoaMiHZ9veZs04qZZ9Fn3U7HeJzjZSAssdLnvopXi363cXm9JqoClyV2OemnVoRwOZN2gdSZxGeOefKR7U+lrBAbJwViMnmT0Nd7AC8C1k34iEt8HJmpztXeOgX5CQpwUPENMCUPsookFbIh7e4aByllEQy0gBbxUz8JMIWYyw98hdASnZ4s8bQfSmiMM8Iw3YxCexKB62LYYJn1UY51NSnwCtwRep+NhaKDk2d6SLh9owxnFbjhw22RriPd5f1InJycjtpvMzWLavl/hDsjjj1kWpnCUBTM46LbERmjz+s4x7fSf2FhhguBT36elz69ivXoiXI+7p0E8f8HsSwm8sgN/AA5m1svsXsdWeZFUiWtAwLg0tI8YNHlazbvFCXfIC6Uhq9eDv04iqdZ3rn2c1rwSx336A7ySTBFdxOCJ46F7ShIhNKm2N+5Qf0K5B2L882fbwqiLsa64+X9aKvufKTsd11vyf19Zivg/Ze0FWoGC8D63Nh91k6Hu32RT+uAtJIjQIZxu9yXJM9lMaRA8ieER+ghrLHaGQqF9J3WmueER3UzU1midvTynOV6g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:09:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:09:05 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:15 CET 2009',
+ currentVersion: 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5',
+ versions: {
+ 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5': {
+ header: '####',
+ data: 'BbXNAy0GcKKyDPiwhP1Jk9mIi3uXMHQdhuxpDvoR2C3YITOUBpurxGhhvmCg+a9pS+fKJdZPxL2mPbJj6GfWTEsm7K/ECEjrVkSTHi6PTUUgYVbCumq9EHjUspos+7VrifZry3c73+qAvIKamvUlNB86TchMpOXVJIyx8UgRX+bdhrxk9ZCEVOiLCG1zGPX8IzmcxPmBRZFlHYqE4ibhl/CLEzWXZBYCofTusClhOh7YM/jBgvDt64W7aIN2y2KiKwmFySkFZdnOvbAb34tXVimwqjqWPvPwd6MujQeX1bmaDD7Y0kXac8CJxqasIezLo2WqzLUbEXdIHGilkaPT2ZKpKhKkpHJHFrV2lVuQJVqwPUr0Gf9qMKgVnsyU8kUfq9ox+fhH70+v7BQSjT7bxxDLs0UesQeL7G4SqvNet5hPI4GQEpOY8p5MUFReIBTRm72NQEU=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:09:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:09:05 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:15 CET 2009'
+ }
+ }
+ },
+ '7bb69b6366a8012f181c01e368ba18d4f7a82bcabb4959189736ad124c4bbfbb': {
+ data: 'wYPZIt0UHiNVefNwtGc7z7Lu3YoQrXdfKmWqilZp8yeIrNfSLB9p60DLMrL3GDq/CsvDYkGAZgj1C/6NVnzVsXsJKq7NDZn1UPOGt+hCnw3lEVbD7zHkoMM4VgFDn1sZdjLe8wdpIFfdlQESTipT3GVXv3swG2qX2O2yuwtlopR8yZQTLg==',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:44:30 CET 2009',
+ updateDate: 'Mon Jan 05 17:44:30 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:18 CET 2009',
+ currentVersion: '23f5fb503e54c0cafe3d4944ddaf40bc74fab8b5d96e2bbddf693b1afb225e5b',
+ versions: {
+ '23f5fb503e54c0cafe3d4944ddaf40bc74fab8b5d96e2bbddf693b1afb225e5b': {
+ header: '####',
+ data: 'IpYj+7t3DhSVD8r9PkLbF5xpGrHhg8omY014P1vkT2KkGDEUj+ekQAbQ1g66Z7oNhRDpjS1/dcDjzH0IIQLjGuQ0oRfL0xZefVTx3N88ZLE39m3cJz10K2xyg3xp06jFBmdNJuCkgRhMzeUXeEJujw4lS2kv7cO04Uh2Maui6jDR7E498rgePY3L32vG1S66li/xU1vPjNn06aFTqSYxUL17/mlJNbgp3XWjGC+l0dXLLfXy1wOm+/I3zp2caTs+a2zDUZ15s+3XeaAWpBH7QCaQsvsQmoBqPbMvkjOQwW3taDvV7Hvkh+qTjCEcLjRFwhZkMNn3N2ewcLWQa2aVIjxt6Z0F4s/1URztWlKVzCfto8RmrLajYRn3ggG12kX2xDJFjNPNfs/7A3tMn+FqXQCCNG5GI06JZ32aQfpnjtmXScUuEs8UeFgsNeYclQhcm5R0sUwISK+D345B8859w+4+9OTY38NgYQQ9o/tmpCjWj1tLYLx/m/GcR2em7iyDpBdcnWUb+tK6Ah89qvXriHwPLSNzhOH2wxmi7nXTRQWMv7g2',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:44:30 CET 2009',
+ updateDate: 'Mon Jan 05 17:44:30 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:18 CET 2009'
+ }
+ }
+ },
+ '8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39': {
+ data: 'pOMTY3PnUAbwMLDEYNJCMzp4iIA42YWr6gqoomg+P40e7LFUtbt/RQRelQwNIztyUSVLl0rilkZZkBUVvxrtTqvibKITCjJQGQIzvcb+Yl4mNosl2Rpp0xxMU03f1+G7eGbuCc5hJXYVAglhEYplaAPzHbRWXMY8iZXZPBuLVf5PN+rdpgAfkGeZ7Uf9RsQ9p/EglrWXYnTwXi3saUfzIjfvSHm5C+dXTY3FHpIc1YkjFrdVgMkhYQGV60JtZcwFtCEL2NpVljAbRgHoIXTOkzUvep4vxrtfBBWWMuAWEI06432gtnH6IQbrR6jOpwuMt7k/09qy/fARPHs3r4qTJ9r2uqWHJ7tjJw+IChQPC+3l5HcPpFURiw8LGAN1NyY1hUrF6N84RSn7AKS0bLa5qN++5lcjjxn/k8+JqmeUqN1/SYIbGwNnJeZ0vA8yvOxnD20iVADX5kOVqJDwXRPLaF6Oz9KkbOrmANCh+PmGw1i6PduB+FgAU4HViYCw5IGOUZ30Pm1NJofqfbhXvgzn7ey2+kUIAwDyOUpJ9fW+9jW/JU4rcawmzwBYN2V8apOoyc3wQJICm2984wIfVBpygCOZM0QDyVgNo57qKtYH3yMDQSkKvpEUmuhklMYhcV+4X5ggdqx7lYXO9IMDnFf2ZDiZyieTlOlRv/nNVecUB177Xpnq2e+X/ik2rCQWVrIymiV6ltr1DEv0krXKfvXGG/FMZHUmo3m+B5bG4xVhmt0GnHseqvY2Vrl9NksLgq3hTDOGSGIy5Nv8kfrd8B4/6Tavh0SumiyXnrTXyYXzCK9E7IqO/0KAln63VkcHsbOtS8mj1drN0YQ2KKaeIW+Yr3Gm0pbcODsgA6aFfz1itZVeovBqUklhXS+/Es8J8xOSvvSyD/TmlFjuErHa+wwNQvftosfwk9ZTt0eIJS5aLHdU2QsCjdfSy0DEPkk2siGhBX5ZhRzqyIAyXApSmy+e7PIqn/dDR51+D1ZHwoTQyTrd+F08jBWZgU/OvS8MRxNZSxQwsi7bcWZG+w0utrIDB8eSOMVBXI5XBeJb4h5Bzut18C1shGHeGkSJp04=',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:10:17 CEST 2007',
+ updateDate: 'Tue May 01 01:13:27 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:02 CET 2009',
+ currentVersion: 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8',
+ versions: {
+ '8a032b53f7356e2d8b28665211abbe2cf1c79fd8eee4752e83cebdced1c19911': {
+ header: '####',
+ data: 'OXpNHHSkdsaD91hw2LER+9XKpf8+bh/O+OcLSgG/gAx228UpifOCD4HTAOs0C7IJ5zhAq1L9NjCGb1QWWTFErYEtDEBRBV4kogscP9HWPxYyZHxjwPI0wE7Ri2eD4Rma76Utb+xVnXWuT+vNb8eRUCK8Ur1rlhYafS0uzAYvVqHDNfZaICksxeVQojil/kSPZDMu8ASz5pMNFNCF4SlwDKPRrJJDbNZ62A3px59YJtsla91DGVyOLhb7VNRxEwnXyxENfP78yA6OjvQDc2KhKFUpHbZws54IolLK1I1mY/Z8BiDXPSnOa694Q1eZxy1Kx/jLINZUIPgGg1++YWITx213awOISdf7Oy0/dUpu10Vr1hgAqCVlDp0IuGK01CswRzEdLVpUk1DaGHuin1rryZx9vThUkEJgQQc3ivr8',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:10:17 CEST 2007',
+ updateDate: 'Tue May 01 01:10:17 CEST 2007',
+ accessDate: 'Tue May 01 01:10:17 CEST 2007'
+ },
+ 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8': {
+ header: '####',
+ data: 'tvSUu+NPKHkwt/ZLXdLGdDm4jSxTEtJfsecdpjJ9UGN3Y2EBCmijU5i7q+hMfNDqBJ4/m5Ayju4zYDAKGp2pt8l1TFoDurITdFcV12jL8j3dc4TTD//uC6OtowRN+altgC1Xc0LsSvEPabjAlwfVC5xqirfm5t2mVmnFZ/GALkGLGxRJRduylT6goPwfunkVGwUdqMa3md+9mwYn2gm7CyC0lpcKX8AZ3B4Oa656yRa9m3Wjgb007TtorLIpZO2MzVwxcHBqqy7YpN+zpmZz6Md9VK3L4F724tuXXWnDeVzGxBO7aZVr62hwPMXM6ibCjUScsaS4f0chivA/tBJoyx7OqKhBxREGeGjpHTeLxyHcekbwXhXyeqxBuwG93yGKutUhGLVYcXwe8/+xSeaBGj/j2RWutKbNKG2yQyNPGj2cxJWsR4YfOQJTSOSWT3K6Mmf+r6hLhIo=',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:13:27 CEST 2007',
+ updateDate: 'Tue May 01 01:13:27 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:02 CET 2009'
+ }
+ }
+ },
+ '9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291': {
+ data: 'xXZUJjgxn62OqnzAvScHJNo4WjYEFp1vQ4ueBe1sk8dH4pXZUKV6m9c1d2cLUgBj4rUNP5cC66GiFHV7G5BDZGLrfrxUlYU6BWvzAz4eG463pRDhHXQgPrhlIGDlK6ovaIsjwaifvHaEfLREoXvLFluqu406KG58guhtWdIFK0rLypyRo8uyltGbTz8wZdu8atY/JYQnb8NaAf4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 16:29:06 CET 2007',
+ updateDate: 'Wed Mar 21 16:29:06 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:01 CET 2009',
+ currentVersion: '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7',
+ versions: {
+ '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7': {
+ header: '####',
+ data: '7wg/yWfSasUjJKV/5ygFfteazVSdqEJ8xGAqtS7m/W2q3rOR+2fr99Il2TzxXCnOe5zV+iir2tOqPQt6BCGbVf0NVwZtvfO/lvfMc7DIwyWuhZ0sS44LBTD9VY9fruuIegktVHSNBoJTCIfAHN/ut1iB80+51An+TdpYT3SGAVM4RdenQ9IdvDOnQo2KE0E7BzHekga800VJrbqI8aJEtmm5mOjte2xHYSPFDCtwURQclwxbNv32hAY/IUkaejqg93WGIzHIIK0+SSDzQwHYQo4yzVGCKKy75eghpvGyg1zbzlv372bND+OuA3laocARFfe4rRd5I5nh8vmSJ+vybh3EIJJzloD+qWk6hsEagkYI0RYu9I2uOfA8drmZ02GV5/ySDsBHX7uhaTPGx4J22rNJoj8s1L7UoaohUHFvUerBvQTir2LPbzqT+B07wZOU0ibtHlaN5C2XMKRxfvGATeR+2J3l7WisCIoRdpQcPFHA7nlTTShBiCVstLxolvd7MMzPOilsi3ecxXLQSeWara4JILqXQCJ4yLbQCMnSpIrZ3TXbwbPZ8fjKjogHNUaBPnmd1hWoc7IVvK9RSFBEdCh9U/hbyPMCiSjdsUCTclmhFmhiVIlB73IyWixmLwHSWSl/ckMxcUK6rB0IPuWcT8iJkxfqOziFhMvC/cNydpN5Nj4WX21c/1M7lVlX10FRx6NIYH5szEXULmLnkfEwr35G9mKJwR2pgZ272UiW2cH64/+M+Kh7XnPbQKxTwVR3FOhR/qdSHeA8MTc9FDslFaTT6YSeJEPoQiLg4c4UdbB7w5nA0o4qg82hiiJbTfT2zFHZeeWOpVO1z4V8SidJrQkh8aL1/Is7KaDVNfL+Lx73gfO6tdSviCJJhD29iTgn+MW4MlGwpeLKpvq+LkXNXi/CVjIa1VqtR/Flk2BqwT2hccgw6E1ML+QdW1n3TvTtdLIvSGheOM5kLdnF76e8Nj0kHDFbnxQMlO7lutngaNBRAvhvSLccT76TMG4OTxNZk5aOre6AIOuUfrFD3KDeOqWie5zpkvTOd/JK/JDFYgbYQh8AqhwJ7VWUH49vfd6AqfwHwdNWymI05F6/0Co4xoQ6qN+iYNConUXz78Uo7AraJuBDQ3a24+wL2mLjnc8jUDFUaAKM6gZUv9+bx1vk6zVdaZcuqgZc6dcyo5Oy8lmbJ/SmRb8BF/Q2nW3SDv77R+p0bKPLmjcytczlMNct58Q1LoiLnGck5v0wByQ0XIMd',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 16:29:06 CET 2007',
+ updateDate: 'Wed Mar 21 16:29:06 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:01 CET 2009'
+ }
+ }
+ },
+ 'c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065': {
+ data: 'HxkHstm/nWfD4tTwtaDqycSrP6vR7O9JUQrVXp90Z+prnnvuUMH3SbOlv+AQZFJotuM9VVOh52yWcl8TuSJ5SYR6pwmZVcK9GJd3aRH48wBRrsi9do+pgyxmzfpBm+CMnUtI63LMPfyz/zPndUQSke5+G/Q1b8ZddaShjYHWHEifjdswmKg68FOSu7RuElR/FwRCBwuT02vMRdrjwxSxxM5zWB3vqzN4xKi/jkvqGgIc21m8adTQoxAJARleZiyWXzfPO/MpUs3vA6nxH6ZO1kEayGw3ZAR3nFBiW0UjjdXCBI2b4PcUP0nSJKetRSiudo2cUKfYxsWgEPoG+PM/CQFdnlfGcPf4d0QYnkU+JHff99mLJRmz7VWH7ZeW10NTxzTEr47diHLpyufZ4knnRgfhfKtwOvgmG1n1lXyXDRVTeyfCCX+mB5qdB79ujqon1BiLOGQfLWZ8bDyTZAakpcRJb8qk3zP004XwN5BpO+jC2waMcUEuH62gSQeelGZ19pzBiRz8kn3ZZ8iviX46Wwk3X1TTke9teF7t6Pop4pRkaAj2z2ji0mqWtv4T/3QW4Xgf1mKaT2t8ZaucGvZ3jrxm0CW/Ra3Cy1v1APwRPvKnY5i/WPDS1elq3vNF0NY7EQbXrxBX7hgGpUGRcHSKYsuftIquJFv0HV31jRhd99nZz6Otx82xidWbroIS+37o2Rr56X/AwkLn3DgH+V/YAK24z3Otku+lbaorXnv6C8ZDUhcce2CjgEuCFPmv928YOahgmE0Q0uKniwVXgXACevvACEsduvW32JhI4D4cjRWcSzB6YhqXE8QYCQwK97OykJ30Szd/ZYykiXjdjymyqFOmI9tZqi/PUOKRJ9NhYZaVAeLEFUunvKJWHNs50CqElw6z7nAvBwYyEVvvc+rSpMb2Z/KAWLMzv5R3MeITVUph/RlRlMIrJr0lBhmghnLRt6cGRQcDA2Si3tGAm34K+BpxVbTK0ilTrwzCfaE3Q+dvBTFRcZzMcPFLHL7Mho1/kNMb5S0izIpsNPCb26yH/gueYghVmhRL76HQAH79k00uJcyXt57AYlOYQM7FKDHWciWtJDOMNjVFDYQJJSAS39HukwrLnAdqCNrabrS+AuWhX+CqmMlKQ0PRszjtT7oQaAcgJd0uPOVz3IsjyZ/CmrzSxM+c4iPXugkiiyS2HYU7EEz9IEDvoqwv3Djcy4+3oxPUdmIJGMz2Mk5UXMDyMpqfuujirZI5r5WQWWQLivD9mid5RWDiQp2NYwpnQ/J0emEpWFlf/XkmXW+Em/A0+DOeJtHB729WsKYEvMWOB1nuITkqPJShf8FVEunHzUuLKsG3Hf5yEc3isB5rWGO8hPCueVUKgiS/NSCxQ+iinBTO3gUl+hzK+yaajQUomCx7+N9/n5HTLM5kFsUxZ8gfG3LMEK1iaza4KZeS8Hmb58NU3e3MI0FvlZHa787LqNO226awx3sX/nuTMX+LXx9v8/AMrkRdbzlcYbe6xWRWcBGiTirbTV/CXMgCdop60xfRqCskQPbfj89zpHQS/GiTJjhUwh6XKc/TpbjQJ6OZ6dAQBDxexPa+sjr70kLARxeUhvDUytp/zd/A5OBpuZ0aUz530aQEj8BCAk18vdUks7TWcpiw+/Lq//QLu/9uLU/rLanu2DFUYGXo7bJzy2QpzuoHqKDqa3anK9Gs34NfcIjUbeMUyCzd6CFj+1vGNIk4zZi44PZvmqxZXI8XcxboTpnheNRksjw36FbhIKWMWksIIq+mh4XMnkQcS83PB9rwMHsYY4nKfCwddYfRlbVjcjX+jSlz0r6Oh3KxVDP6dt37CPo8DGMvXSeU4LFMcYBkZ/Q57sH3/gyblyHK8OqYX3pzbnkCqoaOwAseBrQYMel3OgSLt1nAxzhN+ZicCLhpSYHCcHYDcg9xoa/1u4uEMJ0JC+/OzU7xp3nC4OgSYxVzL+gBNnqX4Plep7oikvE7+qymqwtoEhEEuaO5pbOdPG4I7NknL+u/RazjXdy3IGyfUPCCQKsjAEbAkD6OBZZf4St21e4sSgV/anAYFGr87fHMPtXhBxH6QTQPgWqrK75Lr/RaOLihrQHgVhcQHYcTD7nTtPNelbJKx5aGOFtcqykaVizLzrflZWXnk+QAjHo6Hsn/edm7Hbna+JTlyVsttp2vcs8kHQk6xcCpi2kR7nJwb+6kntEEPZAyuFQVwvdkqyC5nAecdg==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:45:43 CET 2009',
+ updateDate: 'Thu Feb 12 12:54:37 CET 2009',
+ accessDate: 'Thu Feb 12 12:54:37 CET 2009',
+ currentVersion: '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a',
+ versions: {
+ '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a': {
+ header: '####',
+ data: '/mnLRePyLGwPaZ+EkbTRHdE4jz4gY99jnHcIp7AeMfcktEpPmUVNWLwGSJUH3ANP/cO1znxACVQPzC+g8IVIK0muJ/lZ4Iw+HkpsfPtBjPZc+bfhsY5Mud00YBsImleIMlbbJGv3l79eSPcea49OwG30xro6b6I0KK3BmSgr+BG2AmBrKVlFRTPFCHRbO+hG/LgW/xqYgwd9f1dnbeVYCm5lA2zdAnwmMwlUIi/J73MbnsSO0Qg858iF1SPQ2Ne9Q8SCyKKEZwBY/YeSgDzoO76Wvqbzk8uPdmZldaF4zql3ffBeb9ZS9KIyyk2vJcLk7c3DUc65vaT+w25+2GSpEXD4YIV6VSr6Brz4w4gzcDMeLve0U6oruqWijz3CDe40yhd4mMt6wTVs4xo0KHc6yKjTuC1ZUQwZvuCiS8T5czaGpc0+fLyfuE+pVBxTlpOjkoZqzk6NsH5lcKMzB1TCscJ8fbOdtJso7DRUvijIE5+ayY9IktZhMeHsk2zurKV95A==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:54:37 CET 2009',
+ updateDate: 'Thu Feb 12 12:54:37 CET 2009',
+ accessDate: 'Thu Feb 12 12:54:37 CET 2009'
+ },
+ '4ebfe3bec6d419d61eb68a1f25407824e404e3439c23fccde1ac19225b40cb06': {
+ header: '####',
+ data: '6VvjRN9LKi7tt/HsgqmU0bUdZQNVjVAYNLdCrfKdRJCx3W/GZHHR/AQF0FcvuXIn0MWMUypHpTZW86V459OEoV4W18HXEisQKEiqBnUCBaxBd1NKZDpYsThISXXOhZSbXylbLoB+kBaYzT+Fc7utDheVvVPeMo+iEb3ih42B3En3ZXcgUAdEjfbRUm6st9Jiaz4onwXWknVhkF5QewA0GXDhT2JdakFxfUDay75wKvspq5IszbEYwsu+TEgsbuO4/R/bktgsQUrbhtKIEIiNSccDNx1JkUKvIxrRfp1m0Ar3XJsDfv7YSJSLdyVheOEdIpBkeZ40LN83uzGRMZw1bQsKf+XOFTfacYZBBzwVj8e1rJC6AWlH6Fbn0jXw3JcEljA4zUh5IrYhWtyIZW338UVsMSIp91USeM4uCvPsOLAdyCXiWu5H8MMYGz1rJxVlTbMiq0tn1w1f+CL14v8EiUft7l8kfZzBZzdLvzdedD/wHQ==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:45:43 CET 2009',
+ updateDate: 'Thu Feb 12 12:45:43 CET 2009',
+ accessDate: 'Thu Feb 12 12:45:43 CET 2009'
+ },
+ '7ef137cf242e00136e57ddd262edfe6b418b6f57f3b5e5e15f3ec1232867f6c8': {
+ header: '####',
+ data: 'N5eWFfsQGHR1WytyXuVySzJ3zenJEB6IaKr2vgWRHTlJFzexXzJmSLoozTP9Z4TumDOLsNrp+EUeIa3Yo+RqSyQKQRFDHXlUYa6c9PPLPXdexSA9JO3AHzMSpL6K0E4gN3BybjL2rbcQwUqJLvCKy44OdiJvORGfIIpTPx2LQ1o4P+chcpOwwe/ZhgLWmNC6FmkTvsU/xJlNuApyD7tPX7Cj3lP8WBfYEPr68BqTKAa9cxai6ZF4BRC//rFob/4pQNHE+7qjOSY9HOnV5uCtZehPYBwfpBiDYhaxWJxXN6sxtpe7GC5CM7gAAHs5lgVaFSWffOAL3zeX7I4vh3j1nYdXoh5KowZJVVUUfhwqJo2T3YDVsaXNibZIaPd9GlbeBBk2HL6c/ao6B8QNwRU7GvMHAdJKta2I9mtU2NCnr0Uwi4rZRR05V4k0HIMLEJxRo/IYAysAYETNIAXzk0twIokOF5JPjP4uTXRZ8LdiS6JqfoUu3Jv/7yq8wrKZM7DaQA==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:47:39 CET 2009',
+ updateDate: 'Thu Feb 12 12:47:39 CET 2009',
+ accessDate: 'Thu Feb 12 12:47:39 CET 2009'
+ }
+ }
+ },
+ 'ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c': {
+ data: 'zbQlGR1fT8HoH6KvOPBoaIjMUsVMh8MSNIzPO2muIMJDVfXB2rEcPnIFl8fNv9BtE9OLecuex3BQVJKGXdVGFYVNiSS0SgPoEpyD6GJntEIOaB7GnhVflTm8fT7Ba8ArS4r+fIL32Jx9F8sYrL6jKPWeuImGHK+x3X32uORI6znkRac7J727TiTPlbj03X/Fj3Of6Bp9Wa4xbVMwzi+R6NRKD4A6Za3mqhoSpYFeHWld8+ChJU/w2wFkj292OjPBzvvz/SR2Zth+AXTChreQ3Zl1hWNGmU2Ep8ijFCYwcamgPkQwh4vBk9NJlzIgadORcb/0EPDxn638VNA0dbpW8MZUCIMWVe3A8VgdllWxei7dDy1ri6xsKlFovLYjRRPXgAqRSqVATqwyXqhBWhoV6VZ5NaSUGvM8okC2GQSweLuz29py0F987MISmLjav4gdvcMA1wn7FOIaFTNg7oy2CxZefGhHT3sHfX/PIvs/ovfj+7TewI0k+HR414az2D5reo7S5I4+roCm1QLVpPNcXUxbAmEbjF8JCsTtECZ4kdpG39dN6BaMlHoHSN3wu05uTSn+sL7g3Cg0pVLlnHo9baw3fUnVJp3MCEgZJELaiI/WF1Om2y2S9UeLur18z5T7hHFv3Px28D7c22HEDdF2CObeh2uOlZGAa06lp7YlYeoNtb4CqLlZAMK0xIHfNUceC4OMNvqyGswd5WJsYQEnMry20OkxY6YinnQfjAml54B6WlvNVlg/YaKjw5AVinUHjzEFfQbcBFnFGpqg5qJk9hZmb1VI6Ujhq73fPydSfkvfScTImqxCNPD/BR8ovoaJtNpE2gmcoX9A5zhZgu5xUnUnXoaQu0l7K9kWof/UmCCl0O1A6j41aebWr+aoFMalaOPzNJ02vfLuW155IwjFQvRuAp6EuktZ2dFKyFl3QnLbwsMnitReXMoW30cqTYg7ODQnopE73RIb41Nj07qdx6FQMzw4gAIEFBe1iRvlMHQazZCb2ndVvgtK3ZcPNtDoahuPRxMLaKZlRnpa8E5F4o8NHYNivshawZi36Hk6w0dOimCiuk/zvJ1mtx8hhX7B5dsXlNcKxLSvI1onEm2x9HL318xJeT0y29alzPYVFuQs5kq1+UV3h2hL4E/H8h+5mWtTLf/MjaTZ09okW/etuHFFjCmLoKwugk70z2yLWEJGmbjw',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:51:17 CET 2007',
+ updateDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:12 CET 2009',
+ currentVersion: '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926',
+ versions: {
+ '3895963f82854530ff754c8e2d1eaef8d884a8cba7cd058b8b7adcdc12be3da8': {
+ header: '####',
+ data: 'rXmjQYZgxv9jpFus3T/qa9Qc1lxt+mDF+dmZeDmDG3IiE/LnonGt2MqL+YlbFzisF99Uv0IQGOZCPigtBwOXB9m6R6R3lEy/YhD/C6b10s80OBj3yr3PoTsoTmbnmZMYd4r+qx8SaoLLkR0aK6NADYZXebR5QgVtwF/a01EifI6YxH1wm1RX3kyRhIrMzOtL8zHbstPvW4sRtv2YpZqlZqBTdoiqztDUZTKEcCcU5QLnHYMNAVpDHE7D9WvQy8Il1taAbxg97Ir+2ktZLjqfJdKhU7ZLv8fcJiRgnQKPqDWcqpjA+CXM6Ak1HCf9SRJh6Hl64+fk3jEVAPmHvry/xq2RPCG2YnVNWZ+uL3QNuH4zt+IbP4FnrxkCAprmEiNwvuEefMgliGRd+FowIaiFWXcEtYxxQvRDujZN6eoTUU0KVnuy85PKi3ih0ZECoDM88MFhztwCG9/nJQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:51:17 CET 2007',
+ updateDate: 'Wed Mar 14 15:51:17 CET 2007',
+ accessDate: 'Wed Apr 25 10:37:27 CEST 2007'
+ },
+ '5311936f6a95cf123007ef867388adb5c1ec5b2cf1173d66e501daa16488e42e': {
+ header: '####',
+ data: '+VirbcZ59SiN9UJKrQkjQx0Z4avHIhvw12Hq7fs+Qnoz4RgCS17fqzYyJe+jYorjlMPjzUcALYOTobqJJp4Sp8v5nOilHW64Gny2XRp59PQPg0zE4TP22l1PzK04+qJusR5NLPU39hYbW+InkDapdIhdf+nIruqeA311bRLg90A8xmpzio6PkZxXmhZMabbEVfXsYFBQKVBFloTMusBG2eaxTjeK0hOAk0uEc9RGOEwCOvZvjRFCP8DyZ5T6QV1pYYgBFBwSFrB/koXmBmObj8zscJXQ4H4UWC0yw1B3ABbhNX7vC9q+vgZTxnGqI6GvzLcrzaXKTEyfa9twq+vKFX1hqDmM0UVLw0dPOy0/3tabJjFrYbz5EEKVin9UqWhuy5YIvHEJlMkH190Zo+lPMuHvD8TiAU1M/n1bTQSBQb/8STD6uqefbKS/s/bXcS+bdVKBmSgCuutBznYO',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:39:26 CEST 2007',
+ updateDate: 'Wed Apr 25 10:39:26 CEST 2007',
+ accessDate: 'Wed Apr 25 10:39:26 CEST 2007'
+ },
+ '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926': {
+ header: '####',
+ data: 'P1LfM+8PA/kyelFsojabLfBW9D0Aey5qDClz0OTdSamMT2Mv1U35eKcr6ilUrbtW+dKJotAzs3B1dYGzaEQ1j9HnhiL2pk4wgT1JWGe5c9frmFX/3YGO63c2ngnaC/Rrv3LC251cLVS1aoWNPskWkjZLzF7EiWbAeNYTplSa6MWm2LdHAm6xq2dcgYx53RJVvjnsCzpghQdzL96G8ScJjnUx8FC8mHW4Ds0rkHTeoM344Ao8J3o1XwoFqFFJ2X8+lSkj8LVVdjff1EHIicjrMM0oJG8VyxK2TxMvg4mnLWP4ALfh24Wrb9XmrM0NjhQXBo07tL9dwa7sHHKiBrM74644vBR7NB0+Laedg8D+6FmgNoR6icB+qvxCIIvAhOpJ0er9f0CGDDS06knx/lDtVVNewzxx4ATuG0HQn8M61eU83EfbKWG4Mg+9jtRcW0/bdFW/FQr/OeKg',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ updateDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:12 CET 2009'
+ },
+ '5c622bec0fb939da012beb98a858a4e16bd670b3e6fe1f7c92a247f88a65c747': {
+ header: '####',
+ data: 'XGlplDTD1xamZO04H6RiqcLd7XaPwxI3MqpKTCVHPBoMEkwE4A1izGjFKdPqHbQIuYYcT9xDgPOknlkP89jDTfcR4UfENtKHFgFaMee4orSER+MhldJRxMwPLorZmMNNZzVmTmwJS7FI9jYiXEvDbcyw41kN+SA0mxzWpc9emaX4TmZHzlBpY2zXKJLyN3otYYzcTWzuu7DJejWrB+CnNp925X9vVomBPfp/Gt4tiOFsE2ZyEf1B/7cDmMszlQgEgGJONS+C8Qyr+X3GEh5iPoYsGpMNmF7aYnZNciE/B5lP/ABVbZIi2KfmRlSf7Cc+kMkUXyHxOeZHuVv1ZlzfIe3gXlD0/yUJFHNju8ai+F3hpSkhMatf71mLQzD5oFrTmKatH+zQZhGPP9dQxG1cgZRcjbyUQJMazo+0TJuNXNndi/oiRzRJjYRUbZKsfRzIAEU=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:51:49 CEST 2007',
+ updateDate: 'Wed Apr 25 10:51:49 CEST 2007',
+ accessDate: 'Wed Apr 25 10:51:49 CEST 2007'
+ },
+ 'bad48f8ab053804a02bec678db01baf24de35ef04a17b90e1362e67fa352e4a4': {
+ header: '####',
+ data: 'SXl3D4C5Yt81L/117xsHYjZxT/fANq09VZsMNAz3Gcn2+2gopG+1K0JFg/1Mbjt4EMbe5Or42zBlJPo5EAldAfWu4MoTkQzo/wKPzgOWlIi3A9QwZegw3yCuHvJv8iNcpjGfpY0OCzTZKNomTtwc75l+8FqgwPDW4wDkPG98275ERDR8mFSZfUAiQxlTnCbskFneUQ6hdN2gywkyJKuTEcrMkIpzwe9uqPaQg8GjUvvy162/LVaSQAVRIiTbW5URCD+hT5cKOkmFeBejHar8zR3SQQ+tIJlKERBwfE0sNR+RebSboYxWPECYPp0DMj30FnHbfYIVTgRCIlepy2hfis0+9C7dop0jK2nFREjcxSIqonF+juCrfJDt4cTlpn2SmcoMJQsUOedSh6ZoWweXm7lu8buCbA2Q6SY1L6jz7okwIikIinxGDq3qT1pWSgpntI8wvYZ8RD0umJsoAzPYH9zlfQ==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 11:01:21 CEST 2007',
+ updateDate: 'Wed Apr 25 11:01:21 CEST 2007',
+ accessDate: 'Wed Apr 25 11:01:21 CEST 2007'
+ },
+ 'c03d1fcf5b6981741f5d4787315534641c61daee9aa3c063540fbb704989ded6': {
+ header: '####',
+ data: 'sbn5IDJM7VtYov3sqW9+/0USxZEw2xq8di1XVPMMZ6kN6oZZrAY7ukxXHYh+mfuIa1/uV4i4v1YCaKZQShLgUS4cchlK4nnNVL8zejGwB+PaY0E8Um/Jg6E4UAFAZ+haZwzWLQS8lJ1r4hNMTeFqsDRUhC30awJRz8e0rBejLZiS2Hk/jgpH3i8Za1GwDzogw11iHXejYI7MaQGB0E9eQsYYTxGjmzcLfVYkd4AKj5pSEHvsKZklSuWIyDzwaFiIO7xqcJmS/8Wkm63JGNOW3nLR5Ao9V/2vthFHBqS2lQNRnkPWXbmNK3v7vi57zu461w1Nn1U/70EvhHRMk8BdML3XI/U6WgDARjQuVsB8FnTkzapaORG5vUd7nTtWjPdyQzOqacm2YKWpAiG6fUQTZiBusEd8jdnv8BioGUTbXgNVG23zcRbbbEdjKc1aizXHQE1LnROvoHZHkwg=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:59:57 CEST 2007',
+ updateDate: 'Wed Apr 25 10:59:57 CEST 2007',
+ accessDate: 'Wed Apr 25 10:59:57 CEST 2007'
+ },
+ 'dbc283f49de6e303c06a52725b8187f344ba7b433b0158d704f094edba782710': {
+ header: '####',
+ data: 'fbNrpIoYF+gpMUjSxoOc9Y68qRlE2yk7FPPkrHTu07HHWkAWy7H7nFw4BwGiFViMkyEC2orUrMeDYhKmMYFj8DEcALk6452BtNutGZSoqDhD8xnSEPF6fP2Xyy+vZHp4JWDXZt/xHk4vPbxcwTTlmRz5aO8ChXIH5iqfRL9+Dx+gJDKgKmCRMZYMT1pyOUewmsT6QDYdGFJTRRiDmoLfCVAXhJRtqQSBcx3kN3kuf8gyOMAeJnFGISTAj7THzo7eGuQol1omTMgGbDZoL7WJNfZIDamiT9TWwzp3UmQcKIsRvA2ZKtePWRmpWyq6WydJgFXHUuUDVpwT+kc1Rn9Wq2zwm1VBw6gqKCp6W9bZO86rRMs2CtuLT+agSpqb4kz4SEYDCW0+aUsJDCYBXx5yWRM26r0XAbU6X0D+xopGuaVzsV5G7chkCO8mUsjHzZCK7hOAz6OgjR2+',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:38:17 CEST 2007',
+ updateDate: 'Wed Apr 25 10:38:17 CEST 2007',
+ accessDate: 'Wed Apr 25 10:38:17 CEST 2007'
+ },
+ 'ec525dd942f72b71b5fa1aca0a36a9960b71608bb27f32bc7923713bde021b12': {
+ header: '####',
+ data: 'AHP4MFiGukFCCnjLDGoqJUDEr6QNL+KoZlcwOqJIYusRtl5qmhZSsODHbAEpmadxLGogDPrWoH5/XLZ85ASGRF5ALzDgrFKP47/bSEzKVTDABY5BJSqvKgS/lCf2LdR7+0HWUVJ6Z3GOb9GqsXC70pMxDo/RfclOQPa+k/sXCW5u0TmLb/0i/dZEM8N++4umXsyy2WPLtUVzQZ/VdTMDwl50FeQxu3aNGy4qYd4XFk/7gxBH9skBD6/GqpNajHJrcbi/WZt7PZiN9skoVZHhm3YLmteP5hJnrcCGBFJHWuQpXfB7NR8rNmd2c6maemKYmUlX25wQF7JPcROOcyT8iYpF4Hk/eSPs0CSkaDdqSD0Nj9E4kqZrHfVGMwBbDFyAzdHTN3EyGuC4cBXdfNZbdBqwghuB1x7RLXs/pbXg1xqukjRdPLTxUogPdaQBHGo=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:56:58 CEST 2007',
+ updateDate: 'Wed Apr 25 10:56:58 CEST 2007',
+ accessDate: 'Wed Apr 25 10:56:58 CEST 2007'
+ },
+ 'fda6581f0137dd641387a7be193b06edea4451835817bcda38d22ee24ebeb77c': {
+ header: '####',
+ data: 'QwDMobl0Kds+J8mknphumnONOIF9gH+pC/AJpxGmuy/rvKfHSeEuuWAZ/yWj8J/I4V7OjpyTs9/uCWeKs9khpdkcxtObB36IfcbWBHGOgFjvqKgwMa7eZSIUPZz9k1NsqJC9nU9U7w5EBzQKVIjJaey1EdhsggdtNOpQTzt7iu2mWKo33dJKQCQ5VEwhpGh6SH1TgKFbdMkOJJY8d5xPYUxR66LVFpFzgHP0ML5M5U53PK+apT95UIAlqf7N32BjPK63Nsj1WPsnuuL0vWA3KmefHzwKGeatTdsgck+1mwnCDJncPWv7hTwMLGPUaY+Yww3K3YPihuyCUtUdV3fer2VHVAn++JdzerHiLI/86T8gHiLAi/anFFh6i2kMMVxqzREh+62n34MrgdMqbSFQb0V4Dhm45FVJH43uuEaoe3OJPtyvj1HbcSR4VEVgGkDeced8aAK+Dg==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:58:33 CEST 2007',
+ updateDate: 'Wed Apr 25 10:58:33 CEST 2007',
+ accessDate: 'Wed Apr 25 10:58:33 CEST 2007'
+ }
+ }
+ },
+ 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d': {
+ data: '7x7+2tk+I8+OchrmpfLJhDR2crUWfHDo/E8TdmVxbMH9fsnqG4azJG/xVbWROw8N0v8ahhBY3BJG9de9L6PH9B+wECx9zRx/udStcStKRpJLCcjWxVVMt/ipJ+/QqFKWZptqs7VkiT4jZw0V3I4Tl7Wt82/PWZ/euyzYOau+YtiflSedG7+7aEEbhDblntf7NbSXCTIXVnAZw/xuyMjxmioJNNe4sA+fls8KZSYYAzpvxl9+h+esPm978SN/+IuG3mDzCHS+V0tmEhr4v2yfWsZ5axAZFjQSu6TaLNvdFmvgF2olddkizXBsov12WlMSQDSEhs/xkv5ZXVLK3JOCDJldW80eLs0vGOSOJZL3r7NO1gRiwnX5K8PM3YowFIFkWNavRy/B4RneSNCo8XqEg8lBBiJbTtExxMByLKjifcKP7xAD2VeByJ0XDo5If+J4fGiYjo9XU/Bkc2POnJQt+SnNN5iAw493AtGDdPMO37RFRCAeU3W0vR1unsaD9Xn+ClPj1jNCXWZDtvwWnoke8XCeDeTIAzh3wXMCs7ZRqfAHwA1UWOqIq4DP0RJaWeIXCWYSRYAWLnteX1EzHixkvh4MMKmA09bbH/SS5gB6P/V7BBiwxKgstU3tyBbA2bW8aUG1zNthaOtbVqj9YbyogEMN5f3r4I0eMAZDKkbD6med1bHm6P0Zlr0MIYFIgiLkZvEjfoVkuQmFpM1N/PAlEeVDD97VZG9bGN006wdIsR2TEStymt4aBTIyZ+AKDKiGAARYPyYBTswPIAzKBfUipJ7milktKHHmj6LdsDMrwIf5ZQLqvAm2v7xMMBLWTJI+ieGi/R1UgvKAzyGQwzQFB2x+ljNQHsC3wnTLm7/y87CE0FB39FZVC2NJETmWUmAmltL9CPs1Wr6tkin6e2CzSvf5EGsKWBMDkHZD08vjLd30+BxbfS8cuWS3BpTzZ481qjqsF5hDtyRgHQ2eXXggc9imQCvNdG13yNOCcN2KUMPWvPhik6pV7HIMPI2ncPegtCVYwfDFHCn2AV+K1j0G1JIPzRxPlXBX/XNK9kyyK7R3xO7vC3VQyMzPGp8Br5vmoP2356lLLvR5JT7j/uXwZTP1H2/cZSLOii44OXiSNQ8OKp8SIzcWpAd+IuQ7zp2TKOSTl8IEbnorNnJdOG1FbT9kF3FlWkjT6LmQM6Y6pwsYPWinjth72RpTTMBAg6XXr7jveONdFOhoQBjD+VDkF5mv9MqANwv+1HSxwd3SI2OuTsoUcaHzpvquixf6BF2mctDX70i1Nx0gsnBzwsAa3hMQ924fEUyt2XQbJi+3HJ+C5qakgfZ2ERq/MaUL3aSUEL2ViuBly7ObM9/E9NQKyRySXGXb6e1ZdFlajhWLw/N4UpZQVXuQOX/0i95lWQsGbc8aeEn5kh5+Mwruxh8cIBVywiet34O5smc0bdoSWgXdaHZZ2OhJpP26gcDmsYQQPhUUpkhdipRTuNMoWDpy7T2Z36otFZYSRY7tUF7Wmh4zcXxgm8nBbxD3m63ll5MQXIfsR6KL+Ai+81U19VEd224+SdtHd8LP2kbQTRzNvDI2HJdw3GRsdkhyVRFR2NCdoseUfLGqOVxNt/XiWha8r70JOBpe+otSStF5pM92FHHsLqPIEakPqaEXL6IYJa1C9kLjMTjmQNig/biF1X3vQAne1maUvuAGx+6sdUU+GNIpw+AdjilUoRLsFwIMiwLxQLc4dY/97AEdbaC4pNYFW80ch0Joq54IYdmZwv4A08mD7yDGuWxBSyJV4Ylo9nI5ZofpW4Bw2HaG6L3Qx+207Y54WbYjZvmPUdLjItjQWgbJVPfvYi18zaqfbHFulrhKk4MM12oc0OBqt9nl6HHNKHhoHULDMR3B09B4luV1uziY0JudV7ePlCaLd3BDF/y1ujXFPJm3GLkjsaXY/rargrHuiIgKz1FJPuEXKq9admZmS0YgsGkRAgP3RwxpwJoCBuvV1XsFAYJNnz07VjaGvtTazGg5tlfITyF3tZ9m+GAeWR7dObhBOIxR60JddSz/61Zy95BfUOgpuhXYaVuZNFVxYTWcsDFy6Rn4TJN36FfZ6SaNiDQmWK0nhXiphNAzFTDvOBCZdXj0hwSNibD93fMrnphbjmpRfuhLk9MVLupB0FcuW6gGcJENbLKHaJYzRk1LTqXkZ70BCNoSt0HHUgaxj6S0gYVgWa5iqB4HS2vB2gr3B4iEezUWYG5gZsbCcC/H0bvPsSiNpelHrApPgrhGatR5ZwyLt9tnpVTxq6Uw1DkgVdEYrVBUftA9WB02R/cPD0T4K3VqyEaixODGpRWj3RcmUlHT9LwTlVmX9zABKxyIe6Zaq1Chk6mfDPgBzgai4yoUlLQulgayxG3GFc8oZRAm/kOjsY2E+/OpVPtKGzPGR7i4dSK+c+/GTJZykDu6w5FGznNo8YYKB6fvSi0nsTdUSBxBcYgFs81Lkvh/iBf3ZgA4XT9tvHls8VDOKHS7Uz5B7yr13pzVUDJLPQnlbDusmiAKgoloq89ASV2XdmUB50RxeKk1yuMfSVNqXSRxHB7xcQAsnJKaPTvkc1Dikv0K8g6uFSOlN6PXqOJU5SEwkDVsG7OBAWw9aiRC+IKwquOvzejh1Cbu11yMYlPpPtSydMoOEwAKoeoT0XdGVDXP2ySOYpVuW3i8wceWQLg2BYHIlWUzX0CIN0HZbvw5v+ptTzDXT+tp3AtlRzmGKXRVBvdtyUn/38abZ/Qwm5Uzw2jtXc0ol7ce9SMpJb83wpJbQGVTrDUrevFw+vh2x093yS7xNRJS+XNKnfZVG8WahWTdD2VRilgQ/GNILKjAT22XC0kW/+MxBReazixYCMU/vp7fJ2/2i3Th2X6ZlvzVeR+0jd1lp+Y/8//iLFpNn/WCkIKZQk1gVlVlzlY889hORm/SJd2J08ODQ4qCJS4ncYzu/xxikyjd2q+9wb38UHIIOx+qlop36QXaCraduzD5ZO2GHKZBWlJG0nBWxli6BMc6CIQdTKAAm3xnDP0wsIUPhey4u2+HoqC+znZeXTDVwl9n1oxzXsgpHsUlRCHG2pUGF/nGGe/r6/PQ3viSz5I5XUPWy0yOoy6I+NYQCanjcYtFvbcNTDrFmIkQPpf2kFslGlfINGgRlLTIjoYcSx/Xp11FGGwG/1tOKuUzDUAY2dMmFiGGkkxlHL71Z6BFAWj547krybEyCujhtNDCex8htVlI6GH4RxoVyBmw6cO+LV6TO63ieZWrFJGyQ0hd0ikh4A77NZi4+0rEsa1nC4DBm47z3CiLsXH+IlPi3MiBKUVb0MGHcLSvDokCZ4iFsdaMx3Cvkne0Ym8v0i8ImhWa8oJzmC7VQBSCs3gxCs9bENWShhlPs8JJId2vpn5LzsYp913gtD4PthRUGUAa+9cPzQ6V4qQgpzkX0KmV8VRbElDlR1Q4FRC4Cu7ULf8YTSof/Ko2I0iJlH/EmtM+BQO+zf0MohRvDPzEkKeHFhgbUSjcYls/NWU5oK5dOdbP8Sg2AryTySVmMiJd0Eefu6YnjJaLS3++mM1tOHKucCStqhehFL/Jo63qcHbe1jGvAdbKHk6WVHn4DX3DbT3U1awpfEVHRxNG0/IWu/6G2RDx++pi5KcmBIp40gkd4Exv/k2BK/gFs1HXBt8OXS858W0yWDsAl6z9zbzg1JfUvmrfhFLMNN5jls0AITqvo3rHaA4gVUjswUJmsJdElncyRHkTYuE0lbr9Fv5ELkQePYfhyGwKKJpRYdtNZ2f54rAMy5r/Pei1pn0ag6m5jcYzzM8NVIrJSYwsHsghphpkJw7Fxtme8hgAMoD6lL4lGjC786IG9jsnmXnmV+Y491DDjCnOMTy/NTWm1RD+9vjXYxVaO46+0iYtIjk/e6cmFUEz/eGzphzglVXnAlBs569glfbuZrNriiGzd66Wq4lETelMy7sm3UUwL9n3RvGalQCuwxVLZf2oQdNRLnH1k8sKYJk1DtFNW8R3gTRyFQBx1FKYz5rtCKaobLQf7xn+Bnn4uBMtpVoxfsWnK7se3UIKutJuWH2PoetRft7fAcYzLSy9Oyy2fV2gR9OV+9p0HJAIPIKUMC8nVdLXXaggwns4cigSgOLN08gWpTlD39IZmBY8iA+l+bkJcDSFqD+T6hYTNxSXkSLy9Xve18tvYJqG4JvfBt7JwSdA+QwfiS9jIQdIWUs5cBl/ShX9IRmlhsZPF9sow5JAnGJNZhPBF0j9UJfDcgyw98E8wVuNHly5J2CneK1vigbZTM25KMnjevyN3PnfsFSkPjTw4wmMEJpGdMnzzVqA7etpitypyNbgjX0fsAWOgEIRQ5Sog498t6nF1SwWVy7R+0CdpZhh0GpyoNf2TFUklYRec+xRLbAZc5Bkj6Tm9Z/ex9Ssjhi23uL0XG1SCJbHrhox4F8LgLQD22wcnXoSTU4mPAY942u5o2nvB6CTQS8Mj5n+YipQ99UxDhii5UrliGHSdEgjugfHiSoxpkjhNxJSWErYOgWi/qadZqsB/FHLFfMDrhkKxjpcSZwzZO6fAtKiDM5teK6TWaGWwEutd/W/q0Px1vYWxnxHn1ryXx9O3ORe5JJ5FymN4SWkTBIC8eeWTUxQ3TSs2NoGPmN6SnpGFLZH2VLygpg56tE9nXJifXElP8TcIPGPvFGNZFLwtxcdoVbLZaS1IUTpExPGBQ6NUPH24cnWE3RoQrQQHaFcdE1+IRC3TKf+ajINV2LBMhdYI0yE5l5F9hI4GhHNsd/xzROx4NFqkSdVW6T0jFl4NhAUB0iSX2zwJ+yvaor69uzWIFW81n8T5iSPG7Q1naFLL6AOt56wLDUOkioi5CVYlt5lFEl0UtmFnM4j+/Nj+FCCo6jPil847/ZlAicGKXktmDG2nVGILKLe0MZAKdcni/RwBJnl6qSs5x6u2Z46HYi63t4c2RXlljJkHvrn9PuAIG4xSC041F9gaxEshFqg0+nZ5dNiza+DoWgltTHkJehK2UQLMAbRwyvURSz0zSwrUTuT1lBCoSR8/rP3M8PghvUQ6sHpcw1TJ7NwG5y9oS1UVKiU5xC9gHlsMyxfSEaySkhdD5tVOCeGmOzKCD+vx8C577HZaNskKN6KxB3o+DvF6KOAjrtWvZ7C7r1JF7COugUoBSGrp/CeXtvswFvxNc8bqGqEqEZehhl+4TnKrQ+M9LOyWYnkHqbAVt91tIaeNCZZT3wyP4ooZU+JbOogK50kn9LMeT3r7aqbYLY0T1KQH1eezt8tuaeHaKaMX8P7gpW3ucwTINqDlTHL+/wm42D5UfP+/8/jmD+OfHdi8riILye/fDH+BMbk2/syWF94/ZbxjSEWuNtKBEQZJS2PlxQvlqr5pwCcIOFfTE6afEzCjC8968aBhqXMmONQjiYTj+CGZAfivZQV/60o9ckLAXAJoFBiBNf85l7M8DBfmRyabNCQMldus0zvBX6tptH8EuGL4wRPC5vReeigzpcaP8zbjOmvv8bOY6ZgDZTTfXiqOeSwCVUABEUfErNIzGizNu7iYCrbrPqSErrSC/8EmCqyqVbQ9qcN1VSJSAOJ4Vo4udeib5Zvu2zG5St9HWO/blRkKM9qn9s9i6ONSvn1bM8sp20cvAM3+/JVLD5nlCEqVe7oQ+uBCGLpgFJNj6lHiOqSjOm2OSvIbXq53l3IETF/r49OAKYQP8FkVpxrXmQS9Du9Fbp1u50BY9eSmzJuWOE8rOZhNbpaKIpMhdA7HYRmq7hX0bzDUHfKt9hbcrS89fzGikdlyTFmD2soGEbAwgjb4nFkYpzROVAjOhpfz3loAgZO5qpiXym/ee9gus0+OO6PM1xPkWUrTA8mnKvfiFO/ZJx3rn5g5+M/llzj41Cc7Ds0GtbWpUPhLzY7icmtNBamZf/uSUiSHXi6GCZ26llyX7bayCIVUpjg6ijelZQU3rkq42lVPByq8zmxECK8HjAyff6StsBAdIIexA9DN9psACVvybb8iYd09R1wPPFz3o5Gl5tSNV4f2brsPa5VAUyQdQ8YezWXIwZ9u3Q9vrls20FFfN697M+/Y9meu3hX3lVx93LTTsDCLVipaTJyq65n6lbOWZMQb5dgxtoBEKL3ZuxfeSTLiVgbzF3KqxyKNw8MwiyqcVO5mgZGwK9mHFFbSnUiPfHxBfBdqYzH07OksNb9/MvNYK+ebVj5yrEwT/EjNP5/3Bhe5cRUE3m7Y0WgS0TuYZiPgNYCak7ynZXOrYkNjLpH3Wc5GC4RnHXvwpBtD4yJaiIVt0lxYPvfik8FaRjQymubWA09j78ac9d5bKq40ERYLE9oTOoot26jEKoNSX7xqGQCU8VwAOQhC1HfKfdJ88uFMENnB2WLFGqHhZq444eS3Swc1OwBn5zSxUXLNZon9pinWObX8O8ULY1N5TTY8Qh9bLLfLjntCqXFXH8/6wcdnuOrBH0It6LLqrUm/TehuqXXL1c9Q1cYBLYrYjT0FJmbKrcyqG4peOxfCqEiryLLLcdSOECA4vDSvlo6eJ1sk1mXgF64ZEIIH7dZWlOl/eL0L6fGs/vrbvJBBArkVftkOiumIsXMwqaNtZYwMzX811NZpFMOhInwTmh8mbaaCpL+0ioizEE1/is5M9eA3808sF3Miv7d2RtI3sGWbdb9K/cVrOhV4Oy4MkdVxrZpeYuzshod3DRB3/Es72Z1ImrZh+div/GnWpo9Q9M9U/pLVuLnKVCPnXhu5dkF9nVse5NrcBlt7qQvvr/4CC0uctQ94nbjNZobcEXGSYZ8dx7Oftr7fKzT9cxhh93Zm/mxz48dys3JD1JB2V/OZfPoiiMIEW7r/0aXQSjDhp/v7QeIL9nLT/NiNUi5puti/t9q/GDK+pj6UNQak56M2//iLQ0y+3ov9Fod/LJAAVnCgMAFFUX0AJ3nkRPT6Rz/dEtbKdmnVqUER6UzDvhcDfDV+OiMmSgVFZ43d9JkuDPTu5Zuk2J12kgxddjbbSf8Z5TqkaDPlz7OMCdEht6wyTt7QEX88sUaiFrRLgvGxm3BYv6FZ0FGWfKqEgqjnsFJkmIYPYl2jrAC20G9LE5T/niONA8V2wT6S7Ha0xXNWUk6xaWP64SVOFvRvG8mx9fstjLCMhRYGmpol5az6XSgZ9Xd+JzhkoAWc+xmYMrT30kw8LztcWEz1HeK+cktGYS7vB32fG+oM8MMz6bVtkouHiGVE+YlELr4GjUHrnWgNKqtrkL5btt8ceZqI9RjE9aUqN3KgJgAt8YselJLfqFHNu5kh0XQBbD8CIplN6nzaXTcK5qsboyNRAEC7kjzp0iG3vHqNSPvGlfqCKYCZNW9mPpFaTFPQoEhttDp9+W9cCSTeObdPTKe4n0a4CkLNsZ7mZlFHN+7BhJcPa5E/e8P14xJ0E5200RKjkv/+jXxMEvlay0xypHam6Bw15RJDW6vW2O1ZvBZUDtlrpxXf2YpfhFP55WGVbfiVcsQfQTzJkzmgBleS0lmuO7k3s/11XcCfpFSe2aLGA52ClXXvFzSeKFnrZ6gsa4vfX/8bnLQwZDB2btftzgoHvKRTQ9tw/fdicNck/qJDplSW192y/66bqpm/qKFqt8nrx1FfivIXZnqR+YpcvJuZWkp+uT06Jy5oDOHqjmKrQkQoWmQlXyzTHJSIYjK0pfwAV3X09uMYI7+tsR98K6yXNUmYYR7CC7n5m44eu0Gr3fBienuuXFTdbrQvaVHQsY+ekPWByR+rfhVKxoK7cYOJM14faQlpMfrrOtPSJ7yABcCyFRmcaluNQxUIx/ueC07TpbP1oIVhRrBpFPfmUuh8EhWsMqJOrZXvJ12pPrNvSWaqZ7sgs06NNob5iM0YsNPDMYtk7he0ZxwD2Pjh/u7w7X1CyGRJ8iFEn3xihuJzCkn9UU5toSt2jYA98IW32VopPuhqqpBk6sv+Rfs0HvSltGSF1QpbmAEAOrpv/jHlIrT9KhEXXVnQn5uYIMM447o0VAODIDP0UxGmUkRBCZs9YD/aMSaaqjhFjkIXCRIx44G1hMiyJMY1hXV1AVpQQPc61qQqltlXCJShzeDU+eIqeOXKLKEvHpSbSdyC0m7BSjet/2s6Mdwp/JuIft4oUCMF/DoGYGxEo6mi3OYUM+xBpep7iFAY1pb/DzdqHUn9NxwPi6C0OMxU+jaw2733LILmAcE0jFSJyQ4KpeCGubNWjMMg1iVPWtohYbRUuL8Hypq0d9QD2iJ2a6OLnU33HnolnO7VQKSIrBKMMeJZlPfptnytn3CW78xswDIGTsSLYFcbsNL2dj4f0ZU3nUhPy0XKqfEB3DgDpiwH1tdWrpWEaHgIEZWs7HIwSDb69K2kCDTnVGnb6hXSL/k4NvW2qHyTeMPYyqSbK4xwDX37UJMZbA4p62j4mDYa06tADbLsjr0PcLs1hkwanvZEcFz7fo/5Mf6n79QlBsjRyy6GdHwbUF8REbpQUY2j/lF38bz9cz2qwm0OpmpkX8eu4DGxsMZ05ycUk4WdZZv5zCpOV2oiDAvTnxQQY/j3A1wxjklolnjWWLRELaXae1z1KcHzlT+kro0eUIoqSHIbbnhysYb3TYLtllIFR5d7BzJxEirjoyogpnkNBnEXfxzqu1RjvNB1NM4fLOnnd0RmIjW6o7ncj0VY+wWsVVpIiybGvd7eFPftTii+zHU/eOfLOiVLEWwAcN8qQL4GpWC3fKNXBO7cW88YxMhE2SA+aef4WLYlg0y3S/tdoo4V03iSqgbvUwrI6sfcT8biJD8XG95/7MxD8iLzI1Lmj1lg0crieRctFoHel8fnZfOZyN3PkIlQUQGe4q5YG2nMWShtbJUqUs9QF4MuvNB1Xqel9mqzXzfkYArZ33+W6gBn8uMRTiH/uNsdAts3i5CCiScNs6CGXmD/IkX0G17EuHiHi31W2xHq921SRy6VLSM7MuiUmP8HWisDV9Qih8QYA+QI6nKbFtISIDgdLKR4nIjbXbW7FXcr6lu3ujvrAsK+o+O3rWEPhzFwzFRFk/VdwP2BJ+dthGHsj4XxxiZOFYGP3TahTy861IL3ZPbKPLFT5YVx5R+b6z+zaAdEXbE97xP74BJPfTaXR2X3k/rczKgt3GAdwYTHaJ4PMoiJyQ12J5nztQRo7rZdZBMmMqSJcZH1oyPGDCgBJ3nzXbS5F9FLqIbjaA6Sih5PQ6e63j3OucsXZmYU9nA6qQ7fG+x496RsvmvxND0CX+8ryZTbhXDuQoMBPEtY7wXQZegWQRkkrBmnErKEnmxDokiMuyh51z3dJOSYIyHYOfYFR5DAOE+ikEB/IWVva2WuOv+R670WwBRP5e4TqcGgZBk4ppa3YI8/jEqgVP8urL6JBdT0GGwcMwPPxdbvwFPUA8NQq77D01w79w5gJiv2ZXt74iZS7i5TS6yLvw0G/CSP/PaJ291m1Jh4/qSNpBoTEFOrUBhuTAzrn0MsAuuvnPwOnynwh850gqhXmtDml+6JwE84aHwSx5D34jKCUZ+TAtddczIQyxMg1qu7g7WhZe+WCvrzYgW8ZLR6dk7lS3/vXP7mMU6X46xKEb5YmakuT/FTW3xASywnE5+NMAtOWTxLEY60/NiqCVeqI8BPL+9Et5Lyw6di1DlF9Aa4VCqaOGLo6e6/9NlnI/QnFy0kEVxQmOVsRgf9k9P9VAHXMWy4vM05O6LQ/EAptQgFEkRvG4ZKQVcPPM68jSWMqoDdTqwPvELiVAT8K5ZC/OAVqOBqNbMKCzCK92quPV8iiBUnj+07IR44v65BjTWJOUR3f4tm5h4OvRdf2I6rW0RErwXeVLwI58ADfNh1ZyqMua8E4MTB3p7776us8lzYYSmdWCE9GZqY/vQUb6D5F0jO/W5U8ux0Pxqa3ORckrp99RN2vAqviwqMM67CNyyIJqO25kxpVxm4pvCf0h3KX6mzblooM4VFZEMpBREU5FaXTvNDIP00oFCwB+zpENLXLxfaNAuVemH7lbPiA==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:06:54 CET 2007',
+ updateDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:23 CET 2009',
+ currentVersion: 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf',
+ versions: {
+ '12bd9887eb84b99ad40c1e413cccaa9ffd4deed340c71fe53610088faff349bd': {
+ header: '####',
+ data: 'MiAIw+S6GDmLLMcGtkl+wveV7dZAFrL1zGZh/FPvG4kpOBbnyaolRynNrL1yeUbEp4gLL2cK2BGYiVc9196PMOvKPHR5Rqp6GlT6h4RUJ+nFFF5/3LNGzQtJbiY0rrYKptqyPBC8mhlqtdK7sQkQonj5LPhKeCX6AyE3juBPEuFYhvTv9a/iRPub7BdlAocz+bb8ObpbVHnNvbGhiRpx9MpUg44JRxLQYhtDUMi2UFtURidKaK0k2lP81ckPDCgVgxy65FjCq05vSaCW0hanNrIwl+zAgi+3ChriqmflvsZYC7TQzUBPXrAQ8bKmzppZWlArIOppRF7+paWrHA3Qcz4uO5Sw3DvMwbgl+XINnmkE/EbA6VJOjrWYJjsibvbCw6vNr4q1A4Yxwy0a7EXbjFiwpEr+jMUhsq8+d0DxP3tQTusV0l9wcT2OWrDRKdjDUXLQOV9BVw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:27:40 CET 2007',
+ updateDate: 'Wed Mar 14 17:27:40 CET 2007',
+ accessDate: 'Wed Mar 14 19:00:21 CET 2007'
+ },
+ '35af99615d1be9d9841b4a37488fde9aac291c73c8c3aaa570cd05b3fd0baf5d': {
+ header: '####',
+ data: 'lv0pIfnhZZ6ktahFGl3AgAfdcveIcUyAh9x0iVOCzmQ9VjelBztlvxZEo+uByaFh1ptM+eqOFT/Vk9IKhNjRWTXrDXioP7oZ8IZ1kLfk/XuMFH9AgYzm3H1T/yLq5lg1WqqZ+OfO9m37Z4kbTjK9+adIAJ3TwsMxIDpIHYz+qbznjJocubYCbi+DC+4wo6qu5C44gf8n5QF8DOCGaBCyamxFvkqrSMo/Y+3SG3yt98MSgeMScGESuwKKGDHZX0v3ZXvl4UFbxywUtdbipDv4PAlzh0aadMsGqYwO8bPKEUElCWBXd6kASugaqiJaZFtb02EnC+nncv33ZSx+WyJqwKIBk/Kpd3/YDJnX9t3QU60j0YKf0my9oX1746F5u0XGX1DNRaw/1g95zRHoMu6j2cSTTX7CJglzIlTU8kglSO1LOasxm3Gt8iT+8+Lhh4Dw86ugqHXl',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:09:07 CET 2007',
+ updateDate: 'Wed Mar 14 16:09:07 CET 2007',
+ accessDate: 'Wed Mar 14 16:39:40 CET 2007'
+ },
+ '7cc6c6f2eccd8bdefddca21a59669655d7515f440b025144b9ba6b18472cf189': {
+ header: '####',
+ data: '3W8FqWzBVaEbMZRukwXcm03WbvITt8WVKKuJlcSszN0dCJEsIZ9vLAiDp6dfsFF4PEPcSkiy9Ww4FiBYSg5OLW6snRNdA7Wo62dJ3lqn8TjBzv/Rt+khf9mj/WwJZZ4wum+qdwTRPyaoZcAWgA6PAPPVp85iDBP8UBdiFOs+y5kz9GiB3psvOvqC9LZ/RyK3J+H7ierfWecnbqB9LT5Yuhfi8SO/gw+5vve6z1v8sVcexI0o8gk97rDV1W2gZz2WNtO7K5+233Z7aZlzouEbDZEOGG+zEYh6SctWCspgUATElf8vZ29fABsk3uZQO2tnBvINChs6jCRxnbmnjb2Y9R8u2QRtHjjvRro9E+zhQf3laJc0G0ZJp1zN0wwKx+sL7uM6kG1aszNJkzpykR/Uz8bKvoOfG9vkz9+4Pczh5xR+k9rCE8nbu6Yt4EMiUfdfjZJHAhST',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:01:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:01:05 CET 2007',
+ accessDate: 'Tue Apr 17 19:20:33 CEST 2007'
+ },
+ '95ef5754f9a4514e5bf883436d60c38c3cbb15c3f5452d512a05839ce20125ca': {
+ header: '####',
+ data: 'Rko0V7wG9GEmH9pZtXSfxKGDLRhZr65ef/DjkwhsPoYfLryET/ViMjcZcM2blyiLKOxjiS/avGGcXUmInz2AyD5dAFTGge3qAZ3QtxTcNn/fvfJeN+JyGJPIsTIQ7P+jd0uJAb3vPuymISGJluTsP0MZ8zxahSSRUV/VIYwm10tiMVvWEq0+8FynKfWDqJ1eU4pnI47CAdN9CuWhxi12RkMBYgiUzNzTh/tbPTFMc7DIyRfR+si6TuPS3PmtnKt4FMFAX3FznGBCNsonUFf/n7Zy+EYEU/B8wJO+18mqbui5YvmPCPPKiW/pfVuaWarF7zcIcthYoKQfTaCaulO0VRtTA+Wg2LtJv+QcWWWTiY2A9FC/PppLZ8+nFDeng6LqJYKoGnn6qwtSVH38s3Inzbs4r8mSOR099tqwfCnZc9zZHisdIbVm82H3gnqelPmc3IXb3nHb',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:17:20 CET 2007',
+ updateDate: 'Wed Mar 14 17:17:20 CET 2007',
+ accessDate: 'Wed Mar 14 17:22:06 CET 2007'
+ },
+ 'cc7ee01d38e4f1de010d2a235e3b76e838ca05fe70223b8358a5e41975bf2b7b': {
+ header: '####',
+ data: 'TJ5ClYK5JmZvEuNCA+/UeUJQ2rGXbPnFqWP31GAGXqhZmC0RuDNjl3sv0nFKmcdMa/BzvLSywJhkidoRhfKGwN8nZc8M0VpujFkpvdXgNsod6x+5LTMP67qCyvD67pkYMa7O+aosKi/ZWWnYBavZSdhyuWnU1wPxxk+wwcjjIrA5Tm5zTXM/68nLLnIWs2bQbUtcwHgLrBEUshG5oTUFGxrs8zYwodsYUuT1CVwODZrzMxvvbHfH6Lqt94m4hBF0oIrDCd1cSaXghS4PiZkJWQVxJNSsuYF/4PlPrV4ATZS3Jm+DqOxLOOnU2Xu1Qe9DxBppnXjs/WpohYuMV5YeD8iOJLXTQbFKhBJNSCoLp73QywWazuKkasC6cbBrTHYykEKXpt74iE6oKg67YrPkIZJ/jKEGnZ7wsY4ObeDTS7OUbHKxPHRM3ZrmB672R/8ktglg',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:06:54 CET 2007',
+ updateDate: 'Wed Mar 14 16:06:54 CET 2007',
+ accessDate: 'Wed Mar 14 16:06:54 CET 2007'
+ },
+ 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf': {
+ header: '####',
+ data: 'CiJDd/ShGw3rE0xCNZspkdH6hRzvSyaNiuQeMBI0NR1MReaa9uVMV6Ymj+BWVQ8FaOziQ94aolsWre51EKwDWC1otdovPXWHxBXBBI/Y5A4dyQisBeR5E456juUwDtLKX5En4iIuOL14IGt+keUtb5JyfBGuTTA+EnohYzvDxu9MDh/7nzCcWzUxh2zHEBSyowfOwJhx7G2xEvbBgTg+TkejMudbq9k3Owebe9QNdhU9rsY1UMxjL8+HgJmgyo0C0SA91tZXBB3i5ePvg++ze/SW/r+XO/nnVzcEwCJE2UWAL+vNh8tUm+sEbWaqyKwjHNSquxV4cYOG2Lzo45Wp/vZwiUR/8MK9THf0FO1mn3QCd/37AMMneI1Gqk0TNwNtoQKgLVBNhhgX7dIVpRxB2iiSBYyUK6N9LlFahW2QVDS7kdnKH3vk1cP50dj21E45jEhhd75v',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ updateDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:23 CET 2009'
+ },
+ 'd65b23008b22e5000726db3fd22b074b08553fe82245c3526f708b8d89f70963': {
+ header: '####',
+ data: '0y9WhoXwZSfzfxuql8LBc5/RiclPKQxcBYjcdGv7v6B+WuGrB6uu6d8pjNoUtsZnFv/25sefW3ggVgDuI5iZNg2lBQVIwgcvK5jPM5foit49d3RSWl74XdHY2XqykRNDbboKAiNfro+abo/YYQXjkhNBOC0dWSUUw+HmgK/Bm5NmJD4fDTV7OYFsvX4ExjnX9pktaB6aiLZWN1cZruW3Lsszx/ryHpDtcPrmK2hgLQ4FjRSXunbqXKJLOADQiMbGZ8DKZchB5NcEWlE3AfL6ybJzTyr4jXuS7A9PyitxYNKFHAHpJEhxGkyuhUE66QMt1n9NKzkNx6yhhGdIUF2zVGsBUb/pRrL2gt0X2lsZ+CnWFu4jRAeSi3KfK4VrvnoYkVlJImxPiLrzJAvqkuA6TyQRpJ4yFVJ0dgxBoxZVSN1fp9Yvkph+Os8LZscJtpYPPwVDlCnC',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:22:08 CEST 2007',
+ updateDate: 'Tue Apr 17 19:22:08 CEST 2007',
+ accessDate: 'Tue Apr 17 19:22:08 CEST 2007'
+ }
+ }
+ },
+ 'd620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045': {
+ data: '+iiHiN91FfHKOXC8Z/tg+YynPECa5sgYGGofcoJeXt3FAAkAFu3NsLuwjYIaddJiB3MIxFccrCrB5eDDL0SzOS+j63GcoMCeeiXss9YfVunA4RQTTktiU1BknPYfsfHj8EOPDSVHkPFs7KhAnBlgyaDiQPjYko5Np1H2i7F7pRmfC8W5LGdisaqxFDa+1ghu8K6a54QIpbfOmolQU3w7T5qiOdoZv8GLDDoORvMMb4P09IzXpk/yDEZe1GJ4g1a9t+lHAhiKSvdnZf+MhK0jvs6R6ALlmO84lRP34DmT/35Fr5C7D6EJl0OxXkWgYWelTlfU4b8+SStYP5LPYeD38fodSmObpKmpp653T1v2yaTybI1hojgLbH2DuA5VcQAM5JHMjoSy6s76mf2AZZeRnej1dqdvIOTf1Q6CR+ZNIqnkukrtGq/6elF3eZZh1Ln1EZDiTzsMxUHBngtiRmRDofqRSJUGbEAjw90dBoiaIO/WwLAy4cTec0nJxwYd5M7nchEly8Cb+zz7naP+vEGEAWq991u9NFZhrw7WgNgHnG0E3km+X+SYvv0i2MkqjYs6ItDkBNyi0Udnc4CqfWuKa9q04t8mZiy49LU34Ho4/ijuez3rdOeCO/oIwkRkLZYfFO6IxO56tAI3d6iJqmXY+DX0YUZrJ6FT7bDsUj0umV1htuj/uEgQZyOnKOyA8cSjOTMRIkodI12HrtdrIA966BDznsKW4F7f31VaSxI5ezHsdiYEsTqwaZlFQMsjfZX62EvDLJksJTe3JG15BNgsDUUh1mqIDCmVswFTpUTTb+50ap56c/uERSET0iXP8mb4hKwJkmngrBEir3btuMEMS0xSFQ2jTRjlnWRQr9eZT2biarzgEhKHyu2qCUtsUj7TiieQJY09EXCP3g3Da+61nBMoAwi/VqTI6vQaLGtuDrA2+VYGc8x1SiahmAkRPpQS+5N9qPvxxFRbKforMOvmeboFVxdKesub7BHIXQsSOKsHFZnFHswa/oLBITomp3ewfp125RjBUf1C3hMBNg/tmE5pgLqPfQqWK7IOnfdyt0jc391XWb6H3CVcgC8DcPKJ68o7DBucg9xTNwlIxBTafupsBa9JUkBigqYOW8729lNjj/QTvTUaCxWub9SDT6/y1wQUI1wyyg+EaR0fHqumMhIMbuvIPd/SvKMmZ4TXtBc1U3H3IGbkqIfx0f5rI6AuNMD7/pXTAy2Ot1ZBohnQmEotXRvDwxPMqBvPU74t3USTrysyXfJqeFtHi8GTR5X0m/PYQKWCCHgKvjw3d1CJk7tTe3iV2ulk5cnO7tOydTMJFgPuT2oyDDDTp5jYJPRE0OzZcpAzvRSjELfJ111sFBOEzTqtBUHA/E4BnTIM13md0ZaMr33E7ii8rS7vaKrQAI5moonAtAEOVbx/ZrcZ3kGzHpRCISeteHgnM4I90x391HqDkc1A7b+iDQF8OY0H/0as/3gaVaqs5jsuhIByj0+KmoXsdq3ZBhEQRW151QDCdMKdulNUxbKTYV/t92z3slU6lO8fiy+ON/6sTtS6jgnM+oCLxTfpfBdz0uKG7jiSOyunj27QxNjLyu1nF2+mAcDhtMN18QkJGLXKYv39kx7ny1H74i5rba32/QEAFl5eLJNIQbJZfZG3HzKMVS19ZGwgsYNqV1G52x5+bZUTR8YcrLWmPTJ322UxlhTmyjQv+fVCnpksBtjLGntsGloemFF5YVlcl1AfyHb+KlXiAZn+8vpfVVBddFFMeehokzYE1G8Doa/3huhqdtC9qvAtpP54G2p3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:36:20 CET 2007',
+ updateDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:28 CET 2009',
+ currentVersion: '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130',
+ versions: {
+ '0bea892da673bf4b3d3e4e97cd3e1645eb177a8423dc761583b876c5ffb1e2ca': {
+ header: '####',
+ data: 'BmZz8j6Khuz7Q11xPA5zSECcqn7BOcMtLx8AmX2iE4OrIwKWcZ+u4B5kCBxtFPRZWLdWcxAF8VfaedkHx5jxPNeWNIa7NEXXcFLYQv9lwUaxmtqodYtVapAg7N+onw28UnV1vB/h7ll26u263jWYohtd5eMnXhEjIEbrQYpf84jQYlpMKjUDhsVQeZvTI/KfiXa6O38ygO9R+xlq8xKgPPX2bkXfPJiyzlA+GoLSORc0tdqseGGOK4BFyp1V/KRUQ/7uQmGs1yNWt/ijaQtJXpWkWXmjHyTjXsi0z+1s0KH8TwSOfu8yjVshMyIyEDd+EsmZeK0QwMCm96v311cRhMgAkQOqL8xc2uRpGygtTkV2frthF237GOV5vwO9IoMZQFlvKZreV5mPPPBeqfP+o4QRpdnJRRCaP8Ds/MmzGBqE13ntwmo1UVX1k408ZtMCO7h1eQVTgCZ/Y2RD',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:51:02 CET 2007',
+ updateDate: 'Wed Mar 14 16:51:02 CET 2007',
+ accessDate: 'Wed Mar 14 16:51:02 CET 2007'
+ },
+ '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130': {
+ header: '####',
+ data: '++u0MEaILPK8riF0UzCnb+MnC51GYcdqCFRKOP7XYt5QvzWtxhDMOvq8ugCDF8G9sYPAoBLiCxFcuCtnkG4fp563VeEeC/dRnArzMDvjILYKAETgpnLQAfyIR+D8RfUkCbr+aOJ4XEKcy9a240OQJFDT0whoTKuX/6XVzVM/D7F0r+hJiOD1ELsVEi/+U+dXXO/VDxoyjFxfa1+M+Ygk8ewecX4nVqwOiFWHNK2lXW90inip0p8yqDsADx0KhE2tjARWVsjoNdf5RSUOYr0Sb0syyjBMi7oF4jpbLvHpu9fe8vpIcve+aSA/MF0Acxh0/gToDcO8ER3K4wcJgNPIs9lXiSrmuklK7kmS+uhz/rWCtZZH/OB/ov5sez5H51EYLmSNQbx5wZGZhtJWNN+AkJobg/Nt4XKRTe98CutbeiiYUGPxQvwG431Erg4y/q216n55FmCBIHZcUsa6Hk7ezF66c52EuAnVEkn7TZLl7vvym+sv9lKev31xpAGwX5Gy0tx2A7cSE55ZoyqOS9kf1s5Kwprx6RSBzfy7sffLSWHxyOSBnd7B1MNZglVSsbB1r4gMgZdYG//MZ/3IhTFbUqqw2xXHzTvBPA2Hl96g5Xzx0dVx2wHWcPcTSH23VrLscQCwyiDVINwmIzyG4CVSW/6gzA5VM4QYOrUDX2ZA5ligkZpWs0HTqmCB4SoqYJUpafaF2sEtCWHUjuVdw+rQiTBCcRTr8f1Vah2q2xbXMedLCRS3Vq4vlT0a/3wGgVD05CsAom31ZzmHQm94hZrx3FTPenhxLtTOHtDYXnbzYWufWEBSJs6VNtG9F5Md63NZvzEZiggfxTREDRZ7I9MBOPhrxz/3tAo+xInwvLXOEnTNOHVATm9u50kDs1qkJgqiXlxi9pZKmrTu4BeXS8cOxJ8O+Yb0Nh9bExfw+CC8X5xiWE58OwalxY2qlvuoR6mOqdcd+L7YPbGq+hJ/7WgJlrvtQe8IjGF1sJg6jfO8ZeGaPMF5NnbQVxGAq39g00on/z6dW0BLZyA6uglv99si8aRLpMk=',
+ version: '0.2',
+ creationDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ updateDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:28 CET 2009'
+ },
+ '63760358c7f5783d11fd769c78ca3f1ce787113368743655ade89bfa67d0d30a': {
+ header: '####',
+ data: '7lG/UvX5KjLbN+OrHbDeqXmweYeOL+0p3/UoLi2K93mCYdwsvx8mg+zghxwg5ITKPiZ9D/QWIShqiPpl+dvQJGWgs9EcP5W7k32CS2RNFaZ7U820rSpahHP561HDcBU1++5wHWszLnqFFiCuDja3OU90dsCTLI3g0igFgqpaRbjLcRTddI/1N48xNfV1YieC5Kei+jZ34zzrfKRn1f0F7mTkCqCSfygjnpRBgZyo9BfJ9rHULBvplvpslUUfFTShkLnCx0UbWPXog7DIZUCOwvPr3KJvmcZtCJp/1nW7gm0E5PaueJF10+ZlB6pKvueu+5yEgVmVu/lctmPX/UwTYZDgY5VWSWS3C+JNAvV87ZQKKmp8N6aMFMNOLCsOYL5hFN9uWGtMmvtgawqt7OhO9HukSUs8pDTgNeXoWyrorLM0cH2fa6a78GxNs3nCSUmqSQchJf5eWmASZgvI5xXmHXsNbuc4w5R9BaEPzyrrSAIa6r9D3rpFbUhMm+qPv9pZE2HF9liJVdWCBOSF8ZfCjsq5suyYz+YCsFHnwwpYmKAqJNXUMIhxkjgOTi5lNIsvS/iNSN9kdkeWINZk5iQFta34uJbGgjUhRy930ZGMBEV36T+Vb5tz50M6/MnlzAoUDeZAu54btKcrIpIq1Se+8zldwd6UKGq5nG+dMPk7CyKfZ5LkM065KGbgEJfHO651AMWp1sMAsbIAM6h1gVKbRjNyNwO+UK8eDpIX1nXHVj8bDVh96160cFbZj7htsUnXZh2AWuY6ahwdrGwYeSFoVAnd6xUF2oH+zFz2coLmLjD4Xm9IuQFsFO0U1Vo7EKUJHkPgIsXUT9He9tl8/K7UYQMXGgPTpercQFQ1ctFEqlPbFoVNO0j7Z9lmeSBcLdvY67CCbsoBDVJzj/wLRdBQStfeSUe7bEI6ff8+0gVkEFFACc48fWWA6NLLtvJkYjdojjA+C/Xf6EGNeXU/VENMJokB10EJUTueVWKHCLGI/JDBQBBB3HKX2VNFcEMJxES7Gfcbhysm5bdmltyRUJAIdXvw',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 12:56:43 CET 2007',
+ updateDate: 'Wed Mar 21 12:56:43 CET 2007',
+ accessDate: 'Wed Apr 25 09:59:58 CEST 2007'
+ },
+ '6e0dbb3c582039d985e80e10d94f424a63f0cb5b2ffac6388fd806ef89c1da40': {
+ header: '####',
+ data: 'f5hBUeedsvb1VBTpmpQ+XgGbnuVDMVEAdbEN7ZLK5k++4Iuw7l52zX6AHCWUFMDRfT6joiD2DMj0O8B2g55SeOQIAtZb4PZnbf3+ZEqKMOOI7iYSfo2PctLbzzzztma8EUXYkg7sJKCuZuyXhkWZxikBqVQIp9WE/bhRxa/atnB0jJyttnDMdTAN8kxIizrHFfT25hSbcPI1cSzsmF2nLabO6hLlm7mdLZCOD6DSv9hMeOXgqXo7XdfLA4k8swnOA/85HZFmhaYjTyoDGsK8yoJny/xBbiaRij1HQcHkbG6k2QKcs96pjmiJPoCv2dmsU3Bh06l1O4OEXl/RL4qBGJBKsDW/TXy7Qqa5y6LCEnlFAfefTHVgzuEQjJ2qb/z//oIrmujt+8hEa8F7Jyn6+FGqMNRxDvIQn5Ty/CPUStS1lNL1PEb7TA3ChYkYvnuhNVq8HHf47neGMpUwC5ppk5Zzb/5zEP0XH4XXkNbR5/TYjcb0Df3egNLSQLdO13CO3mKeoccmtfcmaFCtOLXWc2xNNcu09s+/QlZMuiu1TAzhWXU2CAXT7K794mTXHXjgGEaEe86Pj1nO1zHN7QhKDN92WMEdYasRAVDu/XYdzpsKJZ3POhNJp6pynotVBOkPk+2g04S8uujLVSIPZIwu7p3RmPQGGvfMviswhyPvSsPqND77j5msYOLCnXXjeXhOe0E7fIRpxPK1F6/N0R4tZCYNJe9Zo248XdqBvl5ZQWDC6aQH1E4djPK/08CS7/kAECqGqOCDPRvvMUNkGOnxsMx5eofr1YR7zWOZajr2GnfhA9fjrLv6KxXPVU0z702aS/Mfnf87ckGpOKA8/ssJiyZ4fzP6uN4pEb6wEta2DnnacUDd96nMvB9HvGCDoYZH646+n4oev+AnkYTy+ZRpmnsG6/3Z85iH3RwN6P2I3DWvGuN2e+1zQ2kaBMDms8qeXVY1+8qWr75ihizHCJr6E8Rd2Sw7xM0+6mKpu6gVGIi09auHg1+6Q6PlCr8Hy/pc4Exj9Hx1m14WKSF2SB1SYOnm',
+ version: '0.2',
+ creationDate: 'Sat May 19 11:26:44 CEST 2007',
+ updateDate: 'Sat May 19 11:26:44 CEST 2007',
+ accessDate: 'Mon Jul 09 15:08:39 CEST 2007'
+ },
+ '84f3b8571428014d04d7c05528af73c89cedf17e23b1f9541fe7060512f4c1a3': {
+ header: '####',
+ data: '2/zsq97zQBq8wE0oAC15HW5pbbzgokoDkLSEGniP1VL+sW3b+tXYOQV+VSFJo8ERNlCSoy679G7N8tPKgA+rO2/roGP/iKEuE38et9R6v9nhCPfo1vKt7XpvzJYow/qDwdStylXbfW9QN12Yx12r/nkPldVTXCYQDF0Vs0h/I1XMjbILpq1smbNXAUdn9I3W9o8KpREvac2H1ir2vYOzq9Ubhq4jggX/9s+FGm40f5MX/OM+lJGdRPCMG3rfWVeFeWEGWpmg0AXpV7eEuKH7sPrWy+QLXD1IwNE03QLhuOh0qEPsEi6kcCaZyLlCHYlzJ/hIAR1CBlCtGm+vqD+WRr0mGQtl81MMl6/BoW40dya/6aIKNOWfmYNgdfplknkVqxFsJnwVqjQJWfCzbW1KqBvMHx/7oPNjbMS0KKhd8ctOsTLSvq4zFI+mvR6BggwT8rwcfa66shJIaDDC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:38:54 CET 2007',
+ updateDate: 'Wed Mar 14 16:38:54 CET 2007',
+ accessDate: 'Wed Mar 14 16:38:54 CET 2007'
+ },
+ 'a4218c7ece0287ebad7f3cdd6510f424245a4d7d42ceb083b664a4335bcb7690': {
+ header: '####',
+ data: 'hQ123ZhZ4AiXD25P/0Laq3MtRO2oSIrY+GoYe3UAiyEHc9HZDCvR+POEEaARXNyh+U6z8S12P1GvQbzo23ZCt5byhqC+UmbfF3Y4FikM7WmHaRPtWjv8JNf3X0iJ9a2IBLA1BlqgJolnVDtrLsFx+6rBIU9r8pI2jdcsw9w9feRbE9/0S0filh66azojT5RM1qLcIUVWGixROY6PALSnA9PCjA6IG5WUa/DX7DyRrosZ9V4ZheMlzlz8CgEKBTN/HREIbPrEocBOvmnbupIEpOvH3OXKDXf39KAGVBAU2IIkOrGyWfT12p9dK+Zf+MQUl4DDIdAbF81Lus+LQmqtQ1ieyV0nNiqFhPuglLvKRj7QZRFfHNyejkMTZQWjQhBdHRmfSxyEgmFrM17yVVz4cMis/44g3szHMgAAfFIc79wq09oNDEV+ZUMS2xyBCALjRmhedqYIMGRCAG15',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:36:20 CET 2007',
+ updateDate: 'Wed Mar 14 16:36:20 CET 2007',
+ accessDate: 'Wed Mar 14 16:38:12 CET 2007'
+ },
+ 'c6613ccf0c1c6b65798c6f35657a10d4c6033aa32204a90d9d0274783a1098ed': {
+ header: '####',
+ data: 'ATU61Uq3Fe24JAEauMRtY8vMjzaQcPtnt1fshTD4dGuptFH9XoZ4bMC4XKHI7JKbx1NUEbR2ySOj9K/NJuWEGZjRgZbNI/KtuxNedlm/7jEpHQx4ZfhXQ8OiUDd+2bB9g6V0Ck2T1gM4IyaZMJ1QfOlYmGGv8n4flhHC5kUzL2OIiAxNHvKQjdEOccnEsk25Gg6FveKHD6NqVunsiCqhxJ84VBNzHJscuCTRcbt6KwR1+dw7Y+nhTjdDFq9UidlxTO0BKYsqj9F4Kq1LXORkSyab7zKooFH5kNd8torb5UFto8dfI8/+DOVHMxNRh2aWSn3O9bzwi1PfYO1nky2O6OKR48Y65Hp1sm3Xj4AAVHWSGakYUSV5M5XxKKzvoKY6Qqhz8GhbkzM2FC0IKTEcmINMvzXdzKRTqBFg6i0t7Qo80i3sQSoju3/4CYRozI2RrF8W4f3/0XgJf21oUAdTXOmSePSZoqhdejXeNQAgb89v+ZextxA6NJNYqvrx1NjdKmWKJIU+o3AgPYj4UIwWHwVADHITKrIWl/SbOsGP5aERtSiLnC+xqfRUOpgfkAYLcytspouHxvQjgNY4I1U/2S1DThG/N2EzuPl7GLYQ+Y3RAvLObFbrV8S3DS6vXIkigxyJT++MotIKoPBq0xDq0ck6joyvwvg4jXUMKlJa8/LQewJlbH8Lszx7SwjynzEQUJcpCnmxixzSNfRzpzgEBQSiClEEqArYykew3rjz9lc9nkdXUCzz81WYsvk6rGJ6ZdDsfKsG9+kaybuLL8huE0ERhznKDJW44ehDGQLr0phO3CI8n/9Px0PhPeZ1hvoiiH8CFSW5f45ZrFaaQG8hNyzWCpCFoX0/dNsNPsAkOJnO4v0PvO0HDOif1JjgPjCS51vBzxu8gYhkWlPo2hZxHhnnrbhxeBUU9jhLAx+NmxxfTjIWkbtHtVjm3ea/D2nuL1YrZKmQ3Qs6GamKlh3WwkRWRAVU3+/mbSGOISxo0u5v8QSmh/IPIXltniaQgWweqGNnCLWluuTyhoqnqDo0II7q',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:04:29 CEST 2007',
+ updateDate: 'Wed Apr 25 10:04:29 CEST 2007',
+ accessDate: 'Sat May 19 11:22:01 CEST 2007'
+ },
+ 'dd2b4cdeaedfc97c384f79c2878fca9a981efde6ebe212138db235e51b80c64a': {
+ header: '####',
+ data: 'd7ZpqQ4CTF00+/UnTvNnnkMXB2Ow/K9dys8V09Nedq4sgMUk08E1vqi9mdWbzNfRD7aV3blru8PfoRrxXRLTG/bjQ6xncecQoAJeUtSplKEO8fhuzGqbMqz47/y3aQDHBbygMAGV3wLgJO2Pv8p+8U/P3cEJisd9OqTNE+EYQz4eiq9dllMNUQjDY9aLHE8H0ny/5r9uohGNjXX/LfFMshjeS4rToCG5mzRaJPaRs1jkjzSntpF0RLxfU1acpJX4pNSuaLscdJ1lIwc17vygg6f3xexqvCeeFZBot1RwwbztZKbMfap4pRF5KoftD9bXJwoFMXigeMGLy0scpzsp1s8zBIwLhwUxEE0IBh7qeStg/3eRSW9slazuIR452O3Rysb+n/jWMyAhIOCSrnncjjH4XHbzV5GgT2d4f8jfBPmOT7l7C1ev41D3FGFxEb5TZGcJTaIW6ofLi5T5',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:52:12 CET 2007',
+ updateDate: 'Wed Mar 14 16:52:12 CET 2007',
+ accessDate: 'Wed Mar 21 12:16:29 CET 2007'
+ }
+ }
+ },
+ 'de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4': {
+ data: 'ZYvHAVCnw96hB+0XxnBY6p+vwvup1BopHUeepu7yOOSdYNFFOFEvtCbxXXoyVaKZAeSd2Vd7YEwRP4TTJjjWNPapT0D65AFqM8x+0rEjhmVfQGZAS4L3QctzRAgBoR1qTr0iqI/46ETkNq6vHz9mPLHEL3MQ/zoh4Pp0T+uMsY5ptzuMPcG0YwajSm5J8XXV2V5ZBEANpgL91xjgh1I9LiKJa/Lv3R9HAZG1uuCvzqjA2LWYeH+6ZcSpadk/UPxDw9c78FUnSNbHAcjuYZ/yI3v5SaZTjEzsB1MtAh6AFiHtvKIMWpqoOs7XQPhz1xXPoGZ7VR64A+/bN2h+Uqn49bQrKjTRGegqkEWFcBwhFH/ZkYfSHCGmZQTVqOakqyofJ22tS0ief45gYaO54YvIliTNTY7SZMRCEhUzz6dz8ENqP7FxhUVcQRbBr0JTmaf6DAwu86iDgkvcp1cY2trnUmlvrgz2GW6TgXoFjFlchUkHIByFeIJ02olfJg4zP8PzgYp2zhwmXL8iXHXnwzuP9bQKq5j8o+UhR11zn4MFvWQyD1UEplK6vphMdS8iXDViLrOwuMz1XUf7RxNdW0gqXwx+qLU+CeypyWLMIlgTlOr1pBqD/S5Jx+Gbn5GHQViuFZHJUjJsU0xel001KjB2Wf1Y15OSdLZ5l0tn/4HYKmZLufTYpub0xrss5r3Z72RYz3wvAWFXzkxWa+oBiRQiF6+ix8DBPTc3tm+ORnQBYcV/VNVRziimV3MFSsD1nHgIF1zu+eXIKE7/b3lzY19KpvtiBio94dejWoA/WO7KXWv2sHH0JoZnRh6lzu0HRFgYqVm/052nCGVA6XSfrFtfIupxdBs22C9wrwC5/Rwanf1S8BQIXpm25P4dv9Y9cS6c2/DUHcle4tsUJlqC+LpRGKXRdolFkiL9r01V09Kev/K2oXaWGYmBLbRfIyvEHyHNeNXv5fnaZ3pTlIwXjJ9K9yKA/1AKAsAEuKlM3N5ep9pfyuyfOWj1I6RvBwVqKvcBZtYJ4u8n9jrxiyq3ZZ35eB62D+ceOAD2s5+LL2IylYjiJA1OO2qpu4x9rt1NHXM6LYJAruBnUrJ0Ylqz/ElcJn/lXAzY6RLqVcZ+tuV580AUkFiaXFEDcqdJbbzh0R15g9DtaeiQZd1PG0a8Xblj9aMQoRDRJeksw1GWO7TfrJX1Cu4k+sgARWRzZ0DvB0SJAxPcmhg2iBByn2ESlcxPvMOpzuJI11BUQsZZ7dcynubeMvdqBeKsC6HMcm+8DLEUPmzsC3HIfARlNbt1fOrGJNuKaLvF1AAdwllELoPf3lQ6EVZI120=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:20:58 CET 2007',
+ updateDate: 'Wed Mar 14 16:47:01 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:06 CET 2009',
+ currentVersion: '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28',
+ versions: {
+ '201725aba7b4dd93531e40ee08eb8156e3aecd3db4f11e54d4d88ed5508c72a2': {
+ header: '####',
+ data: '4ndloDtoW1Mhat41ZlW+nN+WkdEriCn/z/oclyBFQSljJRlMwUFvzE/OCVYc2fQx1D1GBedY/O13v+SCAiJXUrr0dgrMDOfmYy7ZtNo0hYshjaYQucJovt7UQLeFAuLO6rNK9CrsYA/AWoiT878z2iCYCqVq41sL8juCm9n+d9aR0eyjXAKj8QJzVz/uvdudoGQ5xL18x2yUZnemY5gQklYlm0u9zzCJ3rLOENnnAggFnSJ0oysNjB2UwQY6P53bqXzF8E+u6Rv3OoIbmCIZMaoK1G5ivnWHwhLzp9UVdIj8ipfLsTJnGMk+aZ3nnEJ7wQCaaLy/lY2RYmSeUTTZt2ImK4ZLrSxRC21QkD+juyIiaEBJdhP8UOfcqE8Hw+etc/Cl0QgBtv9AgXD4BiZs3HUTXsV/PhIzP+6TGyr3/A2kt8dv33V7Gh2Ba+28wtsG/+HwCMk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:45:40 CET 2007',
+ updateDate: 'Wed Mar 14 16:45:40 CET 2007',
+ accessDate: 'Wed Mar 14 16:45:40 CET 2007'
+ },
+ '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28': {
+ header: '####',
+ data: 'eSAwxBi9CLckMV3o9PxBjVZZ47g2AOIsbPt8QMPta7U+6KKUm58cXHV7BDfRkbin3JYQJGYfu4HYHmayGt4IcX4RD3riftxnG3UFNqG4LQQ8+fwA3xTMBisnUSq0JYc/PKdBKzxH9x8moSqZC/cgFWe90p0PxdY13otjd1qvDL2ALAgY/uEDboTcLTbSEhpGIYQHtQ1ZjDG+KXI8J7atuMvS0KFreNUm9+uMZT0yCXwNpGy+ez2+ZDXTEjZUKaFPLI7g/vyySn6VMXmlqJftGXZ+fW5UWGaxb7WFa1hh/nI2okPuRlUQh50xXQJXVvanw1ATJbN1PRfYEfvQKLlAAwYuoB/qL0y0vU+3OktAbgBvwt9prs3IsqjwMeaejVTo3Yj9pQPJ14a+6lxQZQRFUaLePIPdYvq9NRM7chkNYminW0JN6umi6bvJ4KKTyjAglBQ6X4s=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:47:01 CET 2007',
+ updateDate: 'Wed Mar 14 16:47:01 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:06 CET 2009'
+ },
+ 'c7398bb27021058c9965a332d678b0070287b8ad12694bc8732346e6d84fe9a9': {
+ header: '####',
+ data: 'L+wk8k9ejeUeVz0offdItFpy8drMl1hi0FODBMKlPIAmEcNjnHU/IktOlyLrK0YHj66DaplXw2EyRkJNcMIbfACUtavxhWBH9VTftOPepsbsrU19aP6Xk7R1pr1sC76w1TgKCjE6IyBnK5qk1oHqcGv71GJLMmiqGivKyYOXQ45SH9tbHC4GUrg0YxoAYRwXqg+SlwRHpSZkX55NzPCEZn9eatGKCznTZs7pg0uBoM546fOIEBMgGndNk6gnsAH7At8yYxDMnkGHUctsSExL1O+W3bDDDx7D3uPkkjtd9se0exPru0fmsfcKPrcRkx8b8MAdgcylOtMdYvSudPdR6foSIqKMqktH35QlH6Rr5E/ire3O632QlmCieKDoPk/cB/qL3gKedxT1NxtC7SNR3aumKBAKOBDTVSjWWq3sIImQPZz+RUdRajeqkryNDVVPLFyjdC0=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:20:58 CET 2007',
+ updateDate: 'Wed Mar 14 16:20:58 CET 2007',
+ accessDate: 'Wed Mar 14 16:43:46 CET 2007'
+ }
+ }
+ },
+ 'eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 13:35:58 CET 2007',
+ updateDate: 'Thu May 10 15:01:21 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:54 CET 2009',
+ currentVersion: 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec',
+ versions: {
+ '157b5933272bb6b8a70bbabb7fa0369eb2660f7f0848dcc653f592f5afd4f2a4': {
+ header: '####',
+ data: 'z8BUTeAbrs5GeJ+SxaV9ceaAoqxtW/touC8xhjkEqbG6+IgMrfuz6ABRn+vwiN1/Vmfw/tyad4kB2SyzKgaYPH7rXyBir1mzJi73/oHsXv5wWNhEePmjZginGGcWQ0P4AnrAoxlaI8tXo3fbsz8e40x1b56N5J6zIdvX3eewgIMU+J+iomZVPDQq5DNu0aGUL1xs797FNm4vLQbVRF+mzrZlT4XZNzOr/W/Br4vG/Ureoq1QRjAjj+8HRt7ojmzrpDX3RtmSbWqUPQqx/KpFGqVUNw0zs09MomVIYilRawe/zegW2KZKK4rmqoUm+mnWQTf/I31FYO2N8dLrI7OV71EWlVN4FSO2A7NRUd92uVxHzItMQPS3CSQ57FYAC+WhJh7k+/ikJumVSf18pZRSRaEeKPxbJZFJqrWsWk+SsqBIJ4EklAnBBU7zLmMVe3GO/ml3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 13:35:58 CET 2007',
+ updateDate: 'Wed Mar 14 13:35:58 CET 2007',
+ accessDate: 'Wed Mar 14 13:35:58 CET 2007'
+ },
+ '1835468626573e6189e5302f6f354628f49900efe08adc931990d1c11fd522ef': {
+ header: '####',
+ data: 'Bv0je7USknogpb1ng86CEx6GbHlysuN3e5Iy43kg1iN83AgRm0Hp6/yMivQe/mEmQb+67cjHfKKrznAESYzY8uv3b+ystxoIaQL7tKJ5HYu2NUVvZxRC+PE7AkBhc+O28OzpZEHXXz62uZFsjRDw2hC/KP1XfYW+Deuulnpz6sgjuyWIYXF2486DzaycCqX0NmYXKE7oXAthOlbo+Zsm8Y5MWh5ploJFrzhAm0CCzjsGSa7NBOBWU2o6vN0NFMcOG2pdjZGWpWo1QQ5G9tx9UvM5pTamwcg5TOr4yOd16JmYTDjK2Fd5mdUuG3zIxFR8StIKI/Sd1ah8U+DGbNlVYAVb5OREJxQxVv6I5dxGC43CGWbpx3fB5wuFT3Jek6tv+LgBJaI9Ika79NFJQrLVMFbQgD0qU8YgCmLbxIJ4gxMBUgTN+v6PraIDHleYlpW3KVIiNxv2Ztc=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:24:49 CET 2007',
+ updateDate: 'Wed Mar 14 19:24:49 CET 2007',
+ accessDate: 'Wed Mar 14 19:24:49 CET 2007'
+ },
+ '47f73115ba2079f4b3703f502e3455498900a21941625c25d52ebb7da31055f7': {
+ header: '####',
+ data: 'pK+wAHWg4IJcixnFodLQ5EH+SFQIOMOrthx52u21WZ1ziRWJLSYGwA8CNNK8/welwzPHOPWu2El+zE6cwLHrzmL8EARLvvJ2fEK11ZIvF2C3R06uNrA7QFZr7iu6t67osrpfljqbjKQrMECUCUDrBywRvlpaeIlThfA3XByezK2HtbyHD1/xnyQSenUFu/6Zq1EkVdm9iCkbej2KxZSxA6qMl1WcnplBdOqBSmeGGJ0+Ikn3LZ7t4ztqflsug7QYyQlrmI+d0UB8MFWpf6jYjZQwf1rMH5XHFvrWUCi5IbFNJBUPF3n3IfUlrnjUSBEcW3tmodJa16/biK9/iKqh5ImlnpbQgK7CStgQ8ByJqddJre1idCiK/dyR1z+IXHTu4qm24cJeGUk7la4WMG2O5U/otFbXG5wTVgbLsxfXlE6fzxHAzvEftEE1ZPNOBpRZ+LVYEHKFESIz',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:41:15 CET 2007',
+ updateDate: 'Wed Mar 14 17:41:15 CET 2007',
+ accessDate: 'Wed Mar 14 17:41:15 CET 2007'
+ },
+ '6564169ac5bce1a632c602c51e9e5d637bfd4e87c1fa276e2cf65f39405fc4c9': {
+ header: '####',
+ data: 'fs5hydWDsT/FxWTb57K6zYKwVF310zjHHHtRS/AeBN8XZqTcirhV9oxJW6G6TdDkD7nQfWf53AbsivXn46Tx7oarzoU4R+1mz94TRCkEe5X2X7Wa3HbTj38+QwbkomF7np4MUkVc06aRPqkUE5hvSDbGn4SyKCjo/AnGhuW/QJIqnWVj70tf7CNTb+GR/y41JhJd7yk6U3cIP6Imik+DAvM5pE0KqxGLfLs4c1ChuTFNHfiQbYjs3tANqJCO185t4S8UIY5VxMRcnqgRoloFK3uFACIXoyDGG3FjILgxRCw2ePFsrm2Jtxv+JX4BsM+KDk67OsN91rjQnK5vBP72SzSge4EDCKJXYKdA8KJGYNwRIzk5d5ycbZgW4YCizVw8v7sLMn60v7YrDfBwXAJvvlTP1chA7HoE+WALqXkfBW29AOCNodE3eTXbI7iWz3vcWOCPvSm3hho=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:25:28 CET 2007',
+ updateDate: 'Wed Mar 14 19:25:28 CET 2007',
+ accessDate: 'Thu May 10 15:00:47 CEST 2007'
+ },
+ '7674ea33b650e84f9a461a91928bfc259de5549ce905339fc3b23623c6cfd09e': {
+ header: '####',
+ data: 'D7mLcDpylLnklOtIw/kvYX0M+CR6Si2t8CB9bTT3ZR+bTpXP88OtI19g1k9iPEUPdgbtFKPVw4oNmynP3x+pc8R/zzn4v697SvVtQxdF39Jmry5dnB4SMx6oRkuaISs0nxvTrHJe8U+s5ehzvQ2WWxWZ+LaoBWaYR7slgUFKLdJFyWEalPwMPVu//DoLZeWg19n2C/0Sy8u0DGdYHJVserWrQqxxg0h0m0x1wuKhF7IGvqgyJ31T5w00nMHNZbs89cUuqB/2doMgoUD9BqV7F/53AveuBDcdCc6jlEe8NOdoUyMuhwwwTyKONfjY5e5Cu5W9I36o7GpeKlckoKrTIWFO+NLG8XZvP/f2WJCsIOrCk/LI3C+bxBP+bK4tHRH13iXLeJYUlMK4ibcf8WI445qNoggJSbZzGr7Dav23KZWPcxzRxhI2u6j25/kKGnu4kcMB8ke5N+4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:46:36 CET 2007',
+ updateDate: 'Wed Mar 14 14:46:36 CET 2007',
+ accessDate: 'Wed Mar 14 17:40:01 CET 2007'
+ },
+ 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec': {
+ header: '####',
+ data: 'u9HEcfobxZhG9BY3dVG68ZUYkREFcZ4q1o/xWyt3qje3icA+Nu9yCrZip/4fqe1daUX/MHyzUQdulIfjSwATjj3vvDSPjuGvrtx8oUjJ/K6GFsL366ozi45LkqkOaH02/nVrb+ik2HWIgcne/OzNrwf1mWLJoBF+8ZwQ44xqQK7ikG1mblNWWbZFFQE1B0QPmE/I/1ovm2hAr1ZsNj1l+N96hwGsdsdVFTzn+S7Sg8GTbxEFAxDQkBYEw1k/R8i9EIBndPoDZCebr8vP+c8qSEk/YmBXJ1MGVVvic0/Utn67iNLz9aBnv2z31DvvBj8bIwOxQpB+tom5Ivwe84tFkwwvpxFqYccrEg4bbMcevUo67TBVe+Lb2wzcK0zOr7iHhswbXaLzzOEQ6uF/v2ibTbATP2zNq09AIJjynoSDmrisGHsBrHgeXjiDspc9U70PVC83EsjPRwA=',
+ version: '0.2',
+ creationDate: 'Thu May 10 15:01:21 CEST 2007',
+ updateDate: 'Thu May 10 15:01:21 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:54 CET 2009'
+ },
+ 'e699fa287c2de3d483144b48064a47cd0bc56a436431ce23b48cb8d8c42ce851': {
+ header: '####',
+ data: 'hVD8NOt8g/DIe48JbUUo77e2hMf2UBN6ah23PrIzGTpq0LifC2K/0/s0yeL/PHUOncdT56NccKpF8Fp6EWJqDKoKZPWASuB1vHCEkdbcxlqzqo98VS3A7p2JFwQzSv+5t6y909hhbxobXMCUfZ10HBqGo6TaFc6+pkYqQ/d7MEnj2NuAXC9X9TLLuZSrZ96NCKGr8YVKzxinxHdiF3TdRvIppFByXPlbZ3xiielEnYm6pu/GffW7Hkwd7Vou6jwyggxVqvoVtuAdiIy67l8GX0gQUGipFkvvrAkXfm0sgtWGQvpgDuV/bXq/L5vX/sFpWI2u066lMUOsJQmptNP/Nkp31+ZNk1nCcUIYDDa6vcOy/gRrOFcenPTUQjRkE95KPaCqYBSIWsjoFE0EIB+iBnBCTK3laBSC7pplOtuLCY1YJcJuOkzCVQCVXjhWrNJM77s7a5OyTuE=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 17:43:29 CET 2007',
+ accessDate: 'Wed Mar 14 19:23:51 CET 2007'
+ }
+ }
+ },
+ 'f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732': {
+ data: 'vxOgJv/v3pP8GFqbFLTcgtBqw8V3zhCN9rRXUuWAfatABtr3pySWvt74ITeGw+sDtApBsu+zTY/95BFVtK3y0QJkC5cjJYhLDwvMwpqa0lRfCXWSYmuEhbPETwkW1MN0kAEOMqsUD9cQCH9GDD4A17W89AoTG5Ce//X03YBG0cDjbotgENsWjQpK88LXABHBQAoTF0BPDjN+xai2QPCgN0l1IVpUzI87oZJS7x/4r6DjGTOgcc3+vtEujr+8dGNaq9xTEfAFs1kv6GMeT+R/VkIQLVO+vSxi2fd+954EAXQplt047+aZ3c0c78N6B+GhSi9DgNnbTLu6sl332Zdgo9R09uucS8nvRp3HcTzxriKpx0ZMDh9K9ig5NT9Z2H49pDjCJKTukDU7b2ktOEUNZt58s+uIlw1bMFY1TMETGAHbTq+hld8Szg8f7nJGDQF10kV2ykVEQ2oUBMC9y9VCLyYD0BWId6DUcTNXyI+MqAC4j8pp0NhURY8VSjtnV4Rlq+b48ahP/ifJdq+xrSiT9ykGqc/EyebC1uCTIZewk9MtIAndVYPckMIe0xQ2xhX6/m2bdNboVa3dnS5eKFdbd++un6FD+QAjgtcBkXQnwfptottZoghclKL5h5gPePCQL/66CLYy5+3xctfCG9u+VkH97JKL2hW+XZ/KuxLPFkIAYmbFKsNdIizfpbk5WJvoSzacpo1mwNjZ53zn9xhy/VkSIz3lGl83a6FyoHuR9VklyhTaKrj2JNWzjLaQPiR9Sv2eFNjLTivxtxLwKae5Tz14WU2QlXATC5xdcLeF9nK7yYVarcKlRsYkkvetrVpRiWUVfy9mZQIHOWJtY5AcptKso2Q0v4CuD1C/wV18DMDXzwMXeOq0cKxCsZOuWjO6RwWKzfeZnJ99S+EsFmdI/wxqiu9slJ0xXvgLvjiJhJ03qWwZV45peU1qmvKQrXS80QqLp3kUfRGLbZNOvkZbyf5OK96MA7lok8PuCZGg5jZHFX4B3vxSQ32P7VGSWO5CqHpF45YwtlONZKB0cuvKTRazZ+B2zJfwMYRQloj6sL5501oPqmjVtDg+0aoqKe5DmTf+fHV4FwAxQ8RuW7/BVL+lwf+zjtd31I/yrlDdb/Scs6yayLV026yuHxdQRl+ByogtrXbY4ViuU3NCkVrme7K7meRHnQdXyidhjzHdoJnRPa0IoI4VW3VwWNENRRNDTta2whOdIKsQYtscWBWZnQplRmDChGikERYQVCWejDNgvnbnGrlyQYPF0/vcv6PoDpIvh7Pze9y0MLBU8DnWqAhpdqHPNVdjdq51OKlSitUk5TSN9kxePe0KNFZueLjxZHUFIZ+SIkTxoCoaRWYMJIWvYkcT5S9Y/7NbdapuUaLZNGDc6tgD+LVYRRvGEdPWaOHb7G+qOmdtx8vYxZUqq5mtwnIBRzEllTJyKwwK/kOfAxiRjLxf7SOXsubPuA7bHR9fI5rROSR5rcU+nOfSV9Wf4wZkYBlSmQYqzQfmwl0UCiipJVa1DwYwLimgo2RqhI0M38gEH+mrknnevE8zlUIaEWzxoOnyWbtCecakXS2XvE9j64dswJ3bbeQ3fDQr1308x9qKSjFdDl3eNcJx2e9YwC7wZnTmHeHzRXnZwXsJXqMPDQV99wEDBr71BjlDjMx7vG9bOWrhsyJ37EOvO2X41Ij3j0X4MYpbNgxBFP6zJSu3gILrtqQRpQq6mQJ1bWHyCN1ge1zKNT9pG6rGTRPE9LqHROQuROpgFM1R+DqW4XnGOBYSOtznnsnj5fxfdpGeFq+v/ftvVuN5XsgX6dnT8R77iNUs86Iz2mkxLaQokkNzXl5o1rnQIse9+kcKVZ72mf5SG9s9DD7cZ7bOtmkuZCexJpieIosqLV8jc0IA',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 17:39:39 CET 2007',
+ updateDate: 'Wed Feb 13 15:29:04 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:41 CET 2009',
+ currentVersion: '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74',
+ versions: {
+ '33ce5a03b6d36f59d0fbc9445dd01a515cb56eccc6d854cffbf8aa66f3e4a45f': {
+ header: '####',
+ data: 'pwMmqFOwpW/uSys3hm/AcoERF3eDj4dO+O5SdYsR2mJtmEfXcjhS9altLhVOsck0KMQJdxE3rNDFbduF35yVetXuQrrL+bSRlXMq03EXETyrRzIVhFEM4BjoCSS9nKGgixp04Ve9WSuwD4cXRmcN/L9kCJSCqflXqhkYkjAywQoj1KxHPdAqMaGRpEWioUIfX+NiWbO/qtOu/USAhHmWFXla6/A9kKQeU2d+P3zl9KF2Zm8qm8NXjPKmh2dkd70ATbdzxt9P3BafoRf/Ud8zLIVdQYTbv0pn6UMIiUDRK1ryvgfSY180zg4qkP5pBnxhEgOxbjT8JO6hCl8n2jUCRJLdUXHwgpeuHcKYDyZizc+p9Kbc4+d8K/2UEKgSR6gza6Cpw5TQbZQq+2LxWUoVb3HM3lTqBKUPM0FdY2/3twZm/1bI1uBMPnyp9x/JsQV+xOpu0ZulTA==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:39:39 CET 2007',
+ updateDate: 'Wed Mar 14 17:39:39 CET 2007',
+ accessDate: 'Tue Apr 17 19:09:44 CEST 2007'
+ },
+ '686ea579db132287e8e322194652ec57cba6e60274c00f734db7a0b36702c817': {
+ header: '####',
+ data: 'ilf8U30hSq2mqje9kZkKQAMiEFV0aptXrm8fOtoOR8pp36V29kXyUX6FEOh5eXSRr/jbqGytxKENJeAGxnsv5U+8GgbvlYaR4MPM8lbKcpAoBCc0+CCOiwnp4XCoXFCNttbTzfb6qgR7wqdK7YLnrvfzJieQqJukQZvtWtsVZB/Tis+5niomz8Ca8lo/FjFOIjAq6xtwrW4CS12+yZdTKNbj8e+HwoUcesF9RbCKQlpVHuwhZ/8ghdzDgjEE8z44rDepEv3Lx/aUi+67velLH3j+1crnxBUz7wP/dWzftwWgIxDkCR/vW63yY2Xebt77swDg8g1Qj5OJdYiAq231HKaZjxr10y88JI5HC1EvbbduDN6pknKUgM+qEdojpi2BmjK+9MtV7sVhJoWqwHG8q9z03kgGoFnWEb53HyMVes1n6HYfzwnw+idPFWGZJ4IB25WfJLfQuQ==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:12:39 CEST 2007',
+ updateDate: 'Tue Apr 17 19:12:39 CEST 2007',
+ accessDate: 'Wed Feb 13 15:27:04 CET 2008'
+ },
+ '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74': {
+ header: '####',
+ data: 'l18dnf2TRfinuu9KDraIo41yvG3mNFqiSCOkyMI6WZZD4RnF8R2Ob19fJ8zXv04eDx7TYyyGP1IlFWEdT3LBrOmmbtUmIvtYanIfKTkT6UGHNH2jh1HyHqJbpgIlr67mOm6Es/AgF44BiyJrk5R1y9tA90oeUQynMufiM2MFLpdalDYWEh+W7GV9WCmbBIU/soioTJ1ep2gvy4kJvTSrXENaxHevKfYwn8ucocvY+hjkWB4GWOR40qtaG06wWMLeRsrTBH1jBG9srzbBa4u2IQ0+NJjQrYdiu7nfu6Uyu7Ya/4bxV3Sukao91XvXSFIhcI2OuKl0njUshv6BDEfHwXIQuPtn7KaTx2uYl1pUeTv/tAFvf8Ng9OFNgK0siIMkeg1thFwRiGSmxjP0QZipDtcCekIxj2k=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 15:29:04 CET 2008',
+ updateDate: 'Wed Feb 13 15:29:04 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:41 CET 2009'
+ },
+ '7ee6a662d1980467eea86a58cd7299ee02000740693df2a7ab9dd64347dbbaa4': {
+ header: '####',
+ data: 'ZnwtGdkg72+TQKCJQhZQIqP9sz79FcptnmH8VJEDQY9xTburh4cyhgbgROBis+awp1C5OyiAAoWfPnuRAN8Ai3d9f8M8yjnDGJ4BAJ6OjQ5r4RDQxNycCApXWO3mJpBrx56wMsCVWT6Z8a4khzPrf5HlDtus4lRV4GRdhU9FMpwuaCfgVD38MhlYXDaPgyu/8N+6eQHuFxquXjOJmptfO6tVhP1+/tEHo6iUAX3sXMZAionssRgPllQJxfzrsu7GQk3h66PakRzgStTHUCcdyoEe9c4VnvUgaasTbhENA4x8xPrxjo24zwxfFpWNEb1+pe8N3+dOXTsIdd3CMKrxQ5KkwzyN/Bj9jXNk9YX8PC0geJiR3bCGtPsAd7aEFB7E6y0RVX/RL5f6x0utSYw8mg6lfprlr5A=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 15:28:28 CET 2008',
+ updateDate: 'Wed Feb 13 15:28:28 CET 2008',
+ accessDate: 'Wed Feb 13 15:28:28 CET 2008'
+ },
+ 'c860f9bbcab5fa70854212e18c11a3e9bdc2382f91cfbd25636955c443a05f8e': {
+ header: '####',
+ data: '1rztZ6mKVFVjlL1kEoUsXEMketdElGbOpYK9iy3g1/WeMcTd4D/UjgHvmQHzzNuYJc/yx6cCMMU9dofLe3vWLKhqDAPAVCo49qiH527hP9rQE+0SNO1v2Ymk80hL/gqBfju51bIYxPKAD0uYA+GMX7OdL+S7qdealebERcnVa0K1AHiVU8lu5yIKk55U8zwitk0u86J1zwcraiM3RGXir/x3oZRIKDwT+lhUJPr8GbVjgKlPu07Ii8OdrAGdHefETDlyNnaKPJHTbGXkd3HZ2CYhJCQZGn1Hwfs46iRd5aO+3UErYtgIHl6CXuXd4E+DNW4UJZedP9YV860DBkpqMiQokEMYTh8Y2sOUyf3ZEOshfGvJUhj8O5p7rNm4+2BYO3XhREdV39tn4vUj56wYj+GL5CekEl0c4Mx7ViTQA+gLvk52V2w/5gFyFNQ9U+jUQpb2n+d9cw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:11:33 CEST 2007',
+ updateDate: 'Tue Apr 17 19:11:33 CEST 2007',
+ accessDate: 'Tue Apr 17 19:11:33 CEST 2007'
+ }
+ }
+ },
+ 'fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6': {
+ data: '4zgqvaaWm7nJO09LKN6o5hbWwGzOv7VVmXDu5T+JCHTSOXbteogax2Zrv0uKLkfooGFThJBk0rXfXxE64vMOq3AeHXGw7Chg7hz8Z2Lpjr4FfE6q7Em7UuAlAuL1PiyXXJJK5iSsRY9tkizuYl19aXW+CgpPznYD/PyXgeYxqt9WLqK8cl5iAU87R0cQDhwl16ivzVgiiFeaB6B5FQqWBAHCEgXhqTsaw2gv4snbmPOqcUZbHy/Vb9hv4lPBJwGFNxQzeZUad92VBC8YbIjmbohDsXjteqD2/k1qOgpUB/U5BpyVwsi+5ahgb8gbS+AqYoRDYzkaj83ksPI4JzWyZhpqjhDauaI6M7hGnJ4GB8UZc0M3WPgrlf1r+TXCgpcfembqL1MyteM+C+ItPRP/QdaIXxLOmvGFOBKQYEI7UceUWBCSEzORlS2S2lltlqt+K4B8QTULiKaXCfRmF/u60FpJufIkUX0pE/rQVChxswSWvh7uJFDBIDx8MplTX724A7DN5d4/Ad4Yi2cj3V8X/DEErnHTvirP3tZ2F2oAe7kIdu+JuCqKcMaGB4hVijzv+yim2TCPvrGTFaMmg9PvcWHpik9jEIabCkdqAR8EGIkD29+yvG4vD0DTRKv2vPIfr60ZQnsgs8nlPPoNa6lNHvI/EO0nBGBYBc1TW+syV5h/zOG3rHX0XCHhISZmDMjra7eUETWChncR88P7ciC4yJQtzXFGzeXp2ktzZ8m5g1EQfgtlUVZsHN8e4OQ9DjKt0unfq5RFBj2jlG8TBZn6ZpebxWR2qOxp81KQLHJND9zRTy3h65+k5wo3MnnxE3GbeXg2dFIORRvGUT6bWsqW1fqR/pg1GO8KNtrt3CryZofgE52kuk6hlcmSk9974JR5523+1/hbts8n5VrTi1C6GWhnxpiJb1XIvICdag5g7C2iYppzLKVzbJcFMegwDUrapbmGhkqnGwSY1EQSDyagPr2xlziWhdWdCOVAYcyw8dOpdD97QhVef0OWrJ8nbgFKD6wn21475OFxooheWiMCyZwXqESVG1cVCjeaCsymBtEVPpmQdSkOfMdXpKVF+3osb4K2XDpPeU1zPWVozeMp68YhLztQ/g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 18:43:29 CET 2007',
+ accessDate: 'Mon Jan 19 16:09:30 CET 2009',
+ currentVersion: '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a',
+ versions: {
+ '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a': {
+ header: '####',
+ data: 'QfC77EWgmmnxz9JqLdn9Tw7mNztfQZPdNpaML03EdFpphsjgLloqBRX0UZ21oozjQGHpcUMMOsaJgzCuDlfh7T7ePVV60Ps4AJtzv7bHSVGKsj1iALU1qjtesOYJayp8bA/3peo4HEnVgP86jc5NTwJxpsUhNG0Ae93xVu4lPF0gL0/yjgZUHqYZXkb+oXrcybL0BSOjRnB9fRpA1dEhcwJwoelLTvg7il354qp/Wo+S9Cz5E/K+xnlJAuSXCRXboWea/ZZ9TX88q5uUcY5jLF7Xi2HoFVZw2f5tbycxwGtT1CKXp+OAKn6mQaBAYM51zoMNDT7MvBDXD3v4Cidjgh24GZ2zndfkYT0kHCtY7OVIVSTsXTR+5/XMedojVvDlX9LBa9ST99NLCUy7Di94rJtX72ev3Ei3I1w3qPvCl3jgD2VbIwLogCzqLtY+2IkLAa8M2EpX/D+h',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 18:43:29 CET 2007',
+ accessDate: 'Mon Jan 19 16:09:30 CET 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'test_test_offline_copy_data': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ '9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8': {
+ s: '55a27b18e8fdf1fb5e5bcf859cfa50fcbc69c9a41f04e371606a86411a98f460',
+ v: '983a6c79e7d5d490c3f13645c49760180fca05cc677914bf60fee009ead5a65d',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13":"0"},"data":"Ki9chN/ker5c+7zB5NinstllVq1Vs+N5pezZIohKVVa15VLSIyre3DRilRoldy/94LbGaEM3SZsMlf28hYbWySln3ekNMIB+MItaYb8urw+8U6n8+QaRMAClHXukfi8te2d1OIlgjbrBQNMmzBorjIs="},"directLogins":{"index":{},"data":"54KM7x3emxWZH4CQDLBj4SkT"},"preferences":{"data":"AwOQXmReKkLpp8qZa4zjaWcY"},"oneTimePasswords":{"data":"YgSYIsDeVT87bfiASQqXA2E9"},"version":"0.1"}',
+ statistics: '6Kupec1ZD7Dw0WzK7pPesnLE',
+ userDetailsVersion: '0.3',
+ records: {
+ '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13': {
+ data: 'dXql3HZJQRpvwOe56SgzbbpMoYWRBjEp+E8uMJT7tprzYJ109H1SnxRWWiXlDOzH2XfoXahP3S59K7rHeJ+/icX+ZrsOvp3YEW7wdoEDosyvrQuxrmHdusZ3BeaFIhQMmK9wqpAzpKCRrz30l/yi81zNpLgTXLLK9fiAyksmsfQL3VHgQg==',
+// data: 'bXql3HZJQRpvwOe56SgzbbpMoYWRBjEp+E8uMJT7tprzYJ109H1SnxRWWiXlDOzH2XfoXahP3S59K7rHeJ+/icX+ZrsOvp3YEW7wdoEDosyvrQuxrmHdusZ3BeaFIhQMmK9wqpAzpKCRrz30l/yi81zNpLgTXLLK9fiAyksmsfQL3VHgQg==',
+ version: '0.3',
+ creationDate: 'Tue May 05 01:28:36 PDT 2009',
+ updateDate: 'Tue May 05 01:28:36 PDT 2009',
+ accessDate: 'Tue May 05 01:28:36 PDT 2009',
+ currentVersion: 'a22bad10653a70ec3287917bc23d642fe698042cabbcc1074b60122cf2bb9d4d',
+ versions: {
+ 'a22bad10653a70ec3287917bc23d642fe698042cabbcc1074b60122cf2bb9d4d': {
+ header: '####',
+ data: 'Pc18C1A9NwNlecbOtOOAEymNZD5oq20ZvPqMfiCyNhkcmaN9sEnifF31epZSjpDw4XM4ex3HFhhITttXlCrossDVYB8z00k6XsFruCkdwFRmBjb2PdrdZFAkGQeS/8xTarYWgiflkfGocGqVm6EUq1gh8QLE173Jzo15LOSuzuSS90BTMvcsqzzRrIEe+9jwF9/ehLyQ5yYxNImFGQQ2jkW0KiZsjyEbQAGry7B1/AiSUBaGYHYzcB3bFgXnzC3ecPwL+ENZ+azpTd143WneuVMUJrWNp3S+9ZRzboRzcYV6Ax3nOLPS7LTc+e9j9s4CrPvc1L6pG23AzNByDWst0JrqhN37yp67EVVrFQfUDWcKgZyyA/M82q1TVScx+I4A+g9ASC+PdQ3+M5+EOtEfClkgYJFqzXqwPKYwBv4CBKxikS2Vt8x40271kjmVYyGQOIRTo1UKn6u07TS5hxdEgEI+WdukG52813USiD8bQFbN0r4VhjFSqKMAJoItjqvafBNBl+OXYQ1p1zRCXP7wHS4/F7mvrK98gSuIsBgfL+/q9rExXaxIZJNSbs1HGAXR1TxYSvyKZvLa',
+ version: '0.3',
+ creationDate: 'Tue May 05 01:28:36 PDT 2009',
+ updateDate: 'Tue May 05 01:28:36 PDT 2009',
+ accessDate: 'Tue May 05 01:28:36 PDT 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'test_test_offline_copy_data_withExtraVersion': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ '9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8': {
+ s: '55a27b18e8fdf1fb5e5bcf859cfa50fcbc69c9a41f04e371606a86411a98f460',
+ v: '983a6c79e7d5d490c3f13645c49760180fca05cc677914bf60fee009ead5a65d',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"75b61c51726a35d1c12ac553947ff9e974d1a29339f87fbeee0d831b59938a53":"0"},"data":"YjlNzXUO9m0EXdi5fUguA6RjR5jc2mwuHkpMsHAheExR2zpoV6OJx8tBTdUGqDBAlbIn6xUx2TT+dzgjic/XubgKNsv6JpTvnfiW6ZMWiebKXVigoZw7L5EvmcHjVLI8aoIhVEj4ADwkh9qHm0Kt1zFGQPwwJfo="},"directLogins":{"index":{},"data":"4W5csD8DxlxeXVRROk7wVbXi"},"preferences":{"data":"/DjOoFcgquxUbW5ye2LrpsKM"},"oneTimePasswords":{"data":"DEqkd74lLAGtG4YKRPniBNBU"},"version":"0.1"}',
+ statistics: 'EkRr9wEXi/WOlZfCXphn9kfx',
+ userDetailsVersion: '0.3',
+ records: {
+ '75b61c51726a35d1c12ac553947ff9e974d1a29339f87fbeee0d831b59938a53': {
+ data: '/gtNfde5l2J9eeg+rlBHZtqO4RDaWNQwaMEluOVowKdUlGAYjo9FU0NwKsA9CM3ST4sTYl0mylP3C/AGybO8/9sTCkEn20wi0slharA61Rk8uB2lNjCICZB4l3ZGvD4AHKucu8YQzxpWop5dTN8f4us5eJ2VjvJPLqUzSKZL4g+6MiKbjQ==',
+ version: '0.3',
+ creationDate: 'Tue May 05 18:47:53 CEST 2009',
+ updateDate: 'Tue May 05 18:48:59 CEST 2009',
+ accessDate: 'Tue May 05 18:48:59 CEST 2009',
+ currentVersion: '2c913151cec0422dfa51c5bccbca6ad09d8e195bff144d2b5f7a2da3bf55c11b',
+ versions: {
+ '0311012a897262b85b60a316f086f0576caa3c11a34779c02ad9e60232c79564': {
+ header: '####',
+ data: 'MZGx+tQAecxJNl6UbWHIM8g416Qa8DfWtGo7f2vLkPBbhsr20xnZ233oPqIGceG5/6WMssQd9c8U81urISK+4Ar8zHGUxTdIYLZaDq33Q0uF5vO7OsaBcjL7m+tX7zB+e/eu0ABbqvt+saMsZKKSdIZv2KNbAg5VTiL7GjWuowM23tWgiUBgX3eO5fnUUQWVkBygk0qy2O45oNfb1XcbsGMCfS4YPF9GB/wGSQKG8keMoy1ZWZh4nG+Pdx2ymIrYKLv8T+i7jtWEbyhvEglb7TadCMBBF0pnkYvG3F29skWooZC92dy5213o+3/uSKi0od5tAbvSYZHjT5hDulUtmjRFGq4ZRERLqvrZs9Sg8G2mjtf8Ta99Hob8WLxyGF9x7s1LcLPERtdsP9qCD+I0WtwrDiodl/sPQ/5s3G2S+M/YejKXBvG3AWwoO1gkdhec3+d3meFNvCr0hKNzotrHmDLC4tGyZIaAcBmPQ8xSD5KmNJJFU+V0QIdiEYKnPjo95oSmKyK1UtIoPrWCahfYSKXh+aW53XnzY4JKHRER9vWwdJzz',
+ version: '0.3',
+ creationDate: 'Tue May 05 18:47:53 CEST 2009',
+ updateDate: 'Tue May 05 18:47:53 CEST 2009',
+ accessDate: 'Tue May 05 18:47:53 CEST 2009'
+ },
+ '214d184d75418af71d18f412bc6bb153fd6435a4a675af6bf2a744ecbd7a53b7': {
+ header: '####',
+ data: 'Y38v4jhKwcsW8LDTigIhtdLJ2zgv+1rSutqyu0AilBQeSTe4D0rnapZZTW/mNnD5IGpWKFoEl8+WGj1zvGzleNdkOa08nWJEYDNe2h0+FjBSHBUAgH5fraezomRWzJ/Z5HHFiZuFfpjt2BHd0Y3Not6AuL3aBgjjkEai90r2o59Xr70maUwo1UqmtVg3gvX067MC3hlqhNIp390J8LFiSj8Z4US9x/WzVR5Xx069+0PFMBwipq9WJPrcfTPwvP6xVa+J8BCJk3HtboRutq1ZhhHpibm+TY3Xl3gFTTCHWDZCSJ4Rm1dWkyqpx51u/AVg2TC+ljFLKv7hq3euVZNMLNMY2BqoCkcb+w6dFLDs3WfPAW0aQN2P++GFa/eVpN90YxAeXufjsXKaArTMjGWKiHqyU1iVVI8N1QEiFYjjBV1GvkJxog5PjtAzJF++qwHDIa+gJ+NnOfenVF0wIRMCEnpGyvbg3SkUoenKFoHO0IcSP2CW2RWV/GAmiEZEuVD393mKi5B6fpjdO9JVPNyz0i0kW++dtzInwPnglhOAY1ywT0ExOBLIEr8=',
+ version: '0.3',
+ previousVersion: '0311012a897262b85b60a316f086f0576caa3c11a34779c02ad9e60232c79564',
+ previousVersionKey: 'f45/Sx3jMC8CgdT8cjfcC4ApA8xMXABFO48jiTh5VjJfTlVqw3NnHRO2KDBIhy0znPvP2AKlpKQHruW8LQno7YLyhEIXh4ChjMUjJsFFwB/LUg==',
+ creationDate: 'Tue May 05 18:48:11 CEST 2009',
+ updateDate: 'Tue May 05 18:48:11 CEST 2009',
+ accessDate: 'Tue May 05 18:48:11 CEST 2009'
+ },
+ '2c913151cec0422dfa51c5bccbca6ad09d8e195bff144d2b5f7a2da3bf55c11b': {
+ header: '####',
+ data: 'tkiW41JHOfbYOt2KHx1HtDJEzxbfVS1Y2HJQqdQZ73zhvxnkWLw/X6FMiBexLeoKXO1H9NIWS884MzEO782vg8QRxTizg66Yye+q1Hox+QsaEoaD4UQ54XV1duTOB/XS5P0P9DFvtIz9msEu8GJrvizAdxu/7FG2b5XfENDkwqIzydI7JMfGC0JzDnfGvYkWqoL8jx3Joxa7TNqN4he4v771Ho1ZoUv3Pp7ZGwBU+btl6Q9mcycSf5KXdTw+6nDjfQh8qyts/u7O5xPFh2Yn8zS48x95I4SA4yFKtERU3pLAxIkcZWVb17xT8xlbPESreZ0RyYSR0CgW0wPMxkLHH1uqWycTa7yIxUhyn+JK9jCl4eDa/KUSGbN1yb6pOyjGuev1vHEZv3bOmO52RVVIdMHTe3LezCKY8xpDqtQKSfAvFg1TmabugXePXB+KvPbDDWI5otDEIwLYhDFcSn2FyqUEATSzeU2o1uXO+ffbU3QBrwr27tsreughWSP7905FQbEEshsRUc2Xt92WhTnVM6W74Y0bMLWjTrXbu+hNsjtFYYN6gtezcltnB58MVw==',
+ version: '0.3',
+ previousVersion: '214d184d75418af71d18f412bc6bb153fd6435a4a675af6bf2a744ecbd7a53b7',
+ previousVersionKey: 'XtJ8Ub99GXIkxErIPr0HaIrRqlAO0Naa/tPwUA51K2D5R6R3CR6QbHd3GpkCnu+y+bcEIRYrQqgabi3LROYT+1SZ9B9FctX6FyaTjYEazFdCvg==',
+ creationDate: 'Tue May 05 18:48:59 CEST 2009',
+ updateDate: 'Tue May 05 18:48:59 CEST 2009',
+ accessDate: 'Tue May 05 18:48:59 CEST 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': ""
+}
diff --git a/frontend/gamma/tests/tests/Components/CardDialogNew/cardDialogNew_test.js b/frontend/gamma/tests/tests/Components/CardDialogNew/cardDialogNew_test.js
new file mode 100644
index 0000000..e2b21bc
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/CardDialogNew/cardDialogNew_test.js
@@ -0,0 +1,127 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.Tests.CardDialogNew');
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+Clipperz.PM.Strings.Languages.initSetup();
+
+Clipperz.Tests.CardDialogNew.Tester = function(args) {
+ args = args || {};
+
+ Clipperz.Tests.CardDialogNew.Tester.superclass.constructor.call(this, args);
+ this._user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.Tests.CardDialogNew.Tester, Object, {
+
+ 'toString': function() {
+ return "Clipperz.Tests.CardDialogNew.Tester";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'user': function () {
+ return this._user;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'run': function () {
+ var deferredResult;
+ var proxy;
+ var cardDialogController;
+ var cardDialogComponent;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+
+ deferredResult = new Clipperz.Async.Deferred("cardDialogNew_test.init", {trace:false});
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(this.user(), 'login');
+// deferredResult.addMethod(this.user(), 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+ deferredResult.addMethod(this.user(), 'createNewRecord');
+ deferredResult.addCallback(MochiKit.Base.bind(function (aRecord) {
+ cardDialogController = new Clipperz.PM.UI.Web.Controllers.CardDialogController({record:aRecord, delegate:this});
+ cardDialogController.run();
+ }, this));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'saveChanges': function () {
+ return this.user().saveChanges();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hasPendingChanges': function () {
+ return this.user().hasPendingChanges();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'revertChanges': function () {
+ return this.user().revertChanges();
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+init = function () {
+ var tester;
+
+ tester = new Clipperz.Tests.CardDialogNew.Tester();
+ tester.run();
+};
+
+MochiKit.DOM.addLoadEvent(init);
diff --git a/frontend/gamma/tests/tests/Components/CardDialogNew/index.html b/frontend/gamma/tests/tests/Components/CardDialogNew/index.html
new file mode 100644
index 0000000..1e0061a
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/CardDialogNew/index.html
@@ -0,0 +1,117 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Card Dialog NEW - test</title>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/DOM.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Style.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Visual.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Set.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Toll.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
+ <!-- script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Field.js'></script -->
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/BaseComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/Button.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ComponentSlot.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ProgressBar.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TabPanelComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/Tooltip.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TranslatorWidget.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/ProgressBarController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/TabPanelController.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/CardDialogController.js'></script>
+
+ <script type='text/javascript' src='./User.data.js'></script>
+ <script type='text/javascript' src='./cardDialogNew_test.js'></script>
+<script>
+ Clipperz_IEisBroken = false;
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+</script><![endif]-->
+
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/clipperz.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/compact.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/ytheme-clipperz.css" />
+
+</head>
+<body>
+
+<div id="tableWrapper"></div>
+
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Components/FullApp/README.txt b/frontend/gamma/tests/tests/Components/FullApp/README.txt
new file mode 100644
index 0000000..476aa3a
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/FullApp/README.txt
@@ -0,0 +1 @@
+ln -s ../../../../../context/images . \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Components/FullApp/User.data.js b/frontend/gamma/tests/tests/Components/FullApp/User.data.js
new file mode 100644
index 0000000..b76ccad
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/FullApp/User.data.js
@@ -0,0 +1,1044 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+testData = {
+
+ //-------------------------------------------------------------------------
+
+ 'testData': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+
+ /* tt/tt - empty, just created, account */
+ 'afaadd70f647886043b9196c861dc04f5605baeab3812ea23707fcba08c4a54f': {
+ s: 'df781ec363a380a0bb171d7d4c226248259272a964f04fa2340c77ff84bbc594',
+ v: 'eca214d990ec971a61cd9c5082e62c2d241f8e1ec805a2c26b1d31612747bfb0',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{},"data":"q/wNeY/xf7Sujn5CIxEYPRSF"},"directLogins":{"index":{},"data":"qcVwiiyOYeDHFZq5T06iF1Wp"},"preferences":{"data":"7ONKfKQk9GYGnlRxFgTgAd4J"},"oneTimePasswords":{"data":"GD66ZNSIqkRl1UxhwyrsSm5r"},"version":"0.1"}',
+ statistics: 'tfQF+BrjAQUWyiXWOMkWApmq',
+ userDetailsVersion: '0.3',
+ records: {
+
+ }
+ },
+
+ /* tt/tt - account with "wrong" direct login */
+/* 'afaadd70f647886043b9196c861dc04f5605baeab3812ea23707fcba08c4a54f': {
+ s: 'df781ec363a380a0bb171d7d4c226248259272a964f04fa2340c77ff84bbc594',
+ v: 'eca214d990ec971a61cd9c5082e62c2d241f8e1ec805a2c26b1d31612747bfb0',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"8bcad18cc9613d794ca052c02e91198f7d5b6e1b7d595f21b21ea53a72e56aab":"1"},"data":"/+RHG+JLrFhZLYga2H9hsPyugT5bbiPwmNgY/RqE2g90FXfsCOvJ6TnfHX6ufeVfJ5+jUq/mRhWMlKdIqROSBLRL5EbL7i881EyKMNE24zpzUWm9zN6HcATPO2iNvDjsZjv2dEP9QWtAabw4Hc7UB+39WQ=="},"directLogins":{"index":{"dd9c1f84d06d67fe1ca5826b52bf46e56407e7f9d87fb7b7b927831920955338":1},"data":"ZF6BZYAVIJi3xrCPs6XWHwZDveEonG/5WJVKwIXbCGa5fr1myopvpqYbWI09tPCCktlMKP/X/SiIyBxlq7Z953VpOHWx0AYqTpRnw8PfJ+0BJDEblBFCZ8ZZfkZXcfYmNoY7"},"preferences":{"data":"IpjYNIHTXtE/pZvR8TjotEnR"},"oneTimePasswords":{"data":"1ibPl0R6S/LGBFFyH9pio1Oo"},"version":"0.1"}',
+ statistics: 'XhiWkdDyHzuviv5bdxOY/2Q5',
+ userDetailsVersion: '0.3',
+ records: {
+ '8bcad18cc9613d794ca052c02e91198f7d5b6e1b7d595f21b21ea53a72e56aab': {
+ data: '93QXl+c+JmQo4WTl4rYLYb/oHehjntAroteeHd6HqrUiXYoi+02GYrYcKfvE5wgMWvOwvQ4kVdUv5ksa3gJaUzhrpY5GLM3EV3agEkQ6yuKwHgfmAQvES1c6tcw15lNTzGiZ7PHhBrW5I5H6Le0Mf10uW1DOyu6gFl+W5OarbBBGyQmRmASy+CW2l3/lY5pOFxUq3qlkwW/o4KrSiwKOFh3HDvxOQKwovm0v3puLu+NsuL5rz5blUIZpj+CsOmZUhtU5FC5s6iO2L1uj3w8+Yxu279p249H1bv1zxo1zSBpP507uuRH8dKOLsu7JI6PO+UC8PLqVhPU7fHhDhNleurE7AsUo6eHocG0DhxCAm3xeobm1K2iPd0iRprcuRXmwa8HWRDJHTItbQr9D+cnQTT7/DwneRdQzpMaVZHZcKqtAzz07jboy98plrigu03tV2MkXt2veIMLBofxxHqgZ0NJhcfrVta4FlJsrd1vO9RUkoHl+qPJqQZIVGZzoT0rdHS/nLd614EHJSfRYIl+drUEUchIidbRnMzvPTBo2s6bVfUPcQksVop4E85wMo15ah2BHzUe4vjkmM+Ki8ecUVH8jRR5fmZhCGpBFML5U7o+rERYABFuwwRC9FfCXMtmClHc2LypP+iu+lI/VycdHg/m8skQVeCDBv892vqehUs1CpeVAxMtYOJcFtm6roQNPxJe1EI/j4PAi3SEYPCFev1F7u1g4bw4cG5jCGJx6U3qTTYMX5A06dHf4iSSOUeCsrP5U+VJY0KLhU3E66DzOxNIrIyYN6iOJxKCbhH7ILfGdWAV3MlZZOpVoSIqiR7oZo2PwovtudF5tOy9lhz7SEFYLvuQy8r4mqFC7qMVnXJRrBPDZcQDTdXLG33YV6dWX17QpGrpyvPhX5/UDv8E7zc8PdO1YfJmzL1rpArlIXF1EOsLa6BqjQp5bkIlHKugQMjnn3tf4sYK0OhPskbKidfNm59NedQODEoUr5NGwmjSAqTCokt1D7q0K3vMK',
+ version: '0.3',
+ creationDate: 'Wed Jan 20 16:53:47 CET 2010',
+ updateDate: 'Wed Jan 20 16:53:47 CET 2010',
+ accessDate: 'Wed Jan 20 16:53:47 CET 2010',
+ currentVersion: '79047c5ca148b2915014c44d75874cfedf3caee20cd9f97a87ba2a291ccec741',
+ versions: {
+ '79047c5ca148b2915014c44d75874cfedf3caee20cd9f97a87ba2a291ccec741': {
+ header: '####',
+ data: 'mqqGPhRw/397NUZH6B8XJW1y5rMDZD6u7WUuEU77zcNXYEHFNQq319u0G/qD5E63kbI/kHsNXZFFKmNGw5IxDiteWSfYG4RiiapsUxe3ZgsFDDBHFrD5NSrMdIzLFSoNel+1mZUps9AcmkelhkXSCqRiGPyiPIKq7wKXF+Ql6j1AsnCMOCJLlJdTZPqIUUaTYD4z/tvTOS1xRdUiaRjw7cCh2yMms1c5V//3J0xbO10kEC8xvA8nhJnQqsMh2P4h6QFzAZtXYKMehJXwQ5ap7W327EMnCdXw2N0pv9Lr5S9khN/9oTMy2tMIGtN+UZ684zTiAP+479xES6OvmVL04nGyCarIqMNu7oclR75Qv2U14CNRA3gIaMPv',
+ version: '0.3',
+ creationDate: 'Wed Jan 20 16:53:47 CET 2010',
+ updateDate: 'Wed Jan 20 16:53:47 CET 2010',
+ accessDate: 'Wed Jan 20 16:53:47 CET 2010'
+ }
+ }
+ }
+ }
+ },
+*/
+ /* tt/tt with "fixed" direct login */
+/* 'afaadd70f647886043b9196c861dc04f5605baeab3812ea23707fcba08c4a54f': {
+ s: 'df781ec363a380a0bb171d7d4c226248259272a964f04fa2340c77ff84bbc594',
+ v: 'eca214d990ec971a61cd9c5082e62c2d241f8e1ec805a2c26b1d31612747bfb0',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"8bcad18cc9613d794ca052c02e91198f7d5b6e1b7d595f21b21ea53a72e56aab":"0"},"data":"K6sV3xYDTHn1PDHmbVhG3PogarwMtHCliSEGaJ5eev/RQv7MW9TCP5efsjATRT4eheX7JkXAoLo+sgMVr2fTyu7f7K0IEYp3mCi27T/TmtTM3b8FoaVfmXWEjN0FGx7N6gK6+lZxhFueRxsOha1+fTLDBg=="},"directLogins":{"index":{"dd9c1f84d06d67fe1ca5826b52bf46e56407e7f9d87fb7b7b927831920955338":"0"},"data":"9aUwb/5nIlAOPKz62xTwylK0dilpWVVEJBag5+LydmBwWxTmlfcB+OO6jGnMgDrjif3LVhWFjfKVSoZs5hSpPvhsSDPaLf5vQhF4igRaQpWI9QhBdfmv3QvZ57ei/gfcal346F4="},"preferences":{"data":"IpjYNIHTXtE/pZvR8TjotEnR"},"oneTimePasswords":{"data":"1ibPl0R6S/LGBFFyH9pio1Oo"},"version":"0.1"}',
+ statistics: 'GHHkZjW0QLdUq6CPnVuDLh86',
+ userDetailsVersion: '0.3',
+ records: {
+ '8bcad18cc9613d794ca052c02e91198f7d5b6e1b7d595f21b21ea53a72e56aab': {
+ data: 'SOcANZTLo4dsjpsPghF2+TndV9+1uYhGjup3StEa1kiFHHzDK6kDZkKwjhP0mxFgixlQHZBnvgsW/xdHGXdmj1RHtaNdHlte7W1Wq5MHbH4XE9bJzQAvQmop8OETgGz7Khp4BbUMVLIXhxoJmP3rMx7ulQHds+WN+S5u+iB73y5nkJwfOXrXDjwwlL1vER92XHE1VJZAjkYRB/xes6SLcITaG9LYVSGSVAhtLIzkmrAvPHPIpZSOI4NQnAMEVPllwtMlWQBEeerN7PIKImyaUd9zPzP+v0S1V+kUyioizScsDdVuaNKa+yqwFKvYYy61nobv3Mg+Fo3EGqY7GOiO7AklRTreZoOkZAdogQlA1DZuIBNSbpcMvm5MoP+PsU3HFSb/Vioo+QEcgTWqVyDNuFGZpkOI2iIBuQCwLmsCwB1JaE/1cCd1fEpOWyiFep0vxwi0ZrtRZQowQd2Ua3UIoaG5u5WoYEMYoH7FFi6Djda4Rf4gxed8rPLE+cNTI/p67OKlbAfr8iz3YZknaH+CXp9pPr7V7xXBCWNxo5DnFPeeqqrxjTAbkeg/Rp2hJeN7/zi0TSWKDUTXfkuUNyewHOHb7M+MIvC1F1CtmqLuU3h8RDINYgPtZTtTk68YBmOG88xYTtClr4kKxmp1scrV3nJ7af+IGoVKZpRAwBJYT3HV33vzO9W35zl14eZ0vVuNoHMNsh9uDxjCwRyPtQzVpQuTIYnHHoO5R17XyIfe599BOSBAGimciprURN3llC2H8YhRtMilQRYvEDVsC+mVZmGAeEdQ5o/AehnpBuVKErRBzotWe6bNMkIQqWfwCLQFBb6ap1gT5hbacrJM4AlaPgOdQsyX9npd3yN/tzjVA1IqWLnoaEXq9EfWXhBuT+juMfSQ2Y8bPbpBKZmWWL06T2fVkaZJN0VFtBXGi0XRFJngPskApLunZOfBYq831jSi8/Z937QVTQKWwOz6rLE8covE3mxJ53gDVcOlvqD9s/NGXbmnt2GnlWhVKpzhTIJ812Hr050/2AI9ZmWnv+ypSqeQ3l0BFh4D+xfk5NRv+dKbxANheZnfZMhR6u8F+jX/W3hUtNCIMQc2vLSQ',
+ version: '0.3',
+ creationDate: 'Wed Jan 20 16:53:47 CET 2010',
+ updateDate: 'Wed Jan 20 16:54:56 CET 2010',
+ accessDate: 'Wed Jan 20 16:54:56 CET 2010',
+ currentVersion: 'c0a8f723bf44e0aae1d69f6f85f8e1b747dfbe5ca0d78c5ebda16b32cf17e16d',
+ versions: {
+ '79047c5ca148b2915014c44d75874cfedf3caee20cd9f97a87ba2a291ccec741': {
+ header: '####',
+ data: 'mqqGPhRw/397NUZH6B8XJW1y5rMDZD6u7WUuEU77zcNXYEHFNQq319u0G/qD5E63kbI/kHsNXZFFKmNGw5IxDiteWSfYG4RiiapsUxe3ZgsFDDBHFrD5NSrMdIzLFSoNel+1mZUps9AcmkelhkXSCqRiGPyiPIKq7wKXF+Ql6j1AsnCMOCJLlJdTZPqIUUaTYD4z/tvTOS1xRdUiaRjw7cCh2yMms1c5V//3J0xbO10kEC8xvA8nhJnQqsMh2P4h6QFzAZtXYKMehJXwQ5ap7W327EMnCdXw2N0pv9Lr5S9khN/9oTMy2tMIGtN+UZ684zTiAP+479xES6OvmVL04nGyCarIqMNu7oclR75Qv2U14CNRA3gIaMPv',
+ version: '0.3',
+ creationDate: 'Wed Jan 20 16:53:47 CET 2010',
+ updateDate: 'Wed Jan 20 16:53:47 CET 2010',
+ accessDate: 'Wed Jan 20 16:54:26 CET 2010'
+ },
+ 'c0a8f723bf44e0aae1d69f6f85f8e1b747dfbe5ca0d78c5ebda16b32cf17e16d': {
+ header: '####',
+ data: 'ky36e85TGmGQ+O9FXAhHRXEz5eBQogwuyAEgjpsHaSUM22TowYEw/NkWMg4oT4M2DGIYoTyXatvea859F3kMWM5hUe16PaG9J8HzQcEnaTRmi5oe0cMJAlg6pl7ypLt9kUiqDoMIM4lM/eKO8E/bRZWnU1EsxjehYjQQUoeoSyyTAOhHlLfXS99TzCXFrJjO5rAgaJ7iAjNOcQ8Bm6ECau5ao9AVd5hqgMDEmLJhRwygcGHSTek3i3I4o0jIImcqpfNko/4SbEC4p7+V5Rggr1IG5DkeYfKuyqxgulJbtdkcWxAqPReKXUOkmSGlRTje8rjTTLx1Jv7QCc0hLDYc5pLd8j/G7mOwLG1nLTMeNekljKNCTLAhQ+ccDDq35Jv1cNhmA/icmRlMkztbsR7tzqFs+drQ',
+ version: '0.3',
+ previousVersion: '79047c5ca148b2915014c44d75874cfedf3caee20cd9f97a87ba2a291ccec741',
+ previousVersionKey: 'aLMGf0ucGPaKLVv+AunJaZWDg+gGncnBu2Bf7QseH3ma/jcMOZCNHNd44mNPKfZPyoXYZi6/ToxkJh6Nu8PmOL/SsHTlf8FBZxrNm1i7ZS2b3A==',
+ creationDate: 'Wed Jan 20 16:54:56 CET 2010',
+ updateDate: 'Wed Jan 20 16:54:56 CET 2010',
+ accessDate: 'Wed Jan 20 16:54:56 CET 2010'
+ }
+ }
+ }
+ }
+ },
+*/
+
+ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ /* joe/clipperz*/
+ 'f527cdd90d0d47f8524b4e165398ad1455eba515d04abd101d1e93b3c6ae0674': {
+ s: '186f0c40bf73f2af236eaa6c429df225efa933050c9aae65240e93b7b362e3ee',
+ v: 'ac61a6e325ecf329926a86084f591d8852d0ad3e4a6080f2adc901b82395ecaf',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5":"0","13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551":"1","062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80":"2","ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c":"3","507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a":"4","d5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d":"5","de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4":"6","d620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045":"7","f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732":"8","36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113":"9","fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6":"10","6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18":"11","9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291":"12","6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a":"13","6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728":"14","8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39":"15","084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d":"16","c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065":"17","6dadcd7ab23ece757d6990ce237bdebb68b2df0281c78cc1483d913318112162":"18"},"data":"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"},"directLogins":{"index":{"61e87fdc4f1d9112e3b30c1f6812d095dcdb24f014c83319091eb6c9899ec348":"0","989593d4c48929f0c8f1581aa96969c622807e99619ed4732026e967530a68ad":"1","9f7979368fa29f66c44bd97ecaf6c545abc800b1c7bb21b7655a68e1514c3906":"2","dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496":"3","aa18149164302d5dbe7e2d3724565b9550e00887b49978559783b2e38c625584":"4","1f9bfd677b531a03168d3f8bd8afabb5357244a7bc355dff50bd6c0a072114a6":"5","a48e38845713462ecc9f827149eeaae87da882031f98ef8ebbf9ee9537b63468":"6","6f7bbc4e42ea462b5246e6f51c3f86056bec50601ce2de6067c8c1d26f21c07f":"7","2df54059e78f5771f23bd285cce19595b38331b73d67020424d9a1b2257db09c":"8","065cd0c270e5e8ce50e4ea8e3828dccdae18c01ab030813d756a87d03fe68784":"9","ddbc8d01300a4f10631cbde09e1246332eade3a877a2205209f9eb9e5bc9da0b":"10","9b7a30e667afc9f76ba77600658b2c13bff52432d444261d39bf3d069a160afe":"11","9fd2929cde3d32d9cbc5f1d787f2f64729a5e12a14410556b31c0c099762c46a":"12","f695fc36ac56bead80c0d20a88e01e382819c18dc268f1679551b7c83db7cb14":"13","f22dc41ffabef4b3bc8f7af804fec975bd50718098322a673cbe4aaff9464ae1":"14","03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c":"15","a7b32e72502804bf2946a2a8856139cbbb759c5777e6b3e673db1fdf7e3bd06e":"16","cb9ae0bba1957075ccdbfd3b3481704d62087687a2ac7c411a4f07d444bde0f7":"17","7e1d069b7fa57c03bd7bf48807520feb953157834503aaff8c9d493f37dea69d":"18","24404059cabc63b2dbff0f42ba57183108b8189ef53ab62fa25141a1caea824b":"19","6e218e5d129105c20ac499307b260eb76bb2e753f6c319e17efdb848675c5fa2":"20","75f306bd520b483e86a1b436d94159020197df0155ab9058fb86586925223dc7":"21"},"data":"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"},"preferences":{"data":"fwQt+Wxhev563xviKvItHr3k5MC7ciMmEayJZ7HfwTcWPqaF5Syf1czPlMQiDQzEgWWs4BmQqB0QCDDMi3VyGCrSzAtIMR4afVdRyQ=="},"oneTimePasswords":{"data":"8WhmNFYrgxqzrJwMx+goddfLb2wlXnREHH77BKpL8h4ZalAwNOAt0yoBMECtlnNcve8ufjGAXL80dgUgtqsTn8fpx7+WDL5fNynv5ve9mJq/qgqctQO+pvnLuvs4867NXYInHr84f+t8f0lyfYRQdpDJfem9ECrn5MrpQ1rvwB2PVKcU0f+VPGhu673QeDbqzF+95JfxF9Tnv1PAePL1EGahUYuxTED4y4fcVmsHKl9yZXcsuheM7ecik93cqOVSlnuN+s5c2KWqjgDdLzUjG2dDHcuY97v7JT7Pns4ad5C9i2dYLtNrSHG7QLw6RBS/EnBwGzK+sWFQFCU8u0qSeFb0eGRjvVb9SfIXSeTqAJK3JC+OLAVGiey34jFckykeQjy5nPjhSpqWWhZdpezvZHno3YCXSGkLqbazL6xtesNaZZAbHBKdrwIOuTdhMwArfX/na/gavciFM0zwGb13w6JX3Ar3iTqhnBR20zmv5vcZwIOjf36LSfSNnjT4sWE1Az+FQPmMPQi4ODHfLSJbwYQhwqM5Wq2yXHpKDf/e2RpBZ5JsUkDEyoGmglcLF+pXwk4Mn9LuNOztxXCRWaZ3M/5uVk4xXOqJax1IlnA4nlu+3N0orF5ipRwd7BfmQekiYyp69m9SJA=="},"version":"0.1"}',
+ statistics: 's6W+Nlk1/14i/BN4u7qN8oTc',
+ userDetailsVersion: '0.3',
+ records: {
+ '062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80': {
+ data: '7sgxSQlqR+wh3g06M2+sWp7raQxjjQ9jLIz2OcEB7SckuQcXNrhMlDCbL6ncSljtzgqhioWrOB409kIG8lc7h6ekghOE/Mhi7rVwAiRfNGB7r3mYxpEXRe96O2RG7E+NcSp8ezl+5gJ9D0o1abXPeFQYGcr95hUioCfyY+xrxY8TJVwdb9nHkYvBdKV7rCl1dTxgsKWK3nlo1T7e5uyiz5YUAE6BrCtTFAqtprLI/xOpRti9C+llohS7D6s8hkCBPZfp3chKFDrgpsCBFLhXN8jrBKSjHi1PJdRQzpJsgrxyeBj0dZx3gTsYOXqrYgdIzFUo7K1Tqb30yNprBiDMr7j0YYXiSvEb7OuOIP+HTXGN+yt09bk9LggyY6Fh0e+tenjQQ3soySN/XznOBpEjXbzXoz6fR1MXVnE9GgaX99LVNqwWfq2rIBdSE/FfspRiWP3BY5jIrEkNeRclS05U1zw3K3wxOL+cB9r2IynSXnK8QcrDNNRZ0W3PhsSFfByUXuviLSEOPuJa1mYP29L9Lj/WyHL1Gyl8xLbt2H41S6+wvIleKMuc7teH6wPXbnYphvbwBowoI6HZTEFkz3dQKhhY6VF/81iCXsuaz6BjyrzFX6SkQ4S3lN1tv4opQMJFvnmHb6EkXqVWfeIXzJIJO+owL4vDOf4okpAD+HPjjlVXhq6fvyM5UBIK9+tzJW78X/zifrQOfWRIhwjVsfUdZWmZ/S35vnHWNuXkM8GBYrDysqxanDtah3U8XLAiIhFtBOzpzr6qGaNDOKKgG3K8QXT4bYHOq1rQVUwzQuKhlCyStrRMQrC5Ry251xmLy6dKfppRarVeGDtzB/30BbtFNdZmzMNG2g+Jj5tFCrEtCMvMiQEWZHMU3tGMFxDef/KKdv1fFTJC16jmaUiCHUZmNjB3EO9R6xPVcMlAVKf57n3efrpRk/GTmm9JhAFkuF/wsveH4JjPpDUdkHYFu5tHbb30sbga3ufBAXbQL4ck10S24akU/cKraFGLvuKGaR2U0i6ih911TBSf3pAfZ3RFbBhVIl+6rSknC5+IXoBR7MRstBPW/xC9pQVjN5Qyn0g3aUjUSI+q4jcTuvMl32NtTJbWRMGhfkrpVzypZTyPnIh6XJkyBghlUARXw23MlbjiZxmY4ScDmcWZRZJWIknHlqjDKFDKNnwrfnEI9qWyMDno+jA/DEQz0mnpdZYEsoz1/qAmAeDt89vx',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:46:44 PDT 2007',
+ updateDate: 'Wed Mar 14 07:46:44 PDT 2007',
+ accessDate: 'Fri Jan 08 12:38:42 PST 2010',
+ currentVersion: '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3',
+ versions: {
+ '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3': {
+ header: '####',
+ data: 'GCNNIhDQjMJQZGVSf+95fPtU6eOnFWVhuGm86r8WZGVR2Gf2EjbG1OJ0ZIGpZ/AXgirCMpo5AFxJe0Bay8IYg+xmBqMFhwFxzAgJBYCIts+raSaNRipuY8dTEqDxAqD1cChcG8EhSoiFgQ0fG0I7nNEUDJi0pIt4/ygBcwvAhuAenEp9ZW+oQA0+YysPQRqkz3IieFaOoSEbe5/SqpUilV4q1gTVyzNXvrxzxx+rlvEyGFgFN+vgtUZ1NrwlPk4gVksTpylvv6CFaMGEWKhgMG6efo0rJckKosaJTu1pldJdnmMK4EKNMLOd+jZ6pEhEhYyadrA4+zYU5TlmZA6ASzTaps8piSwZodoi9qY0ch2StK4mAbzeEGe2HdfHuAU9Tyq3Ppk3+VfNdKgpQfYrQOiSlXbKzK636tzXTN/gyrfOTHjBrRl117ywibgSX63ayAYNfcLpKotC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:46:44 PDT 2007',
+ updateDate: 'Wed Mar 14 07:46:44 PDT 2007',
+ accessDate: 'Fri Jan 08 12:38:42 PST 2010'
+ }
+ }
+ },
+ '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d': {
+ data: 'fGzBu1On7e/6rAoSB1a4fq/CkS8Be/T8UP5cQ93asBTWndSYu2lW4DQ4SXQXSindIi3OnNx/f6SNv/extb7OrMLREF92wXI045ipPwy+DIICb+cQNMJ82Sh4cXaIcAWcyrm+MYri3qq9LBKbpwkILcebZidJ86lmKYHJozUezmfbMcwNCljHs/gYkHVzVcuw9L52Ugc6wC7sjsshh+UH6i4/2Frlrophtx+b1vervNd8eoYiKnedHVXVfW7UJcQoF27eHFgzwYnGvRW0KNXFFhqmPb61TSkIvNdCCvBKDP4SXrWvGgzU89wipvWdUPpQ+fCT6Mp3hPRrbJxwMunmjujZOzBld/HkjnXoiNfBb5akA280WvdyzWYATrjV1ZFx8yQY8G0+lRt/MxjKDc38w4y+Rf5WeRbXboJMvFatwooHUggk6qSRmZVvgOmFmNuDRnRYIFzqK3JclhJeVasnqhR6RiGSowc1Ffr1HhcZCMnXpQABGBkZcHD/zw6YjHRyh9Plw7XAm0xb16HMDtiwt7WLJpxLH/HP99j/A2hvMGWiUiFCaYv7AzyEPTmYbN32D1IsAEE/GC3FG0HypGTBolP8wpAfTRdlvWpJz8oRRdwuLV3Pgpu+kXh5sQyeZI6tnuMPQFmRDcMN1oo3E5V5V585nVMnKTFcXhBzD4UnoV+DQNkG/+iSPybQzz/EZmucEqGEYyjI3kl4MAX8UMEUxE4JO0fF8MzyBI13nxknowAceEammx1dGVaJCoIOdhadaPVPyOzXM1Vp1erVm5k4TsxSx1pll+GOm6hVoNHIuQLDueaMEpRxMhfwc8cDyXURqRGPTgTc0bint5xVjo10fnpX1gcdc/AWL6y3tXM80NW+uFJ4GI7VzyzfcMRzTiRaGi19z8MIx8PbIVGh2sw4FhgGujNsPrpuESvUVT+17M0+v8oEoABNlcizTMFs/sA1uqlPumFASltzmViAzClOsDuCh069hFLjdk/Ex5jy4vPYlwOT8Uq9DJC9ZWuZgiI1DrhWN/8QGAEGxxbvnSZPNCQ9kpD5p+iabinLLWOAirVNgKwIRJRyAu/uR9xKd7J9Wxq8q/ii+y5lGilbo2g24wbDwrkXYVhqp/4J0g+p8Wv1NBjCTSCqV39WEizUCRHo3ee9HnQnBJQDOyTBRuz2odTJtJ5tLYjWXZRdFzFSJrEq+Z1z3oq7LnhZy3YWaFXPeKmBCemMthtNt0nL',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 07:49:20 PDT 2008',
+ updateDate: 'Mon Oct 27 00:58:49 PDT 2008',
+ accessDate: 'Tue Jan 05 01:16:38 PST 2010',
+ currentVersion: '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac',
+ versions: {
+ '0ae362285f103722abbd046eee2b7d10aeae6a1d05cbaf2081392ce9df882bcf': {
+ header: '####',
+ data: 'sG6TUmPSEPFpiJ5YdtghWHmHbvUK63tZCZ+Q5iz2ALas//jN+lZCBhZcjEwPEJskBkK2R0MyAh14wWGh2bBHMjsokgTe+L+x+0c/Zi0epE/IC9gtOBhsTe/hZ2e2xOGF/SbzET3DAAYXvxduZ36f7SvvFnrkkKvpj8wGSdTFcBmzqMb9DL2bRyRCLGLMzE3F1a0q5CufCIRz2TgHm+Uw+kfvvwC7ig/F/5iLW90Ypz3vmEtMEFYFHZ9a8Oh0rsXGfevbMhFqALoywzihQEe/NiB8dwn7GEdYKSQ35rhvZh29ULWOZinqmg0ONe0HYaxx7DbKsVoue57S0CIUlgHLajzHfLfqQg2sFI0OT8TnHsGg0YZ6mM2EdKmEjJiER0cP',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 08:00:31 PDT 2008',
+ updateDate: 'Fri Oct 17 08:00:31 PDT 2008',
+ accessDate: 'Fri Oct 17 08:00:31 PDT 2008'
+ },
+ '10f45664bbd979a92f37886f1ecc6e52e49798b16dc997aecd37259ad9b2090e': {
+ header: '####',
+ data: 'RdKVaV/WWWchrCse3KtcXd47Bfm6IAwjqVUpaxoed3HeunI42AAm7xYYSjeK8edHpbNRJbhobBAX5OZtWIp/HmgkobKM8CIiWxrWz89FqyrbnPD7+fXdtgF2yTax/0sC1l0ibncdOuJKX6U829oPlXCpXIOjlomc4wEEAD/5V6FbORvdZ9IE/ME3LsG2y02cT2tIpx6+R6wC/PKXhZA2UDsTE6R2Op2BtIzpVORZLXsdyAp/4wvWQxq90i9cEpbsVQsMB10JVyNHNsRTFhIlHi9MVCaMxQvcrwRElMj/Y9x3RbsFzSGKqFLqdg7Fn/U+KYkpYtsgHv9hraPIb9lV5FH16+iItU/HBM6FGezIj1ZkoQ+dgjPfSjTZzgzDYwyb',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 07:49:20 PDT 2008',
+ updateDate: 'Fri Oct 17 07:49:20 PDT 2008',
+ accessDate: 'Fri Oct 17 07:54:23 PDT 2008'
+ },
+ '2fa7b67e569d5e268d2b70b3d4d3a960d7e437e1937bcb324b67d0b9441db8ba': {
+ header: '####',
+ data: 'dpnI2qKjk0+bfyKktw4ZCWf+rWZ12hO5bda39CwD29JH7KtdpLCLe2LoLd+KKF2wOdpDsoI2iTiwRgFpt77e7DoWJABxq/0aaRCVN9XpqZo08iHiYhJyNlIszO8CdEhX+M3AeZqzTnd6fs91VfIEWggvku2Z+jwr0CbclY6FnOcNnS+1fj+W79Z9XC383GOm2ujjfo3SX/fyNQSw8aX+7AgJIRGR9uHK7M1cVfsNNTbmDb/HDgLlYZ1Pqm/9poHpmS7G4HUoRM2/WjI0R6F48dy5s8vZRi11SCnlnj5oRykScJj6wh2DltbCyesiaTpAjP6MQjTXsZzKpaosaQcQClZw+w6hDD2cA54IaBIv2j5KAHyhxDh2ERdwbdnCsDKPz4+zP+fmKfW295d4OY0l1NCSdcY+75HWTmBWRAooZeDTo7AE8m5sRwxewE0Y8J2MLUYsrs7Rl4kbZCiRRHU7cs+us3fq2DVn2OLGEbkRrK3kA9swT9W8ABqINoA79+DmDaIr6TGxe5AlHkCAl5sYAN4g42UX1NKhl4fWI1Scj9O1Ixds/1UUvqzavld0mE2cR9yt6LntjE5sQSAaexvymAJbU5IIM5NTk7NlY7G3PEvAPjcUsL9SGw==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 08:00:13 PDT 2008',
+ updateDate: 'Fri Oct 17 08:00:13 PDT 2008',
+ accessDate: 'Fri Oct 17 08:00:13 PDT 2008'
+ },
+ '5a17723c34226d8cd663f91b11bfa14979e694e461818113ec8abf7194b46b6b': {
+ header: '####',
+ data: 'yRTvhkoY9zDRBwFYf0G5U8zhfS1XWIUfwes6ADNnFyOrHOr7JZvZZHSgkOPnsmN/f5ngcvFaIV9X3TNTmmPLzD/ewgGVMR+ofMLyOIMGhxUDzosSd1+HKqwDZWneZ6xNsci87W8UCfJgoEGrkAtAwktqyS04pcAas74XiRGBWNcv5mHZONwGPckYUnnaVG02Zf+qif6Pp7ugdvXrgncO5oi2AMSoR8GQxMP+tX53YzLwOpabA32PDT6o+aDPwMstJNQjWCXjeYLDIlb0GjL2zgjglX5CfdGw8vNT5hwGEK2D1FkvHkw79m++9sOWd5w9WdGgtS4mrTZP3JHWC1sPqvsIpq6PsrzRrbfCFH7C4X/ya5ciOIZTCNl4dEGAif94zgN74ueY5BF31PNFtaRaQ1waKkbsrU63MrbQbBar9b0hDZoser3BdgDGb1Ecc2GbJM1HbDITttmFDrzy/Ugh2kistHx7Dci8IGgfT7K94TntRFc5R6suEqYRrmOn57YJTZYrwSgbeTqAt/KOE+gL9LawiLJ0IdSC2RQnO3yu/aOEThHxpdLIKiVJoiEQXYVnq2UpnO79GNtplNnUe1hETQ/JT0o5X1bbENyInUsFjPuitAfChXofkAysIhDOHAdifc0Y+pxOHbQLkL65ZOsEDXWSlwMcduMNdQm4LVx26GLIV6yVsaDN+hGta2CxUuSvEIMM6T5xhaPfJ4K57LVw9MbOjRXpmFQz3QgEr8ZZdUxgE+Kj6CtmsjvzXtCQ3Bv/SccTLJSR/LQ8XRdIcPoOlDDy5jSQDF/8lxkgV1V7M3+SI1iWESPT8My5C+RH32F2MNZzthYq5hIFUB3wsM/AaQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 07:59:31 PDT 2008',
+ updateDate: 'Fri Oct 17 07:59:31 PDT 2008',
+ accessDate: 'Fri Oct 17 07:59:31 PDT 2008'
+ },
+ '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac': {
+ header: '####',
+ data: 'RgIWPbNN3sPkIPBE6lfvf9/EoDFLemTZe0Qh/1wZLrKxLRNzFpUk9+NmeGUp5f1hM3XjXw4cXRvP6GrWq69mz9zGja+1TA6RoW3dFMpSQkbONcrSD1mIjxV2zIvzA/Pangz0ZixbEeHCfwXLvgnevbTXXFjkti3kLHQlk2pJpM3zMl+rMJtcsefszuJ/0tE/bO7sBcFqcYgKAht2OyDQORBAGiW1kI9USKM5OOfJJIZDQ0gDhRgl2U92l3kIOO8hdnj32oRedwfKFmdSRkuMY7ykU0bMuVEVkLi/FWmhHxi66C2ovAztVtMd1IiyoNcHc4UH942GC4pT1A8YQpIHxBAJbrQVhpl9LfFkmJ7xUc6Xs5j0Nv8+z2JGCnJI/D4nDJqYW+iCYtRWu6vUmbg0vGfaYWQFGRZRk8zWfHzHXBvHU8p0QsIjYgCLKiUaU2SRRD2P7JCjeTUrm3I1OI593iPsEH9J2PHCM9OMQ8/Fsdgd7lWgH6P9jLdGUwtb1hGaq8mg3JGrHFXcrVkUEBfeR7xljeSHD7j4YahYrua9EeR8nvq6CNaOr406AWyHse9SXhaOxt8qXRLoELpyQPsaLgafUpsdLjJqHz7J76Rp77NSOtXGplKjAtU1xj+d/agaAKYCjvUJC8/APJI2890Pn7VSXr/TPc5biPEIopyVYEHFqaT4e5nZW1Ku1HXC9gwUwUI9rITG4GzIH1WMEm7oFLNUaSMrdK/UTdTJZ66ENE3B9v9cTUpR0NTkbI+iGKDnc8GHPRlr2ZJwN4KFTxi+o/kkEOBjvRHR55nRh2+dke75LS/fzHQZw5wlyqBv5ZeUZfRA7QHfkj9acR0fJSqqNX25AUzZQnRL3oVpOxFWCMU7QVf5VpnRm9OIOd/5F5EoY7Be4doM/UV9U40F3E6XPZQ8S0GKQzrDjc7jKyGPLNPLUWTmGB39mTNDHZQHh5Xv5Q==',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 00:58:49 PDT 2008',
+ updateDate: 'Mon Oct 27 00:58:49 PDT 2008',
+ accessDate: 'Tue Jan 05 01:16:38 PST 2010'
+ },
+ 'b57a2d2ffafa8029123362071c09709bb9192f06a17140440f0e41d22143148f': {
+ header: '####',
+ data: 'PQ53T2Vo2D8PoLI1qNX//jLaVZFTDTYk6geT9+4RoThTxvlJ+beDPnQzgYhd9iASaF9GQEEL8JxsBnNpEPa6JPOY4ndFLmDLyFDKXMprxq1UIbzFV6kFoYAk3uCCCa3UCDzdr1KXB2CiiF9HrilaA+xkm8krAvH8I5kZD+j23gByz5cAFvXg7A77KEURpjujURL65DW5M+ceIjo6OXaPW9VO03xhqGt/M47ayObpoEGJZn+X9C8s0SE5wOXHbn38YZlRI480OMvtDAxbEYUeQKMmzu6lO4Nw5hhOUjoPSLr/i3tmDx3nPcDwnSafx6jyA4y31eW6yazqTEOP5I5ArC5mUrF7mAAiFvbHIsMoF8PLj6MONlRIOZgbf9HzCpFdt8xBrX/TXp3LaSAj2XTWgSTFI2cgmU3qqPyibvIfUsB5cVHQCXi692JpC+B85axJ0FLyMl5w3vq0txlPkf6q+dadPYDaLHGZEmDjkWScA1GM5xPJHWFwqGE7ejgXKG0sMYsMKWYk+F2LEUmMHtEvSlpgJBntvcQ1ZjYQxeu4hg5txu1ykkif6fXgkXF6wn6qu+5caeJeNhWtAB4q7WVD47111woYMdkmX7AnDTXSAQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 07:57:17 PDT 2008',
+ updateDate: 'Fri Oct 17 07:57:17 PDT 2008',
+ accessDate: 'Fri Oct 17 07:57:17 PDT 2008'
+ },
+ 'b713e0a1e2664ac7bfa7ba887329ea023204d10298973e322983b82b222debf6': {
+ header: '####',
+ data: 'H3gIieYrH7Oy8LEWCZpl9vGp9qYdHNCoBNGijYqlcfXt+1JYvPj1abPp12xLNrDUHfaOZklU2Ip4tOf0CDNhgAan7LYyPqFoy9ss2f9/5RLcbjwiIwSduySIL322HTAwqlzlBt/qaJdHHPUrczmu0fb7fT+0dO4gCL/e/IjcHLefUUgNPAbpHG0Nv0+4lNwKZkIQM3tLRtfJyFBIgWKcMcP1XMic33kr24rwybR8Pb0CHZrOOvvUiGqyoED3ZTZf1twUDVNXO7MWCAC5dBc6/Mk/vSmbbGhppXAH02N0g8G5qzZfp3UVikls55VNhRYLHByVsgpkbIrKXyZnBPTwzm7qefpYAXDOgO+164L66/Art2FYGqZQRZLuh5r8oF38',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 07:58:00 PDT 2008',
+ updateDate: 'Fri Oct 17 07:58:00 PDT 2008',
+ accessDate: 'Fri Oct 17 07:58:00 PDT 2008'
+ },
+ 'c4cea1cd88a86b05f48a99896a37967c3456228283a0406331ca9f67c6f29f97': {
+ header: '####',
+ data: '1znWPwc9JwCe7iOFiUd2iGm4xJd+824B4VRqEtzCQkW46tg25RWfo7XagvK46USB7t6pC8WMLU0M/EC47KucsfpWUqHGbseoXT/8g8E8GoLnIsk9qFyJG7LGd1sUvqBgszLZwjWWG3t9zifmpW5nY9GialBYNmeSLS3bg5xDH+eCEilUUfDe7zGuVSuu/XkHacv/DYUst97e+6u44F7H8Kv8dTywJZpqbmveNPeWfCej2aBXdVV616J5lIRaj2uIYuQYG7blYJh9KZ7yLStdPndl6h65hIJpfWo0PM8nLJuo0lWNHz7misrutnmxJEjkwVIZ5YAmqp1Zz3VC8zw4IxkXrC/sPmp4PaNXgKz9ZJRaY2KV69WmHf7BUQ3QneGngbT0tN526SS5qDFwTGiuIlnYGWvTB2jVrbns68n/d8Fps8sSWfJBvvXJUEkaZB+1WqNilOPGXvyJ5k2O/iucFbRlxwlEHDny+AgsbtXZdp8cHQ4C/O4G0mnUMZuS38gn6e2kQ55mUhxKeORM+J6Rx1y4Iiu9KKNbxyS5eBpAlFB4xS/o35CS4g309vyOEhi37F24bpp4pM0xEPG4mcc/IyChHzaHUGEp1IX1ZO/r3ut9RIN2QWrGLUlZV/9rFKpLLAy6BkY/g8VYNrV8PztOL3rqy/qwqNZouONwPw8w8SA=',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 08:01:59 PDT 2008',
+ updateDate: 'Fri Oct 17 08:01:59 PDT 2008',
+ accessDate: 'Mon Oct 27 00:57:58 PDT 2008'
+ }
+ }
+ },
+ '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551': {
+ data: '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',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 06:53:11 PDT 2007',
+ updateDate: 'Fri Oct 30 10:52:54 PDT 2009',
+ accessDate: 'Sat Jan 23 02:24:21 PST 2010',
+ currentVersion: '933abcdd036332b566a70beba4ae486123475dad2903b00a939c067c34a074f5',
+ versions: {
+ '106a1116d22c2395906a346da4d830c7afbd2da9a46210d0b7a11de238016783': {
+ header: '####',
+ data: 'jgDUvByveAFnchBQKhiHGYDNDtj/7Aja2RePMer0FCOkkEu5GRAiLkxA3/DD3eiU+g+mCxnjnOaEIYL1O5o0+JP08XapsblZHTRKfveeFfs6sWwuqEHGYULBaXx4XSfK2B12HgpBwa5aD49489AkuyXi7t/aAXcKKJcLB1sC61DI3NsmajUaXHBi31Sp7nKAUpMuiWyguW0JVfH6KUPqyldVDBTBqHAis37c1qoR6aFHFfGgAfb35+syfmPRgemujMRkj2XO6dbt9zAYlHVSYFp9393rwPZoyBfXMMdDtSTmq7H9qbmx31GecHZlFN3NymtPPDYUbQ9mpPVRbxE9NjtiPrI5eGFvb++OdOx75PKjYjCAPWWFZ+4aryNn+h+yqab7pAuoG03ACVVrAFIOn09g1ssol/vqvalulEf3hAIviedyiNAC9D0UDHtzUwyIiELvR9qouXLZ',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 10:13:41 PDT 2007',
+ updateDate: 'Tue Apr 17 10:13:41 PDT 2007',
+ accessDate: 'Tue Apr 17 10:13:41 PDT 2007'
+ },
+ '111a8a4b6b912b808a93cf5e8785ca223112628d05f0bfc5dfe1eb40cb72ed8a': {
+ header: '####',
+ data: 't524etHmXljCnLC+IM+WPD8Q5VE7wDsSHVNZzFU4hQzk119t/N/vhtfHYz5HgNstU5T8c7h7RHKvFk5f+4ZwgNgDqSH7H2PrH+7/bV8+uuqbe+/3GYOvELjTF7v3xMyYs1B7ruHpT+291HVNZqxajqCl/+9nbG0e5feqNsTXWUTdLzF0szJuCTNr2I+fhxAO0LRVaf8h+MBPYyuBDnfFDuKm899IsgF9YoYRvjaYO69DkElvf4VP2jrXIJsRnGIUfUaIS/wQ54+X4JBZM/9M09MVOw1SVe+cwG+P3xyPUkqnSb77ECo86C0MktzeYFmPnPv2SM2KFA6slctXsyudoaNlReh1k+6no5J5BjaawTfqYjYrAtWSPsuhxYVsZym/X2CVbkz4rMSn+J5Uio9N5uZ6AqgCKdhAJlwzVb3fIIJwvFpVpy/0LMskb7aG2i4eAxwzx1H6rD3Y',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 06:53:11 PDT 2007',
+ updateDate: 'Wed Mar 14 06:53:11 PDT 2007',
+ accessDate: 'Wed Mar 14 07:24:35 PDT 2007'
+ },
+ '144d6eff3eb5f1cb70c8906741d88018cdeeae3a618ac4066598ad6b04242364': {
+ header: '####',
+ data: 'NPgSZF0eSOzy0/Ns+15Nz4bjSwh4o7fWYgKgwXLRFrF8y3EdbiOH7AiEmmPrCpT1raeYLWCcDIrRTz+/9uvIrz6kK6BjU2emr8YdyLai+PTCRY0SafWS3QiYixX6DJiKIt0SC2F6dfmSHwNsbfTHilFhVXn6wXTJpWvC+sRzw+h42cYpQp0BoLSuFV7vPz/+wtuQdl28BiBgLzGsrtPud0tPcfldGox6Ia/1SrOPcqUr0tnFlNQiUvPU7N0JZgRNyr1PfpAEhmYRI7aEJidsZ36vGQpE0ZQMmQE/9tLS/InALRZT1YXfMsytf0o3y4QlgJrvRgBL7fGiQOZJpU7igLk15xAwU+OLIaYIbr2xlKDJvndHOcrFoYKry9/A/aZSnEYv79wsaf64bBgIVD2WJGLuSFFmzlFnbg/O4kGTin3A8XBpvFA9V6iCMvnEMkrqxD3Qgf7WhxFE1A==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:33:00 PDT 2007',
+ updateDate: 'Wed Mar 14 07:33:00 PDT 2007',
+ accessDate: 'Tue Apr 17 10:12:56 PDT 2007'
+ },
+ '191d456526b14fc5b4ff11b3f856c9568562bbc68435700a2fef0d176482edda': {
+ header: '####',
+ data: '9rcbGeLFjW1cwULSScOa5zfb9BZqoSi8IvarxwjLVz+4VqApsBZnwJsxJHq/L9zV3SRYlAQRRLNy3lhpO/fJAOg4RNp68KdtA+IZfCsn1MzwfOoBrnTTELPKxDim4US9xQNdJp5ffWoLB8demEL2YkSNTrPVr5crvVPyepuRCzdqUoe6Dba05tR6Ju7/+d9K/cfJg+KI/ziSUSVlOTsIahGkipvMwYzhCOqjljJvdeF6XLLCh7F70lFvpW5vtv5jNmpkgvAhfxgovIZ3tav0WDc+DEdFNHNsCtFhwRYsb1dH5Ry01M8g4vS7PDkuCNYOvjL9bS2Wmy/lVulM9dYdB/d/gKWTjbqgre/IR1TPPdtfiVBo2J9PUvM8P/c2LmQrf63OwjWT74N0D7q/NuVn1KXzREQiyMi6ezzujzJolpNVUNkJFlnSHl+EqnfFiiR5ALZ7Nts4uWLe4Vpn0XmyvHoAVDBK3fw7e3n0tIG4x6k95guIWRKdDpYLOTHOe9jKJbc6KxdGmt21/5pX4KdeWavwirKRcXW6ReJIOVF+KREEZZOGWu7UKWgqgdaMuvxO472zzXzxTBvnpOmnxl/oIkhs23OPxHEwHXX8gXnyA60hd2tthCfmzfI48wWkO40cUTFnqO8htWRXwbUa9gYTjYWDTmoIyK9AgO+PfBLNqx3JzJYAymDcw39ItO2lIcEBkZ4=',
+ version: '0.3',
+ previousVersion: '6ca08e08104f73943447eba327c8d0bdab3ab9a01fabec1bd4734b52034a9544',
+ previousVersionKey: 'RDzOj7LWZcdVg5KmmIT5VXM0cUFeC9tC3n0IXDfNpj12cq0w3k1rpBYbt4eSEkOcdM7Va07FPNdZY4Pd65xBo2MGc56Ka1pX3wW4jTxz350qtw==',
+ creationDate: 'Fri Sep 11 05:54:50 PDT 2009',
+ updateDate: 'Fri Sep 11 05:54:50 PDT 2009',
+ accessDate: 'Fri Sep 11 05:54:50 PDT 2009'
+ },
+ '1ae171ac58981896484c222ab42373b0b6bc3d054dd56faebdc9018f3abbf549': {
+ header: '####',
+ data: '0ck0NbHAOYieUs5c1U6xSMf3pj743aIv1nnBnB7f4vsvKpMiYleQwr4SwY1W6vhg+3sLnO9C0CCD8Brt4V1wScz/STp4oB3hoy31W4dsAFsUyAWFJ8MrYDsZW3jotIPVbMKxu+4Yp051iDPcFKimDhfAu1zVyiVE9llNj3tP6d9gukUNfGZ5CvFmEXcheHB8t81Z2tgeO70EELFUn7uqKJwh5xCqTeogPtsifmCjgx8Yo6hi19vl2TDAaX0HquFO3WcIAL185tzYZ5rU23BYwxD7hVfan7lngSVq614MsEB3EX9WiHRoissSSajNkKTlTW8zsNj3VlUXKMQiJ2aA9Pi+/Yt9sNAbmyTl6T5TNN4QSquLPLyxO4p+OIjra1WPdmVsCti7fOyGirogfJF0XhZg4imvGXK0c6lPZIlg/OEnoDSTiHXlOYpSgaEw1Js5HZ+390XY0KYPtpsZlY+oeVS4p29HN7x3CEairuIldEsZrk4whiVcwzlnmw3n8wiewumus4eRh9w0CIwJELKeMiz5cX4bX8+AKS+u8O1W0GwKlEGTj/joA/M=',
+ version: '0.3',
+ previousVersion: 'dac2ca240227fdf7a08fedbc998c49ee7b6fd622bb8404e804c5dc7f439bf8fd',
+ previousVersionKey: 'moIwxP20kmN6f/+pgb8pJNqsLUz8Qo2BvcAFnXBmiX2E4oL1pakM9iq0e3IAiNLApmID2TwyAxhsmKj422R9uWXsUFd84LRRt6lMKa3/u1dC1w==',
+ creationDate: 'Sun Oct 04 14:05:10 PDT 2009',
+ updateDate: 'Sun Oct 04 14:05:10 PDT 2009',
+ accessDate: 'Fri Oct 30 10:52:36 PDT 2009'
+ },
+ '1f1bdb7a21440ac20c6d913d676aa30dc360252d27059e77df51a1be36b2e263': {
+ header: '####',
+ data: 'TaOHH6IoHPKLLoyLyvsBszgsPPcDs6CiLVXzXuXjFSTrhPxzUw9suSsisgDRRs0ncjZ6BCyqoCxMnw6QVvGN4viUwYVR8AWdCg0NMQZ+LkNfq/2WN0M3KyASI8sIdMCwTb57NzOn9soB1HmmmETZfjr7HpY2cc+lS5/4f5rxI8XTEK60lLed+aEuJamAjeZUdgIyu30mMKKjxPfY3Y9iWMwn1OD0zF0mAW+hyEoMhhK7EYlWKCy+4qN0QM+yNFXQyERb04o2n4XrM+qr9df1GtbQMH8igK5VzXIrKjdHjKoLo9G7D7mfx6mRLsmoAJuE0R8gyzotgdBpOgWasHJ82iWEa1dLRKBHJ1d0Lnumv22tvYfasx2DIR5Tmx3kIQ3hFieLSXq48cYMiaZH/IbLiapIOlMgtWDow8JuySBLei/8FAV8jCxSc1Ui/SjbuK/kCvywaSOhDVIxGw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:26:35 PDT 2007',
+ updateDate: 'Wed Mar 14 07:26:35 PDT 2007',
+ accessDate: 'Wed Mar 14 07:26:35 PDT 2007'
+ },
+ '30cd48ae2101c0005fdbb57917031ef36c2e5681890f212a95a2863463369043': {
+ header: '####',
+ data: 'jt/CbXS+TEjH/jPrstH7cQZGK3yse470grrhdAOdWoGVtFMmL7fMJZQOKm5IQSrMHFEsH3PoSs99Rr4ui/u71vUb6s/TIsjyv7yihnCYVsOEJOPcnL2wynciILV8p48Lky1wGztW+oSynYOG0CGYDofFhF/MNCBsG1EcTqW7Cf+8rUiS4nA4ZRZVv3HsZp6rCabJsAoK1pmf5tXGJHPjS6xdy1A9ea4bV5Gad0pu8IXvjbZTrDymHem0t8C+oZ7uJ/mG9cFVcNykXoO/TDP0goD6KvTqtdY3VWNNTAERycAW6jFtdMv2W/AFNmnYatZ+EbSbj6/RyGaNnRv/ceBitMh73HRr1EVtZw0wPthMBXwnlPbpkfUwWPBHYpwImligm62/6YBhxDgnMZta7TSi8apT',
+ version: '0.3',
+ previousVersion: 'cd3479e91eedabe34a1b76f0f26c69d7612672281bcf5d682a787a48caa66521',
+ previousVersionKey: '8BbhE8C41VX8B8m3TbfLz4bgSfE01IAUl8Zlu2YFdEhpw1erqInN1eRE6WLyBB5MxckmJpbn6VSizqbFbi/3Id5p/fibHKmbmNp6xu7iIo5zzA==',
+ creationDate: 'Fri May 22 03:30:43 PDT 2009',
+ updateDate: 'Fri May 22 03:30:43 PDT 2009',
+ accessDate: 'Fri May 22 03:31:39 PDT 2009'
+ },
+ '6ca08e08104f73943447eba327c8d0bdab3ab9a01fabec1bd4734b52034a9544': {
+ header: '####',
+ data: 'XKsPGp4MeuvDrgikcjbMnmw/Gz74sTfyP3lLylbrtEZJ3aGSjRvE7s9o3Ya9GKRhYxNQ0dXT0vM6xIE6r/dMt8PwU+/5dNtRhCGPAHvKmEEGb6EBwR7gUDxQLyFTAYX8ut+CpyNJLQa2pHoEl5aNUTjk6blYrKp0GHKt2Q3PZrjIn78rcOLcKY5bx4OK0h9rN0G8mOFQ0g29knKyaykv8dja/Uy5XBeshKnVT7YRHk1nRuwz69ZcX+1Z2qzfw5sxJx+fDK+otWVpjzDP02qqn7ju/r3GgSnW8p/ghBeurUCLdQiS+fFAevhOwCkZGjPMntG3Q4qVt42VxIiiuvfShdaSsNMOW9Uziew3XwOYL9mNIOSdPSjtry4sKrAh3XNmfuJjWTy+69Iyi85CtQ6xMFilANgSBfTqThUePCrEkv9ZBbvpRovuuljlxqZ3gUmtvwy9a3ACAr8SMGWX0ydQjKyvZhoGRCBM+ZC7zCe/JmIpdklvNd/+HqUgS2iAnf3CeH4gUPQVizFR04Ysgj00xO6v4bdY2bYVKIxunygBGNzySi8DeSREu/rUKWgx0KY7S+Gg/jqFMYpE9oy8CxUCmSLeNrnxUgprPqKrr72yue0kBGVoYyJwhXo4MG+LPV0rtVp8b2GeHE9fYmyEZO2Ke93SrHjezS6CnWQsvjYsFYCLdLtEGwo3mpS46DF69LlO53k=',
+ version: '0.3',
+ previousVersion: '7c80cac9c8b9b5f0f533dd3852d89d6be07963eebfbd2081f2ad6d2f2a06b447',
+ previousVersionKey: 'eEvij0YZ1r+5cNNpleVHE+kjCZlSggZuE+3Kum9b/11JGHTgQ3bY/o5amM+4+FPaiCU0Zd6MWFAI4dPscyvAS9in6WdTOm7z3fQ3uqYAtHghPw==',
+ creationDate: 'Fri Sep 11 05:54:01 PDT 2009',
+ updateDate: 'Fri Sep 11 05:54:01 PDT 2009',
+ accessDate: 'Fri Sep 11 05:54:01 PDT 2009'
+ },
+ '70720f026f37b571e9765d27c51d3d60c7be0293c3266f1f987c8de9c6b5c416': {
+ header: '####',
+ data: 'NYaYljcgfzrlN1DVgrbyj4AeVhXGjXPho3IQwEKD3ZOx/yEZxldCNSyFsrk7PoRB8Q1T/6VV4CGa4HLRSB7QVCrtVqWyu4KbbmFoX8NIQ0H3xv+TSo3S/b3dldUeyW32ScaGbspaf8nFf0CffsgpGusd+kHdiE3gSLJvH9y5j47KgpyyX4TteVzqgez4dcXIs5tdzJq2eUlknwU4651QeKIuRSmRaDRhhOP4yRgUo/qXMlTJFmHviCh+IumvBdmDoPe3Vc1vZ1r8PxpDJLvDoB8GTDE42NhqHfVrew9ym1xlTD9wswwIEikfOyTq3JM857qPOHRqSqthEvr4WHbm1VW5PReIyse0lugGyOzqtCnADp9NvNI440VjaTd4NBQqF7XrRm56+1u1uTdfYGFV5BRiH1KmrM1sxXQ6PlOF9Lou45ALo20xxvJOLKG0RKLMr8gmVT2bNtOSJw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:30:09 PDT 2007',
+ updateDate: 'Wed Mar 14 07:30:09 PDT 2007',
+ accessDate: 'Wed Mar 14 07:30:09 PDT 2007'
+ },
+ '739b67f6c1d52093f5c2153b406df90cd8ebf303ddd0d13d825fc946306114d7': {
+ header: '####',
+ data: 't4ohy1/z6oUzyQLtqQoumRzcLCnaYjL/+WQGwE6yIXaGEhCWywe0aIVusPKLcsfYTCXVU1/dXtuucaZoMw7PMSOUx9awTp14NmShaT/9VKChZf1TLi0CO2jOUGsvO4DHlNAQhJhas431l83F+h5+hrkqX8j5kIhzpwlroGEjkml0fswmmwDyHbSTgVEyErZc+b3V+9oUCwzYvd9ITHh8uWLa6j+GuwZTZAk2FY7Vzoh9K46WO3/qCz1pJ8JVkcffun9alK8qzK0Wp05mMLIrt+WHFFTKrG9zpBkcswkbwhJ5ZnakfYLJ8GPH7fKnAid1FGW0Owms058smDBmFO20HyH+ho7SL80Q689W+Jx0+nkUKvxWtq9BWLW6Z3ClDZOVITeg35gQVr6aRzZ+VZwbAy++',
+ version: '0.3',
+ previousVersion: '30cd48ae2101c0005fdbb57917031ef36c2e5681890f212a95a2863463369043',
+ previousVersionKey: 'i4e0h4QhuN0B39drNLsOWruy+R64siKHWxc9YXgpoCPitWL/ika1MVCRX7CJC7lH5WD9yzx6l9isAy/Hb3nUIEp97VcFKG4S0gOaZkdWNZ/U5Q==',
+ creationDate: 'Fri May 22 03:31:46 PDT 2009',
+ updateDate: 'Fri May 22 03:31:46 PDT 2009',
+ accessDate: 'Mon Jun 15 15:20:17 PDT 2009'
+ },
+ '7c80cac9c8b9b5f0f533dd3852d89d6be07963eebfbd2081f2ad6d2f2a06b447': {
+ header: '####',
+ data: 'LDAixBQ/CEqQX35jio3aAXG+Py4wNylXI1mQJ5IDxnpqmkFZfOXCaScpwIkQwQzEOjh9p3cOShzrBm6r234HKxgg0ufFnkTWbQSjCgekfVEqiBFi2rWSj5v6a5LMANLwtCz0b2IPr6Z8LSPddgao7P0nwBdCiKJAnY/uGdvSn67WSFhAUGAIs5ZKIZQf8Zi+cA3hd+Xlv1W/2+OXLaIPTkD1bCuQo5qEiAoOl5mXngWOmQ2kTGpC7Hfkknm/uzDeiZTe8VpGjqKTwB/tl64LU5OD26DMpihnVeQNqMpYndEJO7Yu9Zodv8WMyYmVlrw1UzTB4BLTL337vVm5uBiUjAfJIwJx3b3fXxdEiWFuK8uwOXAO2X9OOKfLPuowOj21B/+zRLum3Dti23IfHab5KwSq72sB/vjpl/KVbcGsWZET4VTCZvO04T6Emjb2UBLFLIgInZ9tqN4RXSKz0Uj4n+pitmFSDleuPtL8EzEESX6FtmT/IVdr5AGNjv93wIk5CgeoK2YiNlpTb+CHbcA5HPn+TH9T4999mWrJh5hxZ1vGYxlAd1AveMCgA3y/Wl+kZKMnUatXPM0deUS1GnzpoRXtI0dUi6J5sOHxeahZL0TQbCbHcKkoaSJklMl5YEVaLXyakO4ATKyNcsPfDQrPvWfra1I59RI3seStv2Q0bs14Zco+0opvKN71R/HxjF/etUU=',
+ version: '0.3',
+ previousVersion: 'f8ffcda2eddd2f6d19c4be17f6f509f1f66fc5d4bff362f402c6addaeb9cf32b',
+ previousVersionKey: '3JAEXzigeX/PwpA42+K/CPSpP40EO/j++M6pB0NF71EfKCApWSWy89flo0KbrckF+mUAjyY2hLYBc/F+Q2vgGNhAZqq0vo3wcUpFjFktqgRZ4A==',
+ creationDate: 'Mon Jun 15 15:21:15 PDT 2009',
+ updateDate: 'Mon Jun 15 15:21:15 PDT 2009',
+ accessDate: 'Fri Sep 11 05:53:23 PDT 2009'
+ },
+ '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854': {
+ header: '####',
+ data: 'xI3WXddQLFtLVzxJaZWQaw8wAgSuXLjLnyoNXnFuLecTH0BzU36PatglVh2HK3LM8aDLzzbHILdlLNnJ9CY+YnhmGh8hswF9oKTgq0Wsesgdc20QhSMNFFjmMljY1LSXmcAYK04Q5mIzi6Pe/04DRdj+e4zbe5QI4vEBhp/ohEpxZnNqc4BoX6J0eVf6LA1pwrKWvxzMxorWsJrrr+mn3svdlF437n+MMr89k5sQJogufes2GZ9tTvVZ4247ITxXqxgAhwXtbuIs/A5UqqnNdsxlHfpLKG5KjxB6F0h7TtFA3gkZCve5UmAibBnoBCFaIVWQyVq+VO9iqDm3DeXsK2pepvgIvpSID8Poy+uwN7T95mivAsHG5p7MtgN9KwQzNW3Iu+BfO9FlPBMngSk8L29So2CIXe6lEsXSGEi5Yrgyo6hZi6IkGCXwIQ7TCEMnlQEGyKnnAVik',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 10:17:52 PDT 2007',
+ updateDate: 'Tue Apr 17 10:17:52 PDT 2007',
+ accessDate: 'Fri May 22 03:27:59 PDT 2009'
+ },
+ '933abcdd036332b566a70beba4ae486123475dad2903b00a939c067c34a074f5': {
+ header: '####',
+ data: '8mmpKGrkSqiLyreEtGdKN9EXeb47uEN+XkSXEhdIxkMkmvR0A/AGtKjG1o6bbSXfPzAtfrMfJJxwyhWcRVqcikzc0KwINua4X+1Grf7QG2IOYYFqujmLyCwClGSRaannCAbio7+YI2PlDrlMrwB38RvMde6zrMfZzl2O75nkVX3DH+5IHJpwwYeukTSAu5EQR17oed+xoSHkKCQG3ToTsbnGPwZSGM0D+aiTXVW+PJD8D8LvDEU8i3EHQ9E02+d3dKPV/3FGRDgvwLIIjHU0qX5khYJ9PjqSgAxOhRKFwnG1kJn6NG1rvsXYgefJORElib/xijoCM9EJkUZ9e340WwhfZa1GbV7gLEbVn2aeaLcaTjhtPz9pL9WQOklChvdi/0XaHRrgflHogqC0qUQ63lA2CFOXwR9EXspZIi+zLzgAaEMGN0NlnbGHjAiVz6SVU/RUkh3DkKmMuGNS1n93spVbMMLZgcT5zxBFzT6jARvC8qKaxe9UlbMIH8ZCXMrq26V/sEZrxmPT3FZB+dmmqA9lLEBFEcw927uu1U3kZwXhQArQCN3MbEQ=',
+ version: '0.3',
+ previousVersion: '1ae171ac58981896484c222ab42373b0b6bc3d054dd56faebdc9018f3abbf549',
+ previousVersionKey: 'gxQ13UMdZF0F7chGySUkuhxxSJ7CU2wubdG0tijs2G9uxYEY6ADjVX6zi3nrft7ggnLM8LyuFtZqj1wMX3pMUsbxZq0v2vfpVaYZ9cN1pahwMQ==',
+ creationDate: 'Fri Oct 30 10:52:54 PDT 2009',
+ updateDate: 'Fri Oct 30 10:52:54 PDT 2009',
+ accessDate: 'Sat Jan 23 02:24:21 PST 2010'
+ },
+ '9588b523f39cdfc14efa1e15ea7716c2d8eac45d8efd7bfeb19d716f9df72d66': {
+ header: '####',
+ data: 'q6DKkxhgDFs1XkqOYf6dvojPF+yhJbniTLFpSOS+I1sum3EZIJfYxJXyi2Jx3KOVNBMILw1+vrSLe/fh5SSWj8ZBoeppkPPLjyRNdiUyd4IfcRM5OSv2YcTxCubKCH2kIMFAzY/29A6ZGPG+AN8/kxkEHc1fxKaNcj2Cs8qejNR8yK1iKT1Ut9VfEee+Eqy2Ohgdq8wL/xAD5mUzdqHeQl8BY16pXGIYncLxMzR+EJ8E5jJTuGv3O41UbO31lvBSfCt2pfz2MrtsuqNoI8LBHJkcR6t17Bj+rHZUniHlyxSW/1rQJ1NnwpPgUJ1fhfQJZM8Faoif+0bvWFY4xWs/tCCD7oEvf0xM0I3FfcJLbYX8M+wyO08t9BmGdEjnr3VUcuS9qKaJRpdpMP7aQf+vJvioeQDXdOJ6Ceo3BDFc6JdNta1Qc+agGzN2KPbIPrLDL+08hWl61yu3GQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:27:35 PDT 2007',
+ updateDate: 'Wed Mar 14 07:27:35 PDT 2007',
+ accessDate: 'Wed Mar 14 07:27:35 PDT 2007'
+ },
+ 'c7add675f676c4615a2849d5017ac8db9066265253ffe7e03b34ab8260b10888': {
+ header: '####',
+ data: 'ZRJXJ72ZBH01gAML0R7n42fI0WjdbVXzyZH7H5MP2RgtGuVvfdadVK9+U8mzdf1Et9DoKrHhZUp9baeREPO/Fk0r2IO8NmKv/8+rMkK6x4qeWnI8ZAJfQemGtqke/VcTn4KGAyTeV8arzXn/whsLpp/xN087NdDw9dP8PLb43Yk8TNC1m2d85FUagSh4NOI3rmcbHAiCOQpqHBPBoJY1Vf4Pxu949TEUm6kT6Rl0n/sb3PSLu4LSa6+WiGZJ4mgE+3XZyfozrJsvGoTYSkim3MTwhrCLEVaDMTq4Ei6FyG+TeV95Q9Ei8HHwBqdp0fxUxavNe67Oo4m+ECiRvZ24b5+Nz6POBjXfn+61yCyIhz3SV3IaYIF3rgXRZA1q2sax8kRGtoG7ONxczUqGyQ5S6Lht',
+ version: '0.3',
+ previousVersion: '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854',
+ previousVersionKey: 'ZbGA3id5JTGeRjVUR/LkntSGjPDEbZbNrQxc4SiQDdlDO3dJNVpfRp69PSk6vqEiZ4r/6OKvE+fl2TtPadJQ82fP7WsULtrSkYryQL+CQvz0VA==',
+ creationDate: 'Fri May 22 03:28:11 PDT 2009',
+ updateDate: 'Fri May 22 03:28:11 PDT 2009',
+ accessDate: 'Fri May 22 03:29:03 PDT 2009'
+ },
+ 'cd3479e91eedabe34a1b76f0f26c69d7612672281bcf5d682a787a48caa66521': {
+ header: '####',
+ data: '6TAJAQ4qE5l2SybVzeEqQxYZgVow0MKzl8xwfoE0HeuSr8uJlszGas5NaJL1SFI5sDDwIJzbtIBE/yjaNwWw18+JzswIWmkLW+kTIAtJKjNtWnaGlDJMTA4OIo5gj2Vqq4o1VngzMTk/DV6f5ob3/HxN+YpE4r1u2SUVeADbjcyjRmYE9ygvuvQ5AuU3u2hzmstI582kBlksLPGhX6nJfAPCrSkdphNj28T393p5w82/FFCFNHKjgKN/xI3Rotq7rObFaNid1tmHvozKLYeLQQfjglJ2rRDQDTOJONRVJEObDFV5bmaY4z3XljO2nbQ4iMK5CrTFAYTYNph3/WOQWjZHWmAXaHMYvBSlICvF99C530sOGQYIaBWKFuOv/pNuCZh/tBNVcI4pU1dz438/7LQf',
+ version: '0.3',
+ previousVersion: 'ffb687c41ee598b30cf28525024fc18ba96b3d7998fbb298d702311f76ca2127',
+ previousVersionKey: 'U2Z+xaFl6o4XH/8DktJimjP3+1PaYRf1mZPW0sulAOykDH0LY2U+kbBj+mfNV8rVAJlA7O8LYl8AlUNZUTS+036MiIinpD0Tmhkc91rFkMYgbw==',
+ creationDate: 'Fri May 22 03:30:03 PDT 2009',
+ updateDate: 'Fri May 22 03:30:03 PDT 2009',
+ accessDate: 'Fri May 22 03:30:36 PDT 2009'
+ },
+ 'dac2ca240227fdf7a08fedbc998c49ee7b6fd622bb8404e804c5dc7f439bf8fd': {
+ header: '####',
+ data: 'zqOJI8Qken5hwXQ4MFRzfnB5tnROjMhg9mw+aYwwvI8VV8aADoyPuaRi6bdxy4LP45PqVR9G2iXFT+h/WaBql+rz1AA5AVz54cpd2gdDh8Eec/PJXyL3SfXW1PQoO3bwhW6rkR5cNQf8xKxlmGWLvE88AXT65tV/RdYJE574aVEZexzo/40X60weCl1ZITl8IH97eug5URe1lSBFsy5sjo+SE09FqtnmnGy4O2LL+0XSR7xJqiJihv80msEgk3lTbwUEiGWm3OiDnvLk0GjaMy3+EGV2/rHZuICMJkD4ge6cIBc/h00ZCFnXN4bX+OC/KpEFgtnPgQ+duVpsVNdYmNwxSavyFs/UnFFDTDIPZxEKhRHFTW9zaqu2jVTZd4+/ro6TSYSlEN6F/jtiL06nM/F14Bp/dYuqBZfc+N3vx+72jj6IOKTHtqvlj6jdSZseN8olODT2IGI/fsjR79biVCIOODAaF6DCd32ClvoenCVPTIhMc2AfuKTbleiquk95nN4lgpZbMzrrvWHPJD0oKXHo8X1GJd19QCj+IhzCTx1Ap1JPOTMIG+reaxxwicGjH5Iios5DmA4gjsRWj9BVr+QmMJmY4KTpyRG1lVYovm78VWf0nzyGLNx5sgWrRyYLOI75m0zUdNGDUpKGSyqrIuEwOrI36uRr71MvJ0ui1HXBkDbPIvrQ01UyocO1paeHyTk=',
+ version: '0.3',
+ previousVersion: '191d456526b14fc5b4ff11b3f856c9568562bbc68435700a2fef0d176482edda',
+ previousVersionKey: 'zOAbF4q8A+LjWfMMXHRHH2DmzdToA6a2U12y0G6cyAm5tvz1BrrAcgk/5dx0yvFF+ZSxuOOfnvCPVBN2kT75otq44tVEg+FSJ4khcC6HThCluA==',
+ creationDate: 'Fri Sep 11 05:56:02 PDT 2009',
+ updateDate: 'Fri Sep 11 05:56:02 PDT 2009',
+ accessDate: 'Sun Oct 04 14:04:58 PDT 2009'
+ },
+ 'e5b71df0d4d79a195c7ec3288dd7738069837a7c4da3bccc1ebc05d8e4f19d79': {
+ header: '####',
+ data: '1NvK9Y5r0Q880BfB1W5IqdOR77mmqQU0d1GL1XUeQT75R2EgYE9rK1X1jLygCXboPhxzegEe7TDhUsn5XcHN0LkXcLYz8gD/7+He2HiTFxoHd2oQbI3ceBxDJ7+5kWA6Aiqy42QSCuA+TWIQcDVthSyFU7nNdqNxeBYeXiI4jgwcH3xvm0+pBf1OYLtywjUK1JwntP6o68b1LMQJFinDG+sqRcm25ggaZyxDtoLh1IBdSpmXk0papRnyyTGNgsws78dLxnH0Iqxb7FhqYfgLDIvN3i7+IALI0lF0EuTS0hSPlr/1fTz1/6bVt++wI9GpUsrdafUJJMPerXoCK+gAP8EMneLq4f5487HIkwWh1qON6Hvpg+tB95NOSJpqE72VpVxN4+wTQWyDMhfjqXBuQ1wKvTsD/mUsdinU0Wb/YT/zIWBNZPdqur0rjOC+mrOtSdlYSCH89Jj2',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 10:15:09 PDT 2007',
+ updateDate: 'Tue Apr 17 10:15:09 PDT 2007',
+ accessDate: 'Tue Apr 17 10:17:01 PDT 2007'
+ },
+ 'f8ffcda2eddd2f6d19c4be17f6f509f1f66fc5d4bff362f402c6addaeb9cf32b': {
+ header: '####',
+ data: 'Al9KSfdnvVJW+GPqYbIGXNDb4KefUjtkNTJbk0zlBsyeZc+eoDDLJKy3ukugFfDFDmX+g0U3lp1UIsRQB7JHEZ+NWKPJu/hyvbTmwuVFZUnGEZMhMOIqc6nECN+VFCllxV7QBKpdcRJ3E3fiYP4fV0v8wquOD1dfsMs26f3y2fOQLNS0+UpDe0GoRw2R3+lbot3qlftdO6vb5+LYjZEjdSI/G2fPQ3VsS8N0KLLNVHQxix4xn4Qn78i/ImlxbtyoKNLP4ZIaXZ9ELuGvV+yKaQVOVTwxpJOWKMu1Do55cMwdFjxU7Gid03xEYEaZpClcsrbwdGgkJo2+WnpC/L9G4I9X5L+sVISbO49PaZ9DMdQJAlY5QCIjokPchYUp9Vr9u4KcgbAw9FrLQAMSRLnWhf0bLr0mv2ioTOlQKPFBkTIuMnsyglD856ZYQOIHl48+K5HvUZYZqI5UJjPXdrmzycD/Yxt878pSnkkfeyX0Cr/7Rwfq/zOPN5XJcwsO6j9ubuXjnIos0E/SG1BOKrLY+sE7SXzWOqhpzkApb6ILaGhtHNOHmYAckpPAqCe85g/XPZsmWjsABB64Gwg9oviC2ew/IDXigNXGtY8tbQmAny58QPfRihT5HxCRMFP2pA1Xh2WU1vEXtP8=',
+ version: '0.3',
+ previousVersion: '739b67f6c1d52093f5c2153b406df90cd8ebf303ddd0d13d825fc946306114d7',
+ previousVersionKey: 'B0wCj/b+UZP07a7VlnKVl/wtiaFzCmPux+T4tBFQati+nSNQCHUQM2XAQ3n1VWeewIyLjKlVI6W7SXRZnCxlcOdqBLDymDkhKfL0FIvmHNKmig==',
+ creationDate: 'Mon Jun 15 15:20:54 PDT 2009',
+ updateDate: 'Mon Jun 15 15:20:54 PDT 2009',
+ accessDate: 'Mon Jun 15 15:20:54 PDT 2009'
+ },
+ 'ffb687c41ee598b30cf28525024fc18ba96b3d7998fbb298d702311f76ca2127': {
+ header: '####',
+ data: 'mZNwCsPrEohGEYglwUcTQNPDGJWoQRcRDIoWJ482qFJu617UU3Y0hML3CZ+ALtITVpnZl6mGZ3nHCpigt5naJmvwjyV9O7SVkGjc7mrzvjQSP2jrlXGXVIPqjsywDgG74bmaOPLEstQ9Sb2UPGIdinYdDglvQsIaFHQaWHO9bSYLjitfuS+qH2erK/QhqJQ56LxSpcnF5pevfuKZVAkrfhYAhIxqSQ15lZ3QSHxJfT8pQntR8QWL65RetkX/c9eydWyPqVFKqCTghU18p2Omz74UEakBBh3o6DxeTw90UY4YM1tRmsalS3oYG00BFDfDD3mEVZNSrqsxdCikqUSEGvq82whYxsFTj/5fHVLoJybYg5MfpLR+iW8O94g9p2d3jx2mTeNNjOZp+Q5/Wc4rKS7r',
+ version: '0.3',
+ previousVersion: 'c7add675f676c4615a2849d5017ac8db9066265253ffe7e03b34ab8260b10888',
+ previousVersionKey: 'RFTIyzDM9GP+QklGI/YfTgxB64iqyF7+c7bZntSZlFFDkiVN7pJbToZjl47c272J4dPXFxkORR2o+pIyYDdRvKQZQ/oHXp9aZi5BDKGwHYkl8w==',
+ creationDate: 'Fri May 22 03:29:12 PDT 2009',
+ updateDate: 'Fri May 22 03:29:12 PDT 2009',
+ accessDate: 'Fri May 22 03:29:51 PDT 2009'
+ }
+ }
+ },
+ '36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113': {
+ data: '6fhueIibbxKRA7Mtb9TPcWiUKajnikM3D7PbOROBkE39Vw9E/nG8KrtJlwwPQeOGCFhssO/KX3ymYehCR8rfaEL1f9pfdh5x69mSxKRlOmtEknWqUgPzcb1yPenRbQagERadh0LF4zu91M4WjXK9qynEHoxI/pBhwQb1IsnhwtXl4ELtajudv+2Hv3p75v4XOXFsGQMsHPY+Zw7dkFFA8EXhvuxjiGvnxCUkFwNICFRdHTEovkW3VSerLdrYo5lDgjY6ebr/g7wDGuu4RLfUK4+HpzFwZ0+aOrjpFq2ePg2xObvkkMNNjZ2PcR6Cue0sf+aNqzIHIlFPpY2Hmrob8+bwxocKA6aagBu7z5GiUmZNXGE/Vtr/WWBV2+xIJyzXZPet0MLmSnGiALjPJveeKnnFdDtA929ydcAb8efc0/snfU/uDoXDiO5SWEQ8DDNjj1bSo7VPTtvZyFormE1KjqimqSwaUJzbIS4CxPnoDezaBtQmlG4z8mc8jXq1HfPu7s9PUzcbG30gbF0ch2pDj4h47AhE0ZoeiV+VYZTaYateSifQXKBQKjPcuh9PQyDI0HVua3itbbwxXpRubEM4fbvlcd+7gu+Zq03slYICD07fP0I6XGrRHVTfYpDbEb4GJBvRIeZLwRTQzOeFbPLpBU9Lv3zXxfHfcHy9oK+giIxefPdY1ZR2ZFPKOO0xYJsTr0vmTuXeXzy56bKl+yP2lFst5l9QG8j2JcQEotDV1KQS6mbcLjfIpEnltu5fc2t10Q25Noh+F3kF+LcMIYsDjwanojYlOC93mZl01hmSJdimRTk9otjlRTyC7NWwiyy7fe5IyVi7ACNPZyeUYJUPtKWcPbT73Vtf8W3/+HdhmyYNyMQ9PDCBb9WKMon+qW2+ZVH5yv/KqMHRY1fflAfxpHNhrCkwqcAAGw+G/cetbvQjpkfVT2/u/uLupMsITN2Tgvr/8D2IMm3cyDBUCshrp0AfzARRygHFK4x/0uLfCtQSNjw6zMK8mn80R5aS5bZi5gRS8JBMZ4Q0iG4kBlLpIYtsXSBwl8faljjdl/4XvNNWWrdGJn2k0eM4cESlOFFk4s3Yu0Zspo17nKAHINjHAiP3VlhuKSnk5C9hMU5i3vZO8anQmx9UEwUgQVm22azCjyNtUl6jVPYSNsal7A==',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 10:39:35 PDT 2007',
+ updateDate: 'Mon Oct 27 01:16:14 PDT 2008',
+ accessDate: 'Tue Jan 05 01:38:41 PST 2010',
+ currentVersion: 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463',
+ versions: {
+ '381201fd3b67549bd6630841e8902be1499f3ff0c3514dd464ad9679f22f3561': {
+ header: '####',
+ data: 'DgjIW4YcJAYnckuEUzBFkfEC841LuanGopPgp+YkyMn3xuzdpGq/ObLFMVQaeAuyErh1B0REHPbq0E/SRUZbeXLXWN720GU4GXvY5bnen2h7pHvl/H4yz+kvyKh3EHJmmBjuz8s0kclFJQB48lter+G93TEmUaFke9c9m0IkKlgzwZ/PQKZyIyfZA09KFaozdSxdFRbswZj2Vq8Df2PQsKLapZWX1wYQ3lXOcyvNdTULy9MCXwPwX6te6hTLWxQOiSPsvB8LItlhQUsSbrJcJEvWPlBupPu5SeI25zDnqKDETPep63Ks2GWf45nXZzYYmQMzL0l2cenYFxlE18TcOd1Ms24TQ/iDKMhi60zZoo13qjVT5AKZ80KNu46t08qbACxjv/LeK2aM5TNycTFixGskPywpnb6MCo8ibRe5rs1WcTJRMD04sNoiuriivO2fiyo4rxjfdyfueMlOz+Zeztk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 10:39:55 PDT 2007',
+ updateDate: 'Wed Mar 14 10:39:55 PDT 2007',
+ accessDate: 'Mon Oct 27 01:07:56 PDT 2008'
+ },
+ '99dc86ebeb20a3db0c5393d6d94bc1150187b04316a876970dbbcf517b55d6f2': {
+ header: '####',
+ data: 'AJwqCWNKC9z8DC4TUI0hWnqHvQ40Y/x+jXylnVAkyO2QYQcqg51odLFSfgP0GiGEGPYwDc+kUxRrfO+ITgTNm+hHi2iIWkP/ljAC+AQ56MAEKsU/USTbvl6ShZ0XTAdRpwI/oqqOhYThVs6jTm/J8+lx4tWoMtNj835py88c/9eW26pLQubr7VysLSWuIMi+iDp7zXZZz/0gxGKDe5xNq4MGIYw8/OK1iJCOsjBdrRygLlS/Mz9sRlKkwdrDsohtRG0F/NdsIoaU4FttGs/rY91SCedvHy6ovh0zXhxOO44O6MiMbP085D1jCjWJn9S1RBxjxc368MGfMJeZja87nuvgSnLS2tGDL6zFtVJMNcH/7GqQPXZv/sNEykDNWpypchCnwYUJxvBVb45FcUzagPm+SSiekWK1hrEntZkZuEhQZp7Ud9RcENpa5h7wXUJSV1vPl8xBylx9HWmxez7D9OYRqbOlCRAEDqup4ahNhYB9',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 01:09:11 PDT 2008',
+ updateDate: 'Mon Oct 27 01:09:11 PDT 2008',
+ accessDate: 'Mon Oct 27 01:15:58 PDT 2008'
+ },
+ '9fbfcd3e7fe30d549a813f0e6c1be58ed45c3ae7305d7367bffefa097b424ee6': {
+ header: '####',
+ data: 'nZ+Lc5LWWLxnPvUrRrHhxG35PHq7GMbVENHfV1oS0Qw7/63NecssNoEbiOwFVMjAshvfUK7IjnzyvfQhNtFRbj2yzHOTWCd0eJ0O0MmvGzjpUntSDu9/G8RFeEu9jDKugwi/NhOa5legjT9pcsEAqR4s4NN/Ac6juQb6D/Z6Wd6wO0JQhT5/QPk1KllDpDeo2i/GPUKvEi/dXpik0KQcVLVylU82rf6hwEgvRQi+j0O5hnFW1E4ttxClrnPBEBv60jkNwcIpD0r+rvomDe8+398xUuB4DVDJoM+WUYfu6Sm3qI0yBfET+tJvjn8WsHhKTgZpOc2BXC7EdF99nNEg6kV5pSxV6AUA1XUz5kW+YfcSzAXzUH74OqroC0SucHe4+BtRKnbJy4h5vRfjTD+FJaj1Va02cxSR55tQhxm/k67z0QeyB98dnU1l/pPHwBlIWa1eR74gswNSeQ2jrzu5JeQ=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 10:39:35 PDT 2007',
+ updateDate: 'Wed Mar 14 10:39:35 PDT 2007',
+ accessDate: 'Wed Mar 14 10:39:35 PDT 2007'
+ },
+ 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463': {
+ header: '####',
+ data: 'm3yhZu81UAjCY6U2Knrgg8mK+LX35Y/iZgIEm8MuRDAlg6UUz9Z1Anu63COFV08YyYQRuBzTgR9YQ8wrUD1S9FG2ZmtCDemqvd+5OUMgdn4sK7G3CuzAc5osOa5neU2m4y19WuobkGnhO78ko7pVVjO42q0DeMT92uFL6KE/2UCkWlq5SdFyS5qXEJEWs2IO5C8nVpdlO/eZ36Pl2+v+afl3QQMTthCVIUR4/zVP2ajbO48yjDXhYxzskFjtXMYLApEn0wO0dcifcsYhPkozz6Locrt/R6IZXnfZfuW5XXHbqhutoJFPK6L6t0Ib3B2r1TNkPaMsVs2g5V1g3ENRd0IlbG/uBk2o5tgeu6gOYlA1scEiL+/ad9ZxiqYB2ENCGZ8DXA4VNMnzxVPbO96OIUCb9suV0fldGOg=',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 01:16:14 PDT 2008',
+ updateDate: 'Mon Oct 27 01:16:14 PDT 2008',
+ accessDate: 'Tue Jan 05 01:38:41 PST 2010'
+ }
+ }
+ },
+ '507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a': {
+ data: 'ncSFmp/+n1pYUKi2fwhMCevSwFYO5irdcpOlSxC6YPOKYavK4iUbtBsilYWd0hpvUHW2ItaDwiyNFxs2Lwegex6dawKrpMYkPBcaZQDa746yACGgCkhz4MAGnUn5HCmz6xhpCVXMMKe3w2nEOjRB+pOMOeJt2n7aw0hCJ9tQ9JTFNrZOxeXrqoexrd210Rmr9FnKhLIvhNTN1/vXRqP0ys10omJ2mowzF4KoEVmz3ET6pS2d7tGjt9M/OYsH/ETWWc92doF5PO84g5/3HePaCo8NCqq4ul7AWJEbdnkxxmd7urJzIscPQPcoLxL7GfG5LhHTFyHlfFz9dNlccfA+OPftjyfjXTjLYZzbxxbi/nAB9Esqj5AoHfqaJM1ZOrZ+qAvm8Am3+HAXrqtiybDITrCLmGH9ukWDsx7R3lYTlvjArwORBUH+4w4/uYGscVm9kOYj/Rmz/ZMH9JibYFcPcOnr3rWXPFUL/XsXTrm9lzOvPyEYJmkENzd54AHC4Lr5vHpeuipWFLiJOrtn2WcgDG/DdLaYGKsmISXj74XDtP6Ee5lKOtbwwcmVNrl11UCQBEFHNybhXvpil5laKddOauLJDKtaDL/mKYPbr5YSk7HPCzRyE7HM2dC1MpBHuJ8g+hDkgU3wQcxYduKLRpuC0uOqrODigGWhVrdiKdZanlWUq9EkE3eH+E2A/CA8mHl7UNaH89XSvgV7uZyOmK7iZ+1kd9OzhBLQdJnK9qqP467Y14KsTt1E1+tqlqVAuK79QMnllaR0e3ztBRAQsyf5SD0KuSGXWz+z9/RjbhamW1s0UFRGh3voQMypU5RcYfYUA5KVg0BiVKFaiZBZKLo213hKbrgE2KoqVDEmIBFmwsu/S3EDzUY22tTB+o8ZKQiYesAUafGtnvsOLa+h6weF1ZvQVBerbD3fhb2o+d4ZyPkoRAsop+5it0QxsWuZL+J2oWybaikxIP/1ZM2ow4QZLaAVqihyHxqhF5UxZ9zrWxfp34BIPzzU9esSifrD0gXZ3mwutaCukZoijnGODJZtFOy9Rl1gyS1IbpyRbwz5O/YRl4BsD2aOk4InajT13Sa1BLPblQcrau13aeg/IzQhcUJ6n7enkrqiJFTP8N1aFAuYv8ilu0V2ymIuCLUtc4cbo7KyA+gnHhZA+DjjrhG/izOyWtQY/WtDsqvo/6ILwFk37JDjHfkchPEVcdl9qT7goG/4zTGX+lx8UTKKZJjJhLjA',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:01:24 PDT 2007',
+ updateDate: 'Wed Mar 14 08:01:24 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:39 PST 2010',
+ currentVersion: '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b',
+ versions: {
+ '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b': {
+ header: '####',
+ data: 'sgq3FGcsnlbhTLetMa3TQQE6uFZv/JL6Awha1066IimKoAtQGbAr6E1+mxRmvJle91sL7oRfi6suvDanYHfAI+rrG6qCOtESn70ssS+aGFyO3XwFgypzG/Qa34bjxJ16Aqd93H8IdhzdtOxs2Qmou3CjyxbT7Cq+YW/fAo1WfctL4yE4GBNPWC5lfebxSmINlBY+zTjhv9Pf2aK6vL4p3obHl+zhz0YdKAMBwbDyCLa9tYvhGBnq/W6lFUsyZCPVJJP3bQCQww0TNCcLJLm+SYVSiC0NwCQJq+yNqDkWTvv41p5EDB06eOQ2VqC7l4i/JLE/ql9h9Z++gck74/Qs3ppdVdG7sTzWyPya4v3RW2OTc1awFRZipAX5Zd7I97dyw6Yym4y+/9UT8z8iMDYykQ4+QnOhksDIE9a8q6agDF/rbZ/BCRcMWbFylGTdudk26mu0GdPiuLDu',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:01:24 PDT 2007',
+ updateDate: 'Wed Mar 14 08:01:24 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:39 PST 2010'
+ }
+ }
+ },
+ '6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728': {
+ data: '3oUg1TD+Lu4ou06j/MddOTXDqRM+qSKD+6Iuzia1Hop1w7v/BXidqeoKJZQI2VY9oO9B70Nr3B3wDROF+ycy6Rq+FM/xqUGHKXn1lAaSc6Wgj6TLQ6eRF6YZKSPqTj7TDWyw/2pEWk4HjcT8drTrCaC02tzAXMhYWlYPQPW4fUdq4hawoHIdopUN3vafQuFjY47OhqXKav3bNao=',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 07:36:08 PDT 2007',
+ updateDate: 'Tue Apr 17 07:36:08 PDT 2007',
+ accessDate: 'Wed Feb 03 06:28:13 PST 2010',
+ currentVersion: 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc',
+ versions: {
+ 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc': {
+ header: '####',
+ data: 'fehYRMkg/wFj2t/aWu7szbXwrCyCDpjQN4UNck4/OiDlth70a2ve6ow5lAi2jgdlV9WiFrPejfa8dD0Z1g19jx+BBsuUYnBEKD0K+NapdJBBeI0We2nj9nYIij2dfZVx7cuvhy8sN6+DdylUQLsFHbga+Gi5hWcMuULT4GOAIy2WanSQL1RSR4ruA6zm/t+VVboEkkm7PPT+w3LuRl3wRaD4a8ZwYiSV/SzgWooFrh2S3YOUeshdaGCiYpTbXscsOxsCxc11i6wQGBqYSjksmtZDvEegdQdzCmxvq4jaVWJElYYS3av612nD5K/w7Zei6RccBiODBPATjrIczYg7HwmQxIM/6QI9/LQn0LP0yqRVUUtfzaODf0uWNpFzml9l/1lwXuBJyQFBp7H7Th46ekw9yEuPD00oZ+eXvKwbwfUU0JshT4hnEBtIjM8fH974PU0y95f0yLAJ1+M6DVXCxGsBix2aKJx9fuZP4KGpaXg6qCb/6327rph7MGomcrGPIiDjYwD/NTMdGluc55OZfGXtOZUaJCUM6nihqDwU7Ly1ZzYorgcvkX/t/0RNcOkFzGYNByp7mdcotyiHqCDKspqz9mEXAd7Noz3HO5GFpPqbRo7htDigGU1f7dvgbbfRoTz17Bt9Mw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 07:36:08 PDT 2007',
+ updateDate: 'Tue Apr 17 07:36:08 PDT 2007',
+ accessDate: 'Wed Feb 03 06:28:13 PST 2010'
+ }
+ }
+ },
+ '6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a': {
+ data: 'b2mcYUi59l434kGl7ij6dBu3063UL1dToMIu3Zsa9RV9RzeLKnezJhLKunqoAm7KwiJeqDo/REexHI1cshGYtHasVXXuyJfMx1grH7yhoWnkSRF4Sax6w5E5wnGkEpGJHOxXJ9rOjWHZ7yqCUUCB/dqLw4FwPOtRb/ynkBEYztEJA6EKGJuz0vrrTOsT8HMXtj/w6MEZ7qI3fPs=',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 10:12:44 PDT 2007',
+ updateDate: 'Mon Apr 02 10:12:44 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:40 PST 2010',
+ currentVersion: '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3',
+ versions: {
+ '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3': {
+ header: '####',
+ data: 'pZEWSdYIkrX8/r6OYmO0GEuKG9baUgn40Bmw7hXZBd/kfWuRjWsL4/pc5F5Ojrx+N0dxmQn5ZqKAzOOri29Rm4ruxnCbyK+oDsCDyMSnWy/VJcvystnDKzKmBRQVAOSEJtzEb3OtGzvqm0PQ1Dhx1YUAx7L6KlXysmG9h9+MjOcErRL9/1x1LZ33ytR+zK4LvTAb7gN5/9QgwysFyCkNP8bG4nyCzPMiUrBnP0odMTUvDkJDlY0Oia6VjGW6oNxnGIgA5fDraRrW4JH2oejQcrL7+X+jpCp05g==',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 10:12:44 PDT 2007',
+ updateDate: 'Mon Apr 02 10:12:44 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:40 PST 2010'
+ }
+ }
+ },
+ '6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18': {
+ data: 'jzjPgxRHApIJA/6hiY4XCtb5+eKzHlOeoiGwfVDvip95zU7ThHbdmxOUomeyCOZ3S1SGPT4lHvqZgfVG5m5RvH3JaAIa8EY1ZElRohoX3rETVPJzI/Ov5Rp3lZjtWlu5meNrcJz811HBHrtBuJxAmSjYcY3CCal+oC2zcK2fLZR/iOQ+69ONVFhdV9KiOqzNf8IisIa1sIgFopqsdHXiZ9oLe0a7Y56q+OplyU3A+TmxKLI+Qq+WkjvdMzZDDqzYH47me5niugYPdkQwN6WQUE0sK9QPs0uU4TOwqCwN9nPH/DoQ6oXWAu2+R4iCyt6ZjLNkClbps4s8Cwz6wfFQ+4T8bcldjveJenmrYwiUzxSd/4xa34yFVXVw2OD0n8yZhtvNFvfoPy+X9z+Y4f5HlM0qzL9zYya4KwWjFQzhOxFjni9JyGM2PJ1BctB+q1J+CHuhlVjUF0Y5zIS3zFTET8jjDGBZDWB+Ao9E8fUD+0OJJUdKJ4kUfn4ZUZUG20eLBjmJqWBGYZX7UFaPv8ksahoK26Ol6FnBE4KpPStQeDgXZDzGsiLlEsxHJLUFkNtAUXozw38bWWQvi2VIFtkw/ZViPIenmSNT14kUVWdrlKQC8x0+wECeh5ffv0i8UUw3v8QC2ZE7GV0OMl4ySlRCuDCfZ53YFoB3HIR1hSZMhHlHJDPUz8JOuXdHcUQaJeNrfWoC2KkKb0ZecBj9iXooDh9yGi0g7TS7eyhlz1LHpzEWB0CPsZqhNGMxmfFWur7v2hrYzoHQOeB19ZSmWzfUwd4dRpqMp0x1lZaF97jr+yyYhnuQvuO6lru15Pg6FqjzhsNiLtaqtyoaMiHZ9veZs04qZZ9Fn3U7HeJzjZSAssdLnvopXi363cXm9JqoClyV2OemnVoRwOZN2gdSZxGeOefKR7U+lrBAbJwViMnmT0Nd7AC8C1k34iEt8HJmpztXeOgX5CQpwUPENMCUPsookFbIh7e4aByllEQy0gBbxUz8JMIWYyw98hdASnZ4s8bQfSmiMM8Iw3YxCexKB62LYYJn1UY51NSnwCtwRep+NhaKDk2d6SLh9owxnFbjhw22RriPd5f1InJycjtpvMzWLavl/hDsjjj1kWpnCUBTM46LbERmjz+s4x7fSf2FhhguBT36elz69ivXoiXI+7p0E8f8HsSwm8sgN/AA5m1svsXsdWeZFUiWtAwLg0tI8YNHlazbvFCXfIC6Uhq9eDv04iqdZ3rn2c1rwSx336A7ySTBFdxOCJ46F7ShIhNKm2N+5Qf0K5B2L882fbwqiLsa64+X9aKvufKTsd11vyf19Zivg/Ze0FWoGC8D63Nh91k6Hu32RT+uAtJIjQIZxu9yXJM9lMaRA8ieER+ghrLHaGQqF9J3WmueER3UzU1midvTynOV6g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 11:09:05 PDT 2007',
+ updateDate: 'Wed Mar 14 11:09:05 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:42 PST 2010',
+ currentVersion: 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5',
+ versions: {
+ 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5': {
+ header: '####',
+ data: 'BbXNAy0GcKKyDPiwhP1Jk9mIi3uXMHQdhuxpDvoR2C3YITOUBpurxGhhvmCg+a9pS+fKJdZPxL2mPbJj6GfWTEsm7K/ECEjrVkSTHi6PTUUgYVbCumq9EHjUspos+7VrifZry3c73+qAvIKamvUlNB86TchMpOXVJIyx8UgRX+bdhrxk9ZCEVOiLCG1zGPX8IzmcxPmBRZFlHYqE4ibhl/CLEzWXZBYCofTusClhOh7YM/jBgvDt64W7aIN2y2KiKwmFySkFZdnOvbAb34tXVimwqjqWPvPwd6MujQeX1bmaDD7Y0kXac8CJxqasIezLo2WqzLUbEXdIHGilkaPT2ZKpKhKkpHJHFrV2lVuQJVqwPUr0Gf9qMKgVnsyU8kUfq9ox+fhH70+v7BQSjT7bxxDLs0UesQeL7G4SqvNet5hPI4GQEpOY8p5MUFReIBTRm72NQEU=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 11:09:05 PDT 2007',
+ updateDate: 'Wed Mar 14 11:09:05 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:42 PST 2010'
+ }
+ }
+ },
+ '6dadcd7ab23ece757d6990ce237bdebb68b2df0281c78cc1483d913318112162': {
+ data: 'u9H4/IGgoAZuCAc7IsjHXbWl9RlIcyWJQuF+upwUgeQ1asbr4SX0WtB5KIfcS91N2nCaNHbHJfr+fVAjZeo0rRd+6PGkmnMLwcluvanKN+5VnfG69Xp6Drs61xq7yxl+SD5AUiU77OcE7be2dRJC449CPA==',
+ version: '0.3',
+ creationDate: 'Mon Dec 14 02:33:48 PST 2009',
+ updateDate: 'Mon Dec 14 02:33:48 PST 2009',
+ accessDate: 'Tue Jan 05 01:38:43 PST 2010',
+ currentVersion: 'b5d9271386eb38764c1d80c2792eb985d47909f2e0dddd16047f1a6415b70508',
+ versions: {
+ 'b5d9271386eb38764c1d80c2792eb985d47909f2e0dddd16047f1a6415b70508': {
+ header: '####',
+ data: 'g84GdVAIChqt5x2dNYsVR52cAtNqtO9NBRf3ljXQymtSLYEKgIep0jkzRTlni9fj2Np/MJ1qQg0uGn3qyjukHC8t7n1L52q5OxkrF6ffuYAlP/E8+NQo4Bm3UxmGEsmD8mbH3kVCi8LOJx0ZGaE5SqwafO4GWz5j8YX+dOfuhz2pKdpU6NaSrkCb21RJN+vOmAs5LQ8TfCLc1hd9FPxU6w3H9ys+Y5D6K3XP1cP1PU5N3vTFeq+Yl7n15xOPTsO3e88vPFtINpVjrv8h+VRy1U63MOWXkrHWwdUPKIBWx3nqg+H3dDH+lONWvrfriIMJKlQGF6jzfJFBV6yMArbi6lBlgPMOFIo5Pt4DYkHQvon7JlSC3JbHCIA=',
+ version: '0.3',
+ creationDate: 'Mon Dec 14 02:33:48 PST 2009',
+ updateDate: 'Mon Dec 14 02:33:48 PST 2009',
+ accessDate: 'Tue Jan 05 01:38:43 PST 2010'
+ }
+ }
+ },
+ '8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39': {
+ data: 'pOMTY3PnUAbwMLDEYNJCMzp4iIA42YWr6gqoomg+P40e7LFUtbt/RQRelQwNIztyUSVLl0rilkZZkBUVvxrtTqvibKITCjJQGQIzvcb+Yl4mNosl2Rpp0xxMU03f1+G7eGbuCc5hJXYVAglhEYplaAPzHbRWXMY8iZXZPBuLVf5PN+rdpgAfkGeZ7Uf9RsQ9p/EglrWXYnTwXi3saUfzIjfvSHm5C+dXTY3FHpIc1YkjFrdVgMkhYQGV60JtZcwFtCEL2NpVljAbRgHoIXTOkzUvep4vxrtfBBWWMuAWEI06432gtnH6IQbrR6jOpwuMt7k/09qy/fARPHs3r4qTJ9r2uqWHJ7tjJw+IChQPC+3l5HcPpFURiw8LGAN1NyY1hUrF6N84RSn7AKS0bLa5qN++5lcjjxn/k8+JqmeUqN1/SYIbGwNnJeZ0vA8yvOxnD20iVADX5kOVqJDwXRPLaF6Oz9KkbOrmANCh+PmGw1i6PduB+FgAU4HViYCw5IGOUZ30Pm1NJofqfbhXvgzn7ey2+kUIAwDyOUpJ9fW+9jW/JU4rcawmzwBYN2V8apOoyc3wQJICm2984wIfVBpygCOZM0QDyVgNo57qKtYH3yMDQSkKvpEUmuhklMYhcV+4X5ggdqx7lYXO9IMDnFf2ZDiZyieTlOlRv/nNVecUB177Xpnq2e+X/ik2rCQWVrIymiV6ltr1DEv0krXKfvXGG/FMZHUmo3m+B5bG4xVhmt0GnHseqvY2Vrl9NksLgq3hTDOGSGIy5Nv8kfrd8B4/6Tavh0SumiyXnrTXyYXzCK9E7IqO/0KAln63VkcHsbOtS8mj1drN0YQ2KKaeIW+Yr3Gm0pbcODsgA6aFfz1itZVeovBqUklhXS+/Es8J8xOSvvSyD/TmlFjuErHa+wwNQvftosfwk9ZTt0eIJS5aLHdU2QsCjdfSy0DEPkk2siGhBX5ZhRzqyIAyXApSmy+e7PIqn/dDR51+D1ZHwoTQyTrd+F08jBWZgU/OvS8MRxNZSxQwsi7bcWZG+w0utrIDB8eSOMVBXI5XBeJb4h5Bzut18C1shGHeGkSJp04=',
+ version: '0.2',
+ creationDate: 'Mon Apr 30 16:10:17 PDT 2007',
+ updateDate: 'Mon Apr 30 16:13:27 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:42 PST 2010',
+ currentVersion: 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8',
+ versions: {
+ '8a032b53f7356e2d8b28665211abbe2cf1c79fd8eee4752e83cebdced1c19911': {
+ header: '####',
+ data: 'OXpNHHSkdsaD91hw2LER+9XKpf8+bh/O+OcLSgG/gAx228UpifOCD4HTAOs0C7IJ5zhAq1L9NjCGb1QWWTFErYEtDEBRBV4kogscP9HWPxYyZHxjwPI0wE7Ri2eD4Rma76Utb+xVnXWuT+vNb8eRUCK8Ur1rlhYafS0uzAYvVqHDNfZaICksxeVQojil/kSPZDMu8ASz5pMNFNCF4SlwDKPRrJJDbNZ62A3px59YJtsla91DGVyOLhb7VNRxEwnXyxENfP78yA6OjvQDc2KhKFUpHbZws54IolLK1I1mY/Z8BiDXPSnOa694Q1eZxy1Kx/jLINZUIPgGg1++YWITx213awOISdf7Oy0/dUpu10Vr1hgAqCVlDp0IuGK01CswRzEdLVpUk1DaGHuin1rryZx9vThUkEJgQQc3ivr8',
+ version: '0.2',
+ creationDate: 'Mon Apr 30 16:10:17 PDT 2007',
+ updateDate: 'Mon Apr 30 16:10:17 PDT 2007',
+ accessDate: 'Mon Apr 30 16:10:17 PDT 2007'
+ },
+ 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8': {
+ header: '####',
+ data: 'tvSUu+NPKHkwt/ZLXdLGdDm4jSxTEtJfsecdpjJ9UGN3Y2EBCmijU5i7q+hMfNDqBJ4/m5Ayju4zYDAKGp2pt8l1TFoDurITdFcV12jL8j3dc4TTD//uC6OtowRN+altgC1Xc0LsSvEPabjAlwfVC5xqirfm5t2mVmnFZ/GALkGLGxRJRduylT6goPwfunkVGwUdqMa3md+9mwYn2gm7CyC0lpcKX8AZ3B4Oa656yRa9m3Wjgb007TtorLIpZO2MzVwxcHBqqy7YpN+zpmZz6Md9VK3L4F724tuXXWnDeVzGxBO7aZVr62hwPMXM6ibCjUScsaS4f0chivA/tBJoyx7OqKhBxREGeGjpHTeLxyHcekbwXhXyeqxBuwG93yGKutUhGLVYcXwe8/+xSeaBGj/j2RWutKbNKG2yQyNPGj2cxJWsR4YfOQJTSOSWT3K6Mmf+r6hLhIo=',
+ version: '0.2',
+ creationDate: 'Mon Apr 30 16:13:27 PDT 2007',
+ updateDate: 'Mon Apr 30 16:13:27 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:42 PST 2010'
+ }
+ }
+ },
+ '9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291': {
+ data: 'xSjnJLMCEBBiOM2RxFm2EUCxMy9a2eexGsBj851cR/PsJlfG1lCh8HwD1i7HEWVFB2GBK9Pf+U7TpNSYsq9VY+AzBNz4p1aSg3Hswoou4OpCCgnBpeNLkr0q7KBmSVmSH+omECgWzbqux3LiqT7yEWxemVRA4ah4a09DvhB9bpVJiteBGg==',
+ version: '0.3',
+ creationDate: 'Wed Mar 21 08:29:06 PDT 2007',
+ updateDate: 'Sun Oct 04 14:06:08 PDT 2009',
+ accessDate: 'Tue Jan 05 01:38:39 PST 2010',
+ currentVersion: 'a999c255e435e85633f136d0464f29e6d41f87f46e6fb50ca63adeede9a6650a',
+ versions: {
+ '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7': {
+ header: '####',
+ data: '7wg/yWfSasUjJKV/5ygFfteazVSdqEJ8xGAqtS7m/W2q3rOR+2fr99Il2TzxXCnOe5zV+iir2tOqPQt6BCGbVf0NVwZtvfO/lvfMc7DIwyWuhZ0sS44LBTD9VY9fruuIegktVHSNBoJTCIfAHN/ut1iB80+51An+TdpYT3SGAVM4RdenQ9IdvDOnQo2KE0E7BzHekga800VJrbqI8aJEtmm5mOjte2xHYSPFDCtwURQclwxbNv32hAY/IUkaejqg93WGIzHIIK0+SSDzQwHYQo4yzVGCKKy75eghpvGyg1zbzlv372bND+OuA3laocARFfe4rRd5I5nh8vmSJ+vybh3EIJJzloD+qWk6hsEagkYI0RYu9I2uOfA8drmZ02GV5/ySDsBHX7uhaTPGx4J22rNJoj8s1L7UoaohUHFvUerBvQTir2LPbzqT+B07wZOU0ibtHlaN5C2XMKRxfvGATeR+2J3l7WisCIoRdpQcPFHA7nlTTShBiCVstLxolvd7MMzPOilsi3ecxXLQSeWara4JILqXQCJ4yLbQCMnSpIrZ3TXbwbPZ8fjKjogHNUaBPnmd1hWoc7IVvK9RSFBEdCh9U/hbyPMCiSjdsUCTclmhFmhiVIlB73IyWixmLwHSWSl/ckMxcUK6rB0IPuWcT8iJkxfqOziFhMvC/cNydpN5Nj4WX21c/1M7lVlX10FRx6NIYH5szEXULmLnkfEwr35G9mKJwR2pgZ272UiW2cH64/+M+Kh7XnPbQKxTwVR3FOhR/qdSHeA8MTc9FDslFaTT6YSeJEPoQiLg4c4UdbB7w5nA0o4qg82hiiJbTfT2zFHZeeWOpVO1z4V8SidJrQkh8aL1/Is7KaDVNfL+Lx73gfO6tdSviCJJhD29iTgn+MW4MlGwpeLKpvq+LkXNXi/CVjIa1VqtR/Flk2BqwT2hccgw6E1ML+QdW1n3TvTtdLIvSGheOM5kLdnF76e8Nj0kHDFbnxQMlO7lutngaNBRAvhvSLccT76TMG4OTxNZk5aOre6AIOuUfrFD3KDeOqWie5zpkvTOd/JK/JDFYgbYQh8AqhwJ7VWUH49vfd6AqfwHwdNWymI05F6/0Co4xoQ6qN+iYNConUXz78Uo7AraJuBDQ3a24+wL2mLjnc8jUDFUaAKM6gZUv9+bx1vk6zVdaZcuqgZc6dcyo5Oy8lmbJ/SmRb8BF/Q2nW3SDv77R+p0bKPLmjcytczlMNct58Q1LoiLnGck5v0wByQ0XIMd',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 08:29:06 PDT 2007',
+ updateDate: 'Wed Mar 21 08:29:06 PDT 2007',
+ accessDate: 'Sun Oct 04 14:05:49 PDT 2009'
+ },
+ 'a999c255e435e85633f136d0464f29e6d41f87f46e6fb50ca63adeede9a6650a': {
+ header: '####',
+ data: 'xw9i2USOB2xkgG3MBp1+qq9e2nwapnEt0usRAVmUWXcGGLbXJi+ImdrFNGPg3TSZrTIXMdEbLmjxAcxpTWlBfd5NhBVDzY2q/stiNaUWfI8JAHdl7E2CQRHa9quVnxPzYytVbUP01xoUokBWKQnqHZduADt7OKcgLy5iheR0ECoFXT6lKcJtD8mV5TZqKlYHkhNR8FehkNrhX2BWfxDHtlxZQNOK6xBCHF9YQGk3PQqmeIAbvxMiN2sGCdH4pXAURHIcF4uayV96bmCa42r+i4h2p46BcNghSR84ipC6Fyh1y+oGyZ5GqaolmVQcZQ5UbCba57+r5OOSWqmpmbhyoZ8rPOa/ZYFiZDj9UqNl7Ny6fB7PqWjVs9oSLb3oLe3oqfrONvJ/WmttA5J/jztDYYN0peN4AAEiNQLnFZuoHp4S+Wxuf0c+99N+I0egIIgIw88+ssowwMY6Xrf6sxEmA7B6hXB5V7TO3J1DGkVr4Kw6NgxMrFVw1AlqNpBrxKdREYaGRmLwB8/jOC9tr2RzP6SPylXzeOk9/v3XikG0CZckPATqLG2otmZ0pVpJc5XwyKKhDAZWYEzPKXXZoLfdNoa4SAiGF7/otBtH8k1D8d2rDMlhigIjtYR8WvBxCdfvnFeD8w0zewymA1Fbj72Dv8eHtnnNYYsJiHldQimSgcaGkmyFr0oVPo/skLjRjBsQVbiE066eTAjqrcAfKK7pg295Mhgo1aU9cyFPfOha1yiM6BKulihLTMbCr2+KTdMGagVnBxKFmfWJBNbl1J/b5ztazo3A4rIOddUPmGj0uQpaOVLDaFIVvs+3d13JB3iyYOz1nAYlOptS0yzNEMlJMDX4F5gkABGFazoPPQ7PgQ5JUmRrO4BBnp4HvJHNY0Ix9LOUfaLcp/533C43fHTcofB0AVqpdnU2R4lPl9FkUsyeQ1vmY3Z7tE0ZNbM3rE1P26LlEfXg9xbSBzRwS5EOxZF2ZJv9h9a8VPPbMnEUt0dZrXhyUycHF4SfnKLmepZkHTnco64kY9Mc0vJzy5gPCF7z6SDzeA35SX2T25Rl6M+xKSeU1vCv5kPWDpacFhXX/aVJnSlgjYKEWzV4jTGdlg2RA+034JpbsJgDTIqdLYdC44EyZwocR7MObXf0OTprugDIM9AGHFlxPda+TO6Cg0mI7UMYEP/D7AU=',
+ version: '0.3',
+ previousVersion: '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7',
+ previousVersionKey: 'tVHT9HgAaAzSOMZrMyvyTvuJW6P6cSGU0lUWky8NCtKipfN1BPGcX3sVgEf/PTXwKlNxTgpogRDGhDMIl01RHPaqAIXY+W4x/u3bdH/c2NTlJg==',
+ creationDate: 'Sun Oct 04 14:06:08 PDT 2009',
+ updateDate: 'Sun Oct 04 14:06:08 PDT 2009',
+ accessDate: 'Tue Jan 05 01:38:39 PST 2010'
+ }
+ }
+ },
+ 'c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065': {
+ data: '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',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 03:45:43 PST 2009',
+ updateDate: 'Thu Feb 12 03:54:37 PST 2009',
+ accessDate: 'Tue Jan 05 01:38:39 PST 2010',
+ currentVersion: '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a',
+ versions: {
+ '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a': {
+ header: '####',
+ data: '/mnLRePyLGwPaZ+EkbTRHdE4jz4gY99jnHcIp7AeMfcktEpPmUVNWLwGSJUH3ANP/cO1znxACVQPzC+g8IVIK0muJ/lZ4Iw+HkpsfPtBjPZc+bfhsY5Mud00YBsImleIMlbbJGv3l79eSPcea49OwG30xro6b6I0KK3BmSgr+BG2AmBrKVlFRTPFCHRbO+hG/LgW/xqYgwd9f1dnbeVYCm5lA2zdAnwmMwlUIi/J73MbnsSO0Qg858iF1SPQ2Ne9Q8SCyKKEZwBY/YeSgDzoO76Wvqbzk8uPdmZldaF4zql3ffBeb9ZS9KIyyk2vJcLk7c3DUc65vaT+w25+2GSpEXD4YIV6VSr6Brz4w4gzcDMeLve0U6oruqWijz3CDe40yhd4mMt6wTVs4xo0KHc6yKjTuC1ZUQwZvuCiS8T5czaGpc0+fLyfuE+pVBxTlpOjkoZqzk6NsH5lcKMzB1TCscJ8fbOdtJso7DRUvijIE5+ayY9IktZhMeHsk2zurKV95A==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 03:54:37 PST 2009',
+ updateDate: 'Thu Feb 12 03:54:37 PST 2009',
+ accessDate: 'Tue Jan 05 01:38:39 PST 2010'
+ },
+ '4ebfe3bec6d419d61eb68a1f25407824e404e3439c23fccde1ac19225b40cb06': {
+ header: '####',
+ data: '6VvjRN9LKi7tt/HsgqmU0bUdZQNVjVAYNLdCrfKdRJCx3W/GZHHR/AQF0FcvuXIn0MWMUypHpTZW86V459OEoV4W18HXEisQKEiqBnUCBaxBd1NKZDpYsThISXXOhZSbXylbLoB+kBaYzT+Fc7utDheVvVPeMo+iEb3ih42B3En3ZXcgUAdEjfbRUm6st9Jiaz4onwXWknVhkF5QewA0GXDhT2JdakFxfUDay75wKvspq5IszbEYwsu+TEgsbuO4/R/bktgsQUrbhtKIEIiNSccDNx1JkUKvIxrRfp1m0Ar3XJsDfv7YSJSLdyVheOEdIpBkeZ40LN83uzGRMZw1bQsKf+XOFTfacYZBBzwVj8e1rJC6AWlH6Fbn0jXw3JcEljA4zUh5IrYhWtyIZW338UVsMSIp91USeM4uCvPsOLAdyCXiWu5H8MMYGz1rJxVlTbMiq0tn1w1f+CL14v8EiUft7l8kfZzBZzdLvzdedD/wHQ==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 03:45:43 PST 2009',
+ updateDate: 'Thu Feb 12 03:45:43 PST 2009',
+ accessDate: 'Thu Feb 12 03:45:43 PST 2009'
+ },
+ '7ef137cf242e00136e57ddd262edfe6b418b6f57f3b5e5e15f3ec1232867f6c8': {
+ header: '####',
+ data: 'N5eWFfsQGHR1WytyXuVySzJ3zenJEB6IaKr2vgWRHTlJFzexXzJmSLoozTP9Z4TumDOLsNrp+EUeIa3Yo+RqSyQKQRFDHXlUYa6c9PPLPXdexSA9JO3AHzMSpL6K0E4gN3BybjL2rbcQwUqJLvCKy44OdiJvORGfIIpTPx2LQ1o4P+chcpOwwe/ZhgLWmNC6FmkTvsU/xJlNuApyD7tPX7Cj3lP8WBfYEPr68BqTKAa9cxai6ZF4BRC//rFob/4pQNHE+7qjOSY9HOnV5uCtZehPYBwfpBiDYhaxWJxXN6sxtpe7GC5CM7gAAHs5lgVaFSWffOAL3zeX7I4vh3j1nYdXoh5KowZJVVUUfhwqJo2T3YDVsaXNibZIaPd9GlbeBBk2HL6c/ao6B8QNwRU7GvMHAdJKta2I9mtU2NCnr0Uwi4rZRR05V4k0HIMLEJxRo/IYAysAYETNIAXzk0twIokOF5JPjP4uTXRZ8LdiS6JqfoUu3Jv/7yq8wrKZM7DaQA==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 03:47:39 PST 2009',
+ updateDate: 'Thu Feb 12 03:47:39 PST 2009',
+ accessDate: 'Thu Feb 12 03:47:39 PST 2009'
+ }
+ }
+ },
+ 'ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c': {
+ data: 'zbQlGR1fT8HoH6KvOPBoaIjMUsVMh8MSNIzPO2muIMJDVfXB2rEcPnIFl8fNv9BtE9OLecuex3BQVJKGXdVGFYVNiSS0SgPoEpyD6GJntEIOaB7GnhVflTm8fT7Ba8ArS4r+fIL32Jx9F8sYrL6jKPWeuImGHK+x3X32uORI6znkRac7J727TiTPlbj03X/Fj3Of6Bp9Wa4xbVMwzi+R6NRKD4A6Za3mqhoSpYFeHWld8+ChJU/w2wFkj292OjPBzvvz/SR2Zth+AXTChreQ3Zl1hWNGmU2Ep8ijFCYwcamgPkQwh4vBk9NJlzIgadORcb/0EPDxn638VNA0dbpW8MZUCIMWVe3A8VgdllWxei7dDy1ri6xsKlFovLYjRRPXgAqRSqVATqwyXqhBWhoV6VZ5NaSUGvM8okC2GQSweLuz29py0F987MISmLjav4gdvcMA1wn7FOIaFTNg7oy2CxZefGhHT3sHfX/PIvs/ovfj+7TewI0k+HR414az2D5reo7S5I4+roCm1QLVpPNcXUxbAmEbjF8JCsTtECZ4kdpG39dN6BaMlHoHSN3wu05uTSn+sL7g3Cg0pVLlnHo9baw3fUnVJp3MCEgZJELaiI/WF1Om2y2S9UeLur18z5T7hHFv3Px28D7c22HEDdF2CObeh2uOlZGAa06lp7YlYeoNtb4CqLlZAMK0xIHfNUceC4OMNvqyGswd5WJsYQEnMry20OkxY6YinnQfjAml54B6WlvNVlg/YaKjw5AVinUHjzEFfQbcBFnFGpqg5qJk9hZmb1VI6Ujhq73fPydSfkvfScTImqxCNPD/BR8ovoaJtNpE2gmcoX9A5zhZgu5xUnUnXoaQu0l7K9kWof/UmCCl0O1A6j41aebWr+aoFMalaOPzNJ02vfLuW155IwjFQvRuAp6EuktZ2dFKyFl3QnLbwsMnitReXMoW30cqTYg7ODQnopE73RIb41Nj07qdx6FQMzw4gAIEFBe1iRvlMHQazZCb2ndVvgtK3ZcPNtDoahuPRxMLaKZlRnpa8E5F4o8NHYNivshawZi36Hk6w0dOimCiuk/zvJ1mtx8hhX7B5dsXlNcKxLSvI1onEm2x9HL318xJeT0y29alzPYVFuQs5kq1+UV3h2hL4E/H8h+5mWtTLf/MjaTZ09okW/etuHFFjCmLoKwugk70z2yLWEJGmbjw',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:51:17 PDT 2007',
+ updateDate: 'Wed Apr 25 02:14:05 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:39 PST 2010',
+ currentVersion: '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926',
+ versions: {
+ '3895963f82854530ff754c8e2d1eaef8d884a8cba7cd058b8b7adcdc12be3da8': {
+ header: '####',
+ data: 'rXmjQYZgxv9jpFus3T/qa9Qc1lxt+mDF+dmZeDmDG3IiE/LnonGt2MqL+YlbFzisF99Uv0IQGOZCPigtBwOXB9m6R6R3lEy/YhD/C6b10s80OBj3yr3PoTsoTmbnmZMYd4r+qx8SaoLLkR0aK6NADYZXebR5QgVtwF/a01EifI6YxH1wm1RX3kyRhIrMzOtL8zHbstPvW4sRtv2YpZqlZqBTdoiqztDUZTKEcCcU5QLnHYMNAVpDHE7D9WvQy8Il1taAbxg97Ir+2ktZLjqfJdKhU7ZLv8fcJiRgnQKPqDWcqpjA+CXM6Ak1HCf9SRJh6Hl64+fk3jEVAPmHvry/xq2RPCG2YnVNWZ+uL3QNuH4zt+IbP4FnrxkCAprmEiNwvuEefMgliGRd+FowIaiFWXcEtYxxQvRDujZN6eoTUU0KVnuy85PKi3ih0ZECoDM88MFhztwCG9/nJQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 07:51:17 PDT 2007',
+ updateDate: 'Wed Mar 14 07:51:17 PDT 2007',
+ accessDate: 'Wed Apr 25 01:37:27 PDT 2007'
+ },
+ '5311936f6a95cf123007ef867388adb5c1ec5b2cf1173d66e501daa16488e42e': {
+ header: '####',
+ data: '+VirbcZ59SiN9UJKrQkjQx0Z4avHIhvw12Hq7fs+Qnoz4RgCS17fqzYyJe+jYorjlMPjzUcALYOTobqJJp4Sp8v5nOilHW64Gny2XRp59PQPg0zE4TP22l1PzK04+qJusR5NLPU39hYbW+InkDapdIhdf+nIruqeA311bRLg90A8xmpzio6PkZxXmhZMabbEVfXsYFBQKVBFloTMusBG2eaxTjeK0hOAk0uEc9RGOEwCOvZvjRFCP8DyZ5T6QV1pYYgBFBwSFrB/koXmBmObj8zscJXQ4H4UWC0yw1B3ABbhNX7vC9q+vgZTxnGqI6GvzLcrzaXKTEyfa9twq+vKFX1hqDmM0UVLw0dPOy0/3tabJjFrYbz5EEKVin9UqWhuy5YIvHEJlMkH190Zo+lPMuHvD8TiAU1M/n1bTQSBQb/8STD6uqefbKS/s/bXcS+bdVKBmSgCuutBznYO',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 01:39:26 PDT 2007',
+ updateDate: 'Wed Apr 25 01:39:26 PDT 2007',
+ accessDate: 'Wed Apr 25 01:39:26 PDT 2007'
+ },
+ '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926': {
+ header: '####',
+ data: 'P1LfM+8PA/kyelFsojabLfBW9D0Aey5qDClz0OTdSamMT2Mv1U35eKcr6ilUrbtW+dKJotAzs3B1dYGzaEQ1j9HnhiL2pk4wgT1JWGe5c9frmFX/3YGO63c2ngnaC/Rrv3LC251cLVS1aoWNPskWkjZLzF7EiWbAeNYTplSa6MWm2LdHAm6xq2dcgYx53RJVvjnsCzpghQdzL96G8ScJjnUx8FC8mHW4Ds0rkHTeoM344Ao8J3o1XwoFqFFJ2X8+lSkj8LVVdjff1EHIicjrMM0oJG8VyxK2TxMvg4mnLWP4ALfh24Wrb9XmrM0NjhQXBo07tL9dwa7sHHKiBrM74644vBR7NB0+Laedg8D+6FmgNoR6icB+qvxCIIvAhOpJ0er9f0CGDDS06knx/lDtVVNewzxx4ATuG0HQn8M61eU83EfbKWG4Mg+9jtRcW0/bdFW/FQr/OeKg',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 02:14:05 PDT 2007',
+ updateDate: 'Wed Apr 25 02:14:05 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:39 PST 2010'
+ },
+ '5c622bec0fb939da012beb98a858a4e16bd670b3e6fe1f7c92a247f88a65c747': {
+ header: '####',
+ data: 'XGlplDTD1xamZO04H6RiqcLd7XaPwxI3MqpKTCVHPBoMEkwE4A1izGjFKdPqHbQIuYYcT9xDgPOknlkP89jDTfcR4UfENtKHFgFaMee4orSER+MhldJRxMwPLorZmMNNZzVmTmwJS7FI9jYiXEvDbcyw41kN+SA0mxzWpc9emaX4TmZHzlBpY2zXKJLyN3otYYzcTWzuu7DJejWrB+CnNp925X9vVomBPfp/Gt4tiOFsE2ZyEf1B/7cDmMszlQgEgGJONS+C8Qyr+X3GEh5iPoYsGpMNmF7aYnZNciE/B5lP/ABVbZIi2KfmRlSf7Cc+kMkUXyHxOeZHuVv1ZlzfIe3gXlD0/yUJFHNju8ai+F3hpSkhMatf71mLQzD5oFrTmKatH+zQZhGPP9dQxG1cgZRcjbyUQJMazo+0TJuNXNndi/oiRzRJjYRUbZKsfRzIAEU=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 01:51:49 PDT 2007',
+ updateDate: 'Wed Apr 25 01:51:49 PDT 2007',
+ accessDate: 'Wed Apr 25 01:51:49 PDT 2007'
+ },
+ 'bad48f8ab053804a02bec678db01baf24de35ef04a17b90e1362e67fa352e4a4': {
+ header: '####',
+ data: 'SXl3D4C5Yt81L/117xsHYjZxT/fANq09VZsMNAz3Gcn2+2gopG+1K0JFg/1Mbjt4EMbe5Or42zBlJPo5EAldAfWu4MoTkQzo/wKPzgOWlIi3A9QwZegw3yCuHvJv8iNcpjGfpY0OCzTZKNomTtwc75l+8FqgwPDW4wDkPG98275ERDR8mFSZfUAiQxlTnCbskFneUQ6hdN2gywkyJKuTEcrMkIpzwe9uqPaQg8GjUvvy162/LVaSQAVRIiTbW5URCD+hT5cKOkmFeBejHar8zR3SQQ+tIJlKERBwfE0sNR+RebSboYxWPECYPp0DMj30FnHbfYIVTgRCIlepy2hfis0+9C7dop0jK2nFREjcxSIqonF+juCrfJDt4cTlpn2SmcoMJQsUOedSh6ZoWweXm7lu8buCbA2Q6SY1L6jz7okwIikIinxGDq3qT1pWSgpntI8wvYZ8RD0umJsoAzPYH9zlfQ==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 02:01:21 PDT 2007',
+ updateDate: 'Wed Apr 25 02:01:21 PDT 2007',
+ accessDate: 'Wed Apr 25 02:01:21 PDT 2007'
+ },
+ 'c03d1fcf5b6981741f5d4787315534641c61daee9aa3c063540fbb704989ded6': {
+ header: '####',
+ data: 'sbn5IDJM7VtYov3sqW9+/0USxZEw2xq8di1XVPMMZ6kN6oZZrAY7ukxXHYh+mfuIa1/uV4i4v1YCaKZQShLgUS4cchlK4nnNVL8zejGwB+PaY0E8Um/Jg6E4UAFAZ+haZwzWLQS8lJ1r4hNMTeFqsDRUhC30awJRz8e0rBejLZiS2Hk/jgpH3i8Za1GwDzogw11iHXejYI7MaQGB0E9eQsYYTxGjmzcLfVYkd4AKj5pSEHvsKZklSuWIyDzwaFiIO7xqcJmS/8Wkm63JGNOW3nLR5Ao9V/2vthFHBqS2lQNRnkPWXbmNK3v7vi57zu461w1Nn1U/70EvhHRMk8BdML3XI/U6WgDARjQuVsB8FnTkzapaORG5vUd7nTtWjPdyQzOqacm2YKWpAiG6fUQTZiBusEd8jdnv8BioGUTbXgNVG23zcRbbbEdjKc1aizXHQE1LnROvoHZHkwg=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 01:59:57 PDT 2007',
+ updateDate: 'Wed Apr 25 01:59:57 PDT 2007',
+ accessDate: 'Wed Apr 25 01:59:57 PDT 2007'
+ },
+ 'dbc283f49de6e303c06a52725b8187f344ba7b433b0158d704f094edba782710': {
+ header: '####',
+ data: 'fbNrpIoYF+gpMUjSxoOc9Y68qRlE2yk7FPPkrHTu07HHWkAWy7H7nFw4BwGiFViMkyEC2orUrMeDYhKmMYFj8DEcALk6452BtNutGZSoqDhD8xnSEPF6fP2Xyy+vZHp4JWDXZt/xHk4vPbxcwTTlmRz5aO8ChXIH5iqfRL9+Dx+gJDKgKmCRMZYMT1pyOUewmsT6QDYdGFJTRRiDmoLfCVAXhJRtqQSBcx3kN3kuf8gyOMAeJnFGISTAj7THzo7eGuQol1omTMgGbDZoL7WJNfZIDamiT9TWwzp3UmQcKIsRvA2ZKtePWRmpWyq6WydJgFXHUuUDVpwT+kc1Rn9Wq2zwm1VBw6gqKCp6W9bZO86rRMs2CtuLT+agSpqb4kz4SEYDCW0+aUsJDCYBXx5yWRM26r0XAbU6X0D+xopGuaVzsV5G7chkCO8mUsjHzZCK7hOAz6OgjR2+',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 01:38:17 PDT 2007',
+ updateDate: 'Wed Apr 25 01:38:17 PDT 2007',
+ accessDate: 'Wed Apr 25 01:38:17 PDT 2007'
+ },
+ 'ec525dd942f72b71b5fa1aca0a36a9960b71608bb27f32bc7923713bde021b12': {
+ header: '####',
+ data: 'AHP4MFiGukFCCnjLDGoqJUDEr6QNL+KoZlcwOqJIYusRtl5qmhZSsODHbAEpmadxLGogDPrWoH5/XLZ85ASGRF5ALzDgrFKP47/bSEzKVTDABY5BJSqvKgS/lCf2LdR7+0HWUVJ6Z3GOb9GqsXC70pMxDo/RfclOQPa+k/sXCW5u0TmLb/0i/dZEM8N++4umXsyy2WPLtUVzQZ/VdTMDwl50FeQxu3aNGy4qYd4XFk/7gxBH9skBD6/GqpNajHJrcbi/WZt7PZiN9skoVZHhm3YLmteP5hJnrcCGBFJHWuQpXfB7NR8rNmd2c6maemKYmUlX25wQF7JPcROOcyT8iYpF4Hk/eSPs0CSkaDdqSD0Nj9E4kqZrHfVGMwBbDFyAzdHTN3EyGuC4cBXdfNZbdBqwghuB1x7RLXs/pbXg1xqukjRdPLTxUogPdaQBHGo=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 01:56:58 PDT 2007',
+ updateDate: 'Wed Apr 25 01:56:58 PDT 2007',
+ accessDate: 'Wed Apr 25 01:56:58 PDT 2007'
+ },
+ 'fda6581f0137dd641387a7be193b06edea4451835817bcda38d22ee24ebeb77c': {
+ header: '####',
+ data: 'QwDMobl0Kds+J8mknphumnONOIF9gH+pC/AJpxGmuy/rvKfHSeEuuWAZ/yWj8J/I4V7OjpyTs9/uCWeKs9khpdkcxtObB36IfcbWBHGOgFjvqKgwMa7eZSIUPZz9k1NsqJC9nU9U7w5EBzQKVIjJaey1EdhsggdtNOpQTzt7iu2mWKo33dJKQCQ5VEwhpGh6SH1TgKFbdMkOJJY8d5xPYUxR66LVFpFzgHP0ML5M5U53PK+apT95UIAlqf7N32BjPK63Nsj1WPsnuuL0vWA3KmefHzwKGeatTdsgck+1mwnCDJncPWv7hTwMLGPUaY+Yww3K3YPihuyCUtUdV3fer2VHVAn++JdzerHiLI/86T8gHiLAi/anFFh6i2kMMVxqzREh+62n34MrgdMqbSFQb0V4Dhm45FVJH43uuEaoe3OJPtyvj1HbcSR4VEVgGkDeced8aAK+Dg==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 01:58:33 PDT 2007',
+ updateDate: 'Wed Apr 25 01:58:33 PDT 2007',
+ accessDate: 'Wed Apr 25 01:58:33 PDT 2007'
+ }
+ }
+ },
+ 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:06:54 PDT 2007',
+ updateDate: 'Tue Apr 17 10:23:41 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:42 PST 2010',
+ currentVersion: 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf',
+ versions: {
+ '12bd9887eb84b99ad40c1e413cccaa9ffd4deed340c71fe53610088faff349bd': {
+ header: '####',
+ data: 'MiAIw+S6GDmLLMcGtkl+wveV7dZAFrL1zGZh/FPvG4kpOBbnyaolRynNrL1yeUbEp4gLL2cK2BGYiVc9196PMOvKPHR5Rqp6GlT6h4RUJ+nFFF5/3LNGzQtJbiY0rrYKptqyPBC8mhlqtdK7sQkQonj5LPhKeCX6AyE3juBPEuFYhvTv9a/iRPub7BdlAocz+bb8ObpbVHnNvbGhiRpx9MpUg44JRxLQYhtDUMi2UFtURidKaK0k2lP81ckPDCgVgxy65FjCq05vSaCW0hanNrIwl+zAgi+3ChriqmflvsZYC7TQzUBPXrAQ8bKmzppZWlArIOppRF7+paWrHA3Qcz4uO5Sw3DvMwbgl+XINnmkE/EbA6VJOjrWYJjsibvbCw6vNr4q1A4Yxwy0a7EXbjFiwpEr+jMUhsq8+d0DxP3tQTusV0l9wcT2OWrDRKdjDUXLQOV9BVw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 09:27:40 PDT 2007',
+ updateDate: 'Wed Mar 14 09:27:40 PDT 2007',
+ accessDate: 'Wed Mar 14 11:00:21 PDT 2007'
+ },
+ '35af99615d1be9d9841b4a37488fde9aac291c73c8c3aaa570cd05b3fd0baf5d': {
+ header: '####',
+ data: 'lv0pIfnhZZ6ktahFGl3AgAfdcveIcUyAh9x0iVOCzmQ9VjelBztlvxZEo+uByaFh1ptM+eqOFT/Vk9IKhNjRWTXrDXioP7oZ8IZ1kLfk/XuMFH9AgYzm3H1T/yLq5lg1WqqZ+OfO9m37Z4kbTjK9+adIAJ3TwsMxIDpIHYz+qbznjJocubYCbi+DC+4wo6qu5C44gf8n5QF8DOCGaBCyamxFvkqrSMo/Y+3SG3yt98MSgeMScGESuwKKGDHZX0v3ZXvl4UFbxywUtdbipDv4PAlzh0aadMsGqYwO8bPKEUElCWBXd6kASugaqiJaZFtb02EnC+nncv33ZSx+WyJqwKIBk/Kpd3/YDJnX9t3QU60j0YKf0my9oX1746F5u0XGX1DNRaw/1g95zRHoMu6j2cSTTX7CJglzIlTU8kglSO1LOasxm3Gt8iT+8+Lhh4Dw86ugqHXl',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:09:07 PDT 2007',
+ updateDate: 'Wed Mar 14 08:09:07 PDT 2007',
+ accessDate: 'Wed Mar 14 08:39:40 PDT 2007'
+ },
+ '7cc6c6f2eccd8bdefddca21a59669655d7515f440b025144b9ba6b18472cf189': {
+ header: '####',
+ data: '3W8FqWzBVaEbMZRukwXcm03WbvITt8WVKKuJlcSszN0dCJEsIZ9vLAiDp6dfsFF4PEPcSkiy9Ww4FiBYSg5OLW6snRNdA7Wo62dJ3lqn8TjBzv/Rt+khf9mj/WwJZZ4wum+qdwTRPyaoZcAWgA6PAPPVp85iDBP8UBdiFOs+y5kz9GiB3psvOvqC9LZ/RyK3J+H7ierfWecnbqB9LT5Yuhfi8SO/gw+5vve6z1v8sVcexI0o8gk97rDV1W2gZz2WNtO7K5+233Z7aZlzouEbDZEOGG+zEYh6SctWCspgUATElf8vZ29fABsk3uZQO2tnBvINChs6jCRxnbmnjb2Y9R8u2QRtHjjvRro9E+zhQf3laJc0G0ZJp1zN0wwKx+sL7uM6kG1aszNJkzpykR/Uz8bKvoOfG9vkz9+4Pczh5xR+k9rCE8nbu6Yt4EMiUfdfjZJHAhST',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 11:01:05 PDT 2007',
+ updateDate: 'Wed Mar 14 11:01:05 PDT 2007',
+ accessDate: 'Tue Apr 17 10:20:33 PDT 2007'
+ },
+ '95ef5754f9a4514e5bf883436d60c38c3cbb15c3f5452d512a05839ce20125ca': {
+ header: '####',
+ data: 'Rko0V7wG9GEmH9pZtXSfxKGDLRhZr65ef/DjkwhsPoYfLryET/ViMjcZcM2blyiLKOxjiS/avGGcXUmInz2AyD5dAFTGge3qAZ3QtxTcNn/fvfJeN+JyGJPIsTIQ7P+jd0uJAb3vPuymISGJluTsP0MZ8zxahSSRUV/VIYwm10tiMVvWEq0+8FynKfWDqJ1eU4pnI47CAdN9CuWhxi12RkMBYgiUzNzTh/tbPTFMc7DIyRfR+si6TuPS3PmtnKt4FMFAX3FznGBCNsonUFf/n7Zy+EYEU/B8wJO+18mqbui5YvmPCPPKiW/pfVuaWarF7zcIcthYoKQfTaCaulO0VRtTA+Wg2LtJv+QcWWWTiY2A9FC/PppLZ8+nFDeng6LqJYKoGnn6qwtSVH38s3Inzbs4r8mSOR099tqwfCnZc9zZHisdIbVm82H3gnqelPmc3IXb3nHb',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 09:17:20 PDT 2007',
+ updateDate: 'Wed Mar 14 09:17:20 PDT 2007',
+ accessDate: 'Wed Mar 14 09:22:06 PDT 2007'
+ },
+ 'cc7ee01d38e4f1de010d2a235e3b76e838ca05fe70223b8358a5e41975bf2b7b': {
+ header: '####',
+ data: 'TJ5ClYK5JmZvEuNCA+/UeUJQ2rGXbPnFqWP31GAGXqhZmC0RuDNjl3sv0nFKmcdMa/BzvLSywJhkidoRhfKGwN8nZc8M0VpujFkpvdXgNsod6x+5LTMP67qCyvD67pkYMa7O+aosKi/ZWWnYBavZSdhyuWnU1wPxxk+wwcjjIrA5Tm5zTXM/68nLLnIWs2bQbUtcwHgLrBEUshG5oTUFGxrs8zYwodsYUuT1CVwODZrzMxvvbHfH6Lqt94m4hBF0oIrDCd1cSaXghS4PiZkJWQVxJNSsuYF/4PlPrV4ATZS3Jm+DqOxLOOnU2Xu1Qe9DxBppnXjs/WpohYuMV5YeD8iOJLXTQbFKhBJNSCoLp73QywWazuKkasC6cbBrTHYykEKXpt74iE6oKg67YrPkIZJ/jKEGnZ7wsY4ObeDTS7OUbHKxPHRM3ZrmB672R/8ktglg',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:06:54 PDT 2007',
+ updateDate: 'Wed Mar 14 08:06:54 PDT 2007',
+ accessDate: 'Wed Mar 14 08:06:54 PDT 2007'
+ },
+ 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf': {
+ header: '####',
+ data: 'CiJDd/ShGw3rE0xCNZspkdH6hRzvSyaNiuQeMBI0NR1MReaa9uVMV6Ymj+BWVQ8FaOziQ94aolsWre51EKwDWC1otdovPXWHxBXBBI/Y5A4dyQisBeR5E456juUwDtLKX5En4iIuOL14IGt+keUtb5JyfBGuTTA+EnohYzvDxu9MDh/7nzCcWzUxh2zHEBSyowfOwJhx7G2xEvbBgTg+TkejMudbq9k3Owebe9QNdhU9rsY1UMxjL8+HgJmgyo0C0SA91tZXBB3i5ePvg++ze/SW/r+XO/nnVzcEwCJE2UWAL+vNh8tUm+sEbWaqyKwjHNSquxV4cYOG2Lzo45Wp/vZwiUR/8MK9THf0FO1mn3QCd/37AMMneI1Gqk0TNwNtoQKgLVBNhhgX7dIVpRxB2iiSBYyUK6N9LlFahW2QVDS7kdnKH3vk1cP50dj21E45jEhhd75v',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 10:23:41 PDT 2007',
+ updateDate: 'Tue Apr 17 10:23:41 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:42 PST 2010'
+ },
+ 'd65b23008b22e5000726db3fd22b074b08553fe82245c3526f708b8d89f70963': {
+ header: '####',
+ data: '0y9WhoXwZSfzfxuql8LBc5/RiclPKQxcBYjcdGv7v6B+WuGrB6uu6d8pjNoUtsZnFv/25sefW3ggVgDuI5iZNg2lBQVIwgcvK5jPM5foit49d3RSWl74XdHY2XqykRNDbboKAiNfro+abo/YYQXjkhNBOC0dWSUUw+HmgK/Bm5NmJD4fDTV7OYFsvX4ExjnX9pktaB6aiLZWN1cZruW3Lsszx/ryHpDtcPrmK2hgLQ4FjRSXunbqXKJLOADQiMbGZ8DKZchB5NcEWlE3AfL6ybJzTyr4jXuS7A9PyitxYNKFHAHpJEhxGkyuhUE66QMt1n9NKzkNx6yhhGdIUF2zVGsBUb/pRrL2gt0X2lsZ+CnWFu4jRAeSi3KfK4VrvnoYkVlJImxPiLrzJAvqkuA6TyQRpJ4yFVJ0dgxBoxZVSN1fp9Yvkph+Os8LZscJtpYPPwVDlCnC',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 10:22:08 PDT 2007',
+ updateDate: 'Tue Apr 17 10:22:08 PDT 2007',
+ accessDate: 'Tue Apr 17 10:22:08 PDT 2007'
+ }
+ }
+ },
+ 'd620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045': {
+ data: '+iiHiN91FfHKOXC8Z/tg+YynPECa5sgYGGofcoJeXt3FAAkAFu3NsLuwjYIaddJiB3MIxFccrCrB5eDDL0SzOS+j63GcoMCeeiXss9YfVunA4RQTTktiU1BknPYfsfHj8EOPDSVHkPFs7KhAnBlgyaDiQPjYko5Np1H2i7F7pRmfC8W5LGdisaqxFDa+1ghu8K6a54QIpbfOmolQU3w7T5qiOdoZv8GLDDoORvMMb4P09IzXpk/yDEZe1GJ4g1a9t+lHAhiKSvdnZf+MhK0jvs6R6ALlmO84lRP34DmT/35Fr5C7D6EJl0OxXkWgYWelTlfU4b8+SStYP5LPYeD38fodSmObpKmpp653T1v2yaTybI1hojgLbH2DuA5VcQAM5JHMjoSy6s76mf2AZZeRnej1dqdvIOTf1Q6CR+ZNIqnkukrtGq/6elF3eZZh1Ln1EZDiTzsMxUHBngtiRmRDofqRSJUGbEAjw90dBoiaIO/WwLAy4cTec0nJxwYd5M7nchEly8Cb+zz7naP+vEGEAWq991u9NFZhrw7WgNgHnG0E3km+X+SYvv0i2MkqjYs6ItDkBNyi0Udnc4CqfWuKa9q04t8mZiy49LU34Ho4/ijuez3rdOeCO/oIwkRkLZYfFO6IxO56tAI3d6iJqmXY+DX0YUZrJ6FT7bDsUj0umV1htuj/uEgQZyOnKOyA8cSjOTMRIkodI12HrtdrIA966BDznsKW4F7f31VaSxI5ezHsdiYEsTqwaZlFQMsjfZX62EvDLJksJTe3JG15BNgsDUUh1mqIDCmVswFTpUTTb+50ap56c/uERSET0iXP8mb4hKwJkmngrBEir3btuMEMS0xSFQ2jTRjlnWRQr9eZT2biarzgEhKHyu2qCUtsUj7TiieQJY09EXCP3g3Da+61nBMoAwi/VqTI6vQaLGtuDrA2+VYGc8x1SiahmAkRPpQS+5N9qPvxxFRbKforMOvmeboFVxdKesub7BHIXQsSOKsHFZnFHswa/oLBITomp3ewfp125RjBUf1C3hMBNg/tmE5pgLqPfQqWK7IOnfdyt0jc391XWb6H3CVcgC8DcPKJ68o7DBucg9xTNwlIxBTafupsBa9JUkBigqYOW8729lNjj/QTvTUaCxWub9SDT6/y1wQUI1wyyg+EaR0fHqumMhIMbuvIPd/SvKMmZ4TXtBc1U3H3IGbkqIfx0f5rI6AuNMD7/pXTAy2Ot1ZBohnQmEotXRvDwxPMqBvPU74t3USTrysyXfJqeFtHi8GTR5X0m/PYQKWCCHgKvjw3d1CJk7tTe3iV2ulk5cnO7tOydTMJFgPuT2oyDDDTp5jYJPRE0OzZcpAzvRSjELfJ111sFBOEzTqtBUHA/E4BnTIM13md0ZaMr33E7ii8rS7vaKrQAI5moonAtAEOVbx/ZrcZ3kGzHpRCISeteHgnM4I90x391HqDkc1A7b+iDQF8OY0H/0as/3gaVaqs5jsuhIByj0+KmoXsdq3ZBhEQRW151QDCdMKdulNUxbKTYV/t92z3slU6lO8fiy+ON/6sTtS6jgnM+oCLxTfpfBdz0uKG7jiSOyunj27QxNjLyu1nF2+mAcDhtMN18QkJGLXKYv39kx7ny1H74i5rba32/QEAFl5eLJNIQbJZfZG3HzKMVS19ZGwgsYNqV1G52x5+bZUTR8YcrLWmPTJ322UxlhTmyjQv+fVCnpksBtjLGntsGloemFF5YVlcl1AfyHb+KlXiAZn+8vpfVVBddFFMeehokzYE1G8Doa/3huhqdtC9qvAtpP54G2p3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:36:20 PDT 2007',
+ updateDate: 'Mon Jul 09 06:10:15 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:40 PST 2010',
+ currentVersion: '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130',
+ versions: {
+ '0bea892da673bf4b3d3e4e97cd3e1645eb177a8423dc761583b876c5ffb1e2ca': {
+ header: '####',
+ data: 'BmZz8j6Khuz7Q11xPA5zSECcqn7BOcMtLx8AmX2iE4OrIwKWcZ+u4B5kCBxtFPRZWLdWcxAF8VfaedkHx5jxPNeWNIa7NEXXcFLYQv9lwUaxmtqodYtVapAg7N+onw28UnV1vB/h7ll26u263jWYohtd5eMnXhEjIEbrQYpf84jQYlpMKjUDhsVQeZvTI/KfiXa6O38ygO9R+xlq8xKgPPX2bkXfPJiyzlA+GoLSORc0tdqseGGOK4BFyp1V/KRUQ/7uQmGs1yNWt/ijaQtJXpWkWXmjHyTjXsi0z+1s0KH8TwSOfu8yjVshMyIyEDd+EsmZeK0QwMCm96v311cRhMgAkQOqL8xc2uRpGygtTkV2frthF237GOV5vwO9IoMZQFlvKZreV5mPPPBeqfP+o4QRpdnJRRCaP8Ds/MmzGBqE13ntwmo1UVX1k408ZtMCO7h1eQVTgCZ/Y2RD',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:51:02 PDT 2007',
+ updateDate: 'Wed Mar 14 08:51:02 PDT 2007',
+ accessDate: 'Wed Mar 14 08:51:02 PDT 2007'
+ },
+ '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130': {
+ header: '####',
+ data: '++u0MEaILPK8riF0UzCnb+MnC51GYcdqCFRKOP7XYt5QvzWtxhDMOvq8ugCDF8G9sYPAoBLiCxFcuCtnkG4fp563VeEeC/dRnArzMDvjILYKAETgpnLQAfyIR+D8RfUkCbr+aOJ4XEKcy9a240OQJFDT0whoTKuX/6XVzVM/D7F0r+hJiOD1ELsVEi/+U+dXXO/VDxoyjFxfa1+M+Ygk8ewecX4nVqwOiFWHNK2lXW90inip0p8yqDsADx0KhE2tjARWVsjoNdf5RSUOYr0Sb0syyjBMi7oF4jpbLvHpu9fe8vpIcve+aSA/MF0Acxh0/gToDcO8ER3K4wcJgNPIs9lXiSrmuklK7kmS+uhz/rWCtZZH/OB/ov5sez5H51EYLmSNQbx5wZGZhtJWNN+AkJobg/Nt4XKRTe98CutbeiiYUGPxQvwG431Erg4y/q216n55FmCBIHZcUsa6Hk7ezF66c52EuAnVEkn7TZLl7vvym+sv9lKev31xpAGwX5Gy0tx2A7cSE55ZoyqOS9kf1s5Kwprx6RSBzfy7sffLSWHxyOSBnd7B1MNZglVSsbB1r4gMgZdYG//MZ/3IhTFbUqqw2xXHzTvBPA2Hl96g5Xzx0dVx2wHWcPcTSH23VrLscQCwyiDVINwmIzyG4CVSW/6gzA5VM4QYOrUDX2ZA5ligkZpWs0HTqmCB4SoqYJUpafaF2sEtCWHUjuVdw+rQiTBCcRTr8f1Vah2q2xbXMedLCRS3Vq4vlT0a/3wGgVD05CsAom31ZzmHQm94hZrx3FTPenhxLtTOHtDYXnbzYWufWEBSJs6VNtG9F5Md63NZvzEZiggfxTREDRZ7I9MBOPhrxz/3tAo+xInwvLXOEnTNOHVATm9u50kDs1qkJgqiXlxi9pZKmrTu4BeXS8cOxJ8O+Yb0Nh9bExfw+CC8X5xiWE58OwalxY2qlvuoR6mOqdcd+L7YPbGq+hJ/7WgJlrvtQe8IjGF1sJg6jfO8ZeGaPMF5NnbQVxGAq39g00on/z6dW0BLZyA6uglv99si8aRLpMk=',
+ version: '0.2',
+ creationDate: 'Mon Jul 09 06:10:15 PDT 2007',
+ updateDate: 'Mon Jul 09 06:10:15 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:40 PST 2010'
+ },
+ '63760358c7f5783d11fd769c78ca3f1ce787113368743655ade89bfa67d0d30a': {
+ header: '####',
+ data: '7lG/UvX5KjLbN+OrHbDeqXmweYeOL+0p3/UoLi2K93mCYdwsvx8mg+zghxwg5ITKPiZ9D/QWIShqiPpl+dvQJGWgs9EcP5W7k32CS2RNFaZ7U820rSpahHP561HDcBU1++5wHWszLnqFFiCuDja3OU90dsCTLI3g0igFgqpaRbjLcRTddI/1N48xNfV1YieC5Kei+jZ34zzrfKRn1f0F7mTkCqCSfygjnpRBgZyo9BfJ9rHULBvplvpslUUfFTShkLnCx0UbWPXog7DIZUCOwvPr3KJvmcZtCJp/1nW7gm0E5PaueJF10+ZlB6pKvueu+5yEgVmVu/lctmPX/UwTYZDgY5VWSWS3C+JNAvV87ZQKKmp8N6aMFMNOLCsOYL5hFN9uWGtMmvtgawqt7OhO9HukSUs8pDTgNeXoWyrorLM0cH2fa6a78GxNs3nCSUmqSQchJf5eWmASZgvI5xXmHXsNbuc4w5R9BaEPzyrrSAIa6r9D3rpFbUhMm+qPv9pZE2HF9liJVdWCBOSF8ZfCjsq5suyYz+YCsFHnwwpYmKAqJNXUMIhxkjgOTi5lNIsvS/iNSN9kdkeWINZk5iQFta34uJbGgjUhRy930ZGMBEV36T+Vb5tz50M6/MnlzAoUDeZAu54btKcrIpIq1Se+8zldwd6UKGq5nG+dMPk7CyKfZ5LkM065KGbgEJfHO651AMWp1sMAsbIAM6h1gVKbRjNyNwO+UK8eDpIX1nXHVj8bDVh96160cFbZj7htsUnXZh2AWuY6ahwdrGwYeSFoVAnd6xUF2oH+zFz2coLmLjD4Xm9IuQFsFO0U1Vo7EKUJHkPgIsXUT9He9tl8/K7UYQMXGgPTpercQFQ1ctFEqlPbFoVNO0j7Z9lmeSBcLdvY67CCbsoBDVJzj/wLRdBQStfeSUe7bEI6ff8+0gVkEFFACc48fWWA6NLLtvJkYjdojjA+C/Xf6EGNeXU/VENMJokB10EJUTueVWKHCLGI/JDBQBBB3HKX2VNFcEMJxES7Gfcbhysm5bdmltyRUJAIdXvw',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 04:56:43 PDT 2007',
+ updateDate: 'Wed Mar 21 04:56:43 PDT 2007',
+ accessDate: 'Wed Apr 25 00:59:58 PDT 2007'
+ },
+ '6e0dbb3c582039d985e80e10d94f424a63f0cb5b2ffac6388fd806ef89c1da40': {
+ header: '####',
+ data: 'f5hBUeedsvb1VBTpmpQ+XgGbnuVDMVEAdbEN7ZLK5k++4Iuw7l52zX6AHCWUFMDRfT6joiD2DMj0O8B2g55SeOQIAtZb4PZnbf3+ZEqKMOOI7iYSfo2PctLbzzzztma8EUXYkg7sJKCuZuyXhkWZxikBqVQIp9WE/bhRxa/atnB0jJyttnDMdTAN8kxIizrHFfT25hSbcPI1cSzsmF2nLabO6hLlm7mdLZCOD6DSv9hMeOXgqXo7XdfLA4k8swnOA/85HZFmhaYjTyoDGsK8yoJny/xBbiaRij1HQcHkbG6k2QKcs96pjmiJPoCv2dmsU3Bh06l1O4OEXl/RL4qBGJBKsDW/TXy7Qqa5y6LCEnlFAfefTHVgzuEQjJ2qb/z//oIrmujt+8hEa8F7Jyn6+FGqMNRxDvIQn5Ty/CPUStS1lNL1PEb7TA3ChYkYvnuhNVq8HHf47neGMpUwC5ppk5Zzb/5zEP0XH4XXkNbR5/TYjcb0Df3egNLSQLdO13CO3mKeoccmtfcmaFCtOLXWc2xNNcu09s+/QlZMuiu1TAzhWXU2CAXT7K794mTXHXjgGEaEe86Pj1nO1zHN7QhKDN92WMEdYasRAVDu/XYdzpsKJZ3POhNJp6pynotVBOkPk+2g04S8uujLVSIPZIwu7p3RmPQGGvfMviswhyPvSsPqND77j5msYOLCnXXjeXhOe0E7fIRpxPK1F6/N0R4tZCYNJe9Zo248XdqBvl5ZQWDC6aQH1E4djPK/08CS7/kAECqGqOCDPRvvMUNkGOnxsMx5eofr1YR7zWOZajr2GnfhA9fjrLv6KxXPVU0z702aS/Mfnf87ckGpOKA8/ssJiyZ4fzP6uN4pEb6wEta2DnnacUDd96nMvB9HvGCDoYZH646+n4oev+AnkYTy+ZRpmnsG6/3Z85iH3RwN6P2I3DWvGuN2e+1zQ2kaBMDms8qeXVY1+8qWr75ihizHCJr6E8Rd2Sw7xM0+6mKpu6gVGIi09auHg1+6Q6PlCr8Hy/pc4Exj9Hx1m14WKSF2SB1SYOnm',
+ version: '0.2',
+ creationDate: 'Sat May 19 02:26:44 PDT 2007',
+ updateDate: 'Sat May 19 02:26:44 PDT 2007',
+ accessDate: 'Mon Jul 09 06:08:39 PDT 2007'
+ },
+ '84f3b8571428014d04d7c05528af73c89cedf17e23b1f9541fe7060512f4c1a3': {
+ header: '####',
+ data: '2/zsq97zQBq8wE0oAC15HW5pbbzgokoDkLSEGniP1VL+sW3b+tXYOQV+VSFJo8ERNlCSoy679G7N8tPKgA+rO2/roGP/iKEuE38et9R6v9nhCPfo1vKt7XpvzJYow/qDwdStylXbfW9QN12Yx12r/nkPldVTXCYQDF0Vs0h/I1XMjbILpq1smbNXAUdn9I3W9o8KpREvac2H1ir2vYOzq9Ubhq4jggX/9s+FGm40f5MX/OM+lJGdRPCMG3rfWVeFeWEGWpmg0AXpV7eEuKH7sPrWy+QLXD1IwNE03QLhuOh0qEPsEi6kcCaZyLlCHYlzJ/hIAR1CBlCtGm+vqD+WRr0mGQtl81MMl6/BoW40dya/6aIKNOWfmYNgdfplknkVqxFsJnwVqjQJWfCzbW1KqBvMHx/7oPNjbMS0KKhd8ctOsTLSvq4zFI+mvR6BggwT8rwcfa66shJIaDDC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:38:54 PDT 2007',
+ updateDate: 'Wed Mar 14 08:38:54 PDT 2007',
+ accessDate: 'Wed Mar 14 08:38:54 PDT 2007'
+ },
+ 'a4218c7ece0287ebad7f3cdd6510f424245a4d7d42ceb083b664a4335bcb7690': {
+ header: '####',
+ data: 'hQ123ZhZ4AiXD25P/0Laq3MtRO2oSIrY+GoYe3UAiyEHc9HZDCvR+POEEaARXNyh+U6z8S12P1GvQbzo23ZCt5byhqC+UmbfF3Y4FikM7WmHaRPtWjv8JNf3X0iJ9a2IBLA1BlqgJolnVDtrLsFx+6rBIU9r8pI2jdcsw9w9feRbE9/0S0filh66azojT5RM1qLcIUVWGixROY6PALSnA9PCjA6IG5WUa/DX7DyRrosZ9V4ZheMlzlz8CgEKBTN/HREIbPrEocBOvmnbupIEpOvH3OXKDXf39KAGVBAU2IIkOrGyWfT12p9dK+Zf+MQUl4DDIdAbF81Lus+LQmqtQ1ieyV0nNiqFhPuglLvKRj7QZRFfHNyejkMTZQWjQhBdHRmfSxyEgmFrM17yVVz4cMis/44g3szHMgAAfFIc79wq09oNDEV+ZUMS2xyBCALjRmhedqYIMGRCAG15',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:36:20 PDT 2007',
+ updateDate: 'Wed Mar 14 08:36:20 PDT 2007',
+ accessDate: 'Wed Mar 14 08:38:12 PDT 2007'
+ },
+ 'c6613ccf0c1c6b65798c6f35657a10d4c6033aa32204a90d9d0274783a1098ed': {
+ header: '####',
+ data: 'ATU61Uq3Fe24JAEauMRtY8vMjzaQcPtnt1fshTD4dGuptFH9XoZ4bMC4XKHI7JKbx1NUEbR2ySOj9K/NJuWEGZjRgZbNI/KtuxNedlm/7jEpHQx4ZfhXQ8OiUDd+2bB9g6V0Ck2T1gM4IyaZMJ1QfOlYmGGv8n4flhHC5kUzL2OIiAxNHvKQjdEOccnEsk25Gg6FveKHD6NqVunsiCqhxJ84VBNzHJscuCTRcbt6KwR1+dw7Y+nhTjdDFq9UidlxTO0BKYsqj9F4Kq1LXORkSyab7zKooFH5kNd8torb5UFto8dfI8/+DOVHMxNRh2aWSn3O9bzwi1PfYO1nky2O6OKR48Y65Hp1sm3Xj4AAVHWSGakYUSV5M5XxKKzvoKY6Qqhz8GhbkzM2FC0IKTEcmINMvzXdzKRTqBFg6i0t7Qo80i3sQSoju3/4CYRozI2RrF8W4f3/0XgJf21oUAdTXOmSePSZoqhdejXeNQAgb89v+ZextxA6NJNYqvrx1NjdKmWKJIU+o3AgPYj4UIwWHwVADHITKrIWl/SbOsGP5aERtSiLnC+xqfRUOpgfkAYLcytspouHxvQjgNY4I1U/2S1DThG/N2EzuPl7GLYQ+Y3RAvLObFbrV8S3DS6vXIkigxyJT++MotIKoPBq0xDq0ck6joyvwvg4jXUMKlJa8/LQewJlbH8Lszx7SwjynzEQUJcpCnmxixzSNfRzpzgEBQSiClEEqArYykew3rjz9lc9nkdXUCzz81WYsvk6rGJ6ZdDsfKsG9+kaybuLL8huE0ERhznKDJW44ehDGQLr0phO3CI8n/9Px0PhPeZ1hvoiiH8CFSW5f45ZrFaaQG8hNyzWCpCFoX0/dNsNPsAkOJnO4v0PvO0HDOif1JjgPjCS51vBzxu8gYhkWlPo2hZxHhnnrbhxeBUU9jhLAx+NmxxfTjIWkbtHtVjm3ea/D2nuL1YrZKmQ3Qs6GamKlh3WwkRWRAVU3+/mbSGOISxo0u5v8QSmh/IPIXltniaQgWweqGNnCLWluuTyhoqnqDo0II7q',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 01:04:29 PDT 2007',
+ updateDate: 'Wed Apr 25 01:04:29 PDT 2007',
+ accessDate: 'Sat May 19 02:22:01 PDT 2007'
+ },
+ 'dd2b4cdeaedfc97c384f79c2878fca9a981efde6ebe212138db235e51b80c64a': {
+ header: '####',
+ data: 'd7ZpqQ4CTF00+/UnTvNnnkMXB2Ow/K9dys8V09Nedq4sgMUk08E1vqi9mdWbzNfRD7aV3blru8PfoRrxXRLTG/bjQ6xncecQoAJeUtSplKEO8fhuzGqbMqz47/y3aQDHBbygMAGV3wLgJO2Pv8p+8U/P3cEJisd9OqTNE+EYQz4eiq9dllMNUQjDY9aLHE8H0ny/5r9uohGNjXX/LfFMshjeS4rToCG5mzRaJPaRs1jkjzSntpF0RLxfU1acpJX4pNSuaLscdJ1lIwc17vygg6f3xexqvCeeFZBot1RwwbztZKbMfap4pRF5KoftD9bXJwoFMXigeMGLy0scpzsp1s8zBIwLhwUxEE0IBh7qeStg/3eRSW9slazuIR452O3Rysb+n/jWMyAhIOCSrnncjjH4XHbzV5GgT2d4f8jfBPmOT7l7C1ev41D3FGFxEb5TZGcJTaIW6ofLi5T5',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:52:12 PDT 2007',
+ updateDate: 'Wed Mar 14 08:52:12 PDT 2007',
+ accessDate: 'Wed Mar 21 04:16:29 PDT 2007'
+ }
+ }
+ },
+ 'de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4': {
+ data: 'CPY8iR/pjIj9RJQLodhZzqAHNxzEvqIrpTemeMh+7RmJ5TfWVJ9n8dJuEntoOd3NbNYP9mGEzytvBKxTFtQ8xxD/c03RfdQwMFuYAaCrHdNineK/hzeETNF6siCdiUFnCgyluUT8eLtMKOPvZJKpP3iei5GNnQJMbeLvM/yRmnLyNiHFBPgi8fx9bYLE4XqPP+e6RgFC1UkKJLeeVgGY+qid1LycKqEklQc6OH9JzLFPKUeu56xINyOzPrR4hPJg0fKIboy7EkPnXXn6bXWUsqzcFNBvubdDi4VPeKcEbcR2JDGACInJNDxVO7EobRzvycrT0UQnWPgRgj3cBKZPBrXN7ntdt8C7ceokHhEcmW3u7C96lMYFIm4cCeN5bGpJe8Hw4kc+zOT3RnDFqNTCg5nW6TTYbdOWOkZ9PpizPB094Etiz0bIoH9uUomMqKYGZagXBm0b7O8irSh9hXKdS58jH+UisXy03Vvf2hNZceIM6rpyLRhPhM9n3B5AaUD6X4JGyaTy9odGxKpCqzLeDqYo2wWfVtV3822uJqdrO8c1HHM5CSAQZm7ni9U9kwHAHIdt/UwuGDORmNBchEgv02tE8qnoAD7lWeB92VSv84J+NQ+v8js7/AgQFLjXdjuCGY5ouzriURf2HIA2NIy1dnfX9UiAqNn4bP9upU/8UAILSoHVou7zdINCDgWCupJkA+Dbl2nl4PC2rFpAfqDCPlV3L3UAqIU5V/SxchN8vdkdOLE0xjMn5dHvud5fUMZgXSF3Q/h1Ouf+4EU81Fgc/cjy9WLYGEk+dFLOCy2CQDlBfsQZBD1vvfg8UACcjK/f7DjGF9NZAGzFeSBNB+a66uZhGpd5MOhtJGm8CCITh/883QaRTxKqaVfPe+VtCTYYtVeZWTGAut01fFae1iNTSkgN2rlK38boZ2DbiRaA9jDvhTuH7IISLlBNUCeIkfTrWEMVndoj53lApX2eJ79DvmtB+WHuh1AklO1SOZ3eOXDw4oWpFFuBNO8HqKccPRce4HI3KFE6AVFzDoIT82MnxbfcsSpbtZyhZPTlZ2+mUd2e3HETD50KAkr9TFAa3geJi4rCfnlf95c2vb6D43wUrE+X6+44C/FqCvtym3yH9F4Fy79gFrZk+303KpcfcwheNLT3yLqgGe0FoJToSUPrZkgQb2MFh12B3X+uHClM6EoZInn1vSQSaNQvg4a6W3KT5WVhszgfKXdGFieil9LFZtf5TIX/xVGHuUtmgPrJMadjoZDSF6XW',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 08:20:58 PDT 2007',
+ updateDate: 'Fri Dec 18 09:50:20 PST 2009',
+ accessDate: 'Tue Jan 05 01:38:41 PST 2010',
+ currentVersion: '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28',
+ versions: {
+ '201725aba7b4dd93531e40ee08eb8156e3aecd3db4f11e54d4d88ed5508c72a2': {
+ header: '####',
+ data: '4ndloDtoW1Mhat41ZlW+nN+WkdEriCn/z/oclyBFQSljJRlMwUFvzE/OCVYc2fQx1D1GBedY/O13v+SCAiJXUrr0dgrMDOfmYy7ZtNo0hYshjaYQucJovt7UQLeFAuLO6rNK9CrsYA/AWoiT878z2iCYCqVq41sL8juCm9n+d9aR0eyjXAKj8QJzVz/uvdudoGQ5xL18x2yUZnemY5gQklYlm0u9zzCJ3rLOENnnAggFnSJ0oysNjB2UwQY6P53bqXzF8E+u6Rv3OoIbmCIZMaoK1G5ivnWHwhLzp9UVdIj8ipfLsTJnGMk+aZ3nnEJ7wQCaaLy/lY2RYmSeUTTZt2ImK4ZLrSxRC21QkD+juyIiaEBJdhP8UOfcqE8Hw+etc/Cl0QgBtv9AgXD4BiZs3HUTXsV/PhIzP+6TGyr3/A2kt8dv33V7Gh2Ba+28wtsG/+HwCMk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:45:40 PDT 2007',
+ updateDate: 'Wed Mar 14 08:45:40 PDT 2007',
+ accessDate: 'Wed Mar 14 08:45:40 PDT 2007'
+ },
+ '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28': {
+ header: '####',
+ data: 'eSAwxBi9CLckMV3o9PxBjVZZ47g2AOIsbPt8QMPta7U+6KKUm58cXHV7BDfRkbin3JYQJGYfu4HYHmayGt4IcX4RD3riftxnG3UFNqG4LQQ8+fwA3xTMBisnUSq0JYc/PKdBKzxH9x8moSqZC/cgFWe90p0PxdY13otjd1qvDL2ALAgY/uEDboTcLTbSEhpGIYQHtQ1ZjDG+KXI8J7atuMvS0KFreNUm9+uMZT0yCXwNpGy+ez2+ZDXTEjZUKaFPLI7g/vyySn6VMXmlqJftGXZ+fW5UWGaxb7WFa1hh/nI2okPuRlUQh50xXQJXVvanw1ATJbN1PRfYEfvQKLlAAwYuoB/qL0y0vU+3OktAbgBvwt9prs3IsqjwMeaejVTo3Yj9pQPJ14a+6lxQZQRFUaLePIPdYvq9NRM7chkNYminW0JN6umi6bvJ4KKTyjAglBQ6X4s=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:47:01 PDT 2007',
+ updateDate: 'Wed Mar 14 08:47:01 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:41 PST 2010'
+ },
+ 'c7398bb27021058c9965a332d678b0070287b8ad12694bc8732346e6d84fe9a9': {
+ header: '####',
+ data: 'L+wk8k9ejeUeVz0offdItFpy8drMl1hi0FODBMKlPIAmEcNjnHU/IktOlyLrK0YHj66DaplXw2EyRkJNcMIbfACUtavxhWBH9VTftOPepsbsrU19aP6Xk7R1pr1sC76w1TgKCjE6IyBnK5qk1oHqcGv71GJLMmiqGivKyYOXQ45SH9tbHC4GUrg0YxoAYRwXqg+SlwRHpSZkX55NzPCEZn9eatGKCznTZs7pg0uBoM546fOIEBMgGndNk6gnsAH7At8yYxDMnkGHUctsSExL1O+W3bDDDx7D3uPkkjtd9se0exPru0fmsfcKPrcRkx8b8MAdgcylOtMdYvSudPdR6foSIqKMqktH35QlH6Rr5E/ire3O632QlmCieKDoPk/cB/qL3gKedxT1NxtC7SNR3aumKBAKOBDTVSjWWq3sIImQPZz+RUdRajeqkryNDVVPLFyjdC0=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 08:20:58 PDT 2007',
+ updateDate: 'Wed Mar 14 08:20:58 PDT 2007',
+ accessDate: 'Wed Mar 14 08:43:46 PDT 2007'
+ }
+ }
+ },
+ 'eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 05:35:58 PDT 2007',
+ updateDate: 'Thu May 10 06:01:21 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:37 PST 2010',
+ currentVersion: 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec',
+ versions: {
+ '157b5933272bb6b8a70bbabb7fa0369eb2660f7f0848dcc653f592f5afd4f2a4': {
+ header: '####',
+ data: 'z8BUTeAbrs5GeJ+SxaV9ceaAoqxtW/touC8xhjkEqbG6+IgMrfuz6ABRn+vwiN1/Vmfw/tyad4kB2SyzKgaYPH7rXyBir1mzJi73/oHsXv5wWNhEePmjZginGGcWQ0P4AnrAoxlaI8tXo3fbsz8e40x1b56N5J6zIdvX3eewgIMU+J+iomZVPDQq5DNu0aGUL1xs797FNm4vLQbVRF+mzrZlT4XZNzOr/W/Br4vG/Ureoq1QRjAjj+8HRt7ojmzrpDX3RtmSbWqUPQqx/KpFGqVUNw0zs09MomVIYilRawe/zegW2KZKK4rmqoUm+mnWQTf/I31FYO2N8dLrI7OV71EWlVN4FSO2A7NRUd92uVxHzItMQPS3CSQ57FYAC+WhJh7k+/ikJumVSf18pZRSRaEeKPxbJZFJqrWsWk+SsqBIJ4EklAnBBU7zLmMVe3GO/ml3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 05:35:58 PDT 2007',
+ updateDate: 'Wed Mar 14 05:35:58 PDT 2007',
+ accessDate: 'Wed Mar 14 05:35:58 PDT 2007'
+ },
+ '1835468626573e6189e5302f6f354628f49900efe08adc931990d1c11fd522ef': {
+ header: '####',
+ data: 'Bv0je7USknogpb1ng86CEx6GbHlysuN3e5Iy43kg1iN83AgRm0Hp6/yMivQe/mEmQb+67cjHfKKrznAESYzY8uv3b+ystxoIaQL7tKJ5HYu2NUVvZxRC+PE7AkBhc+O28OzpZEHXXz62uZFsjRDw2hC/KP1XfYW+Deuulnpz6sgjuyWIYXF2486DzaycCqX0NmYXKE7oXAthOlbo+Zsm8Y5MWh5ploJFrzhAm0CCzjsGSa7NBOBWU2o6vN0NFMcOG2pdjZGWpWo1QQ5G9tx9UvM5pTamwcg5TOr4yOd16JmYTDjK2Fd5mdUuG3zIxFR8StIKI/Sd1ah8U+DGbNlVYAVb5OREJxQxVv6I5dxGC43CGWbpx3fB5wuFT3Jek6tv+LgBJaI9Ika79NFJQrLVMFbQgD0qU8YgCmLbxIJ4gxMBUgTN+v6PraIDHleYlpW3KVIiNxv2Ztc=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 11:24:49 PDT 2007',
+ updateDate: 'Wed Mar 14 11:24:49 PDT 2007',
+ accessDate: 'Wed Mar 14 11:24:49 PDT 2007'
+ },
+ '47f73115ba2079f4b3703f502e3455498900a21941625c25d52ebb7da31055f7': {
+ header: '####',
+ data: 'pK+wAHWg4IJcixnFodLQ5EH+SFQIOMOrthx52u21WZ1ziRWJLSYGwA8CNNK8/welwzPHOPWu2El+zE6cwLHrzmL8EARLvvJ2fEK11ZIvF2C3R06uNrA7QFZr7iu6t67osrpfljqbjKQrMECUCUDrBywRvlpaeIlThfA3XByezK2HtbyHD1/xnyQSenUFu/6Zq1EkVdm9iCkbej2KxZSxA6qMl1WcnplBdOqBSmeGGJ0+Ikn3LZ7t4ztqflsug7QYyQlrmI+d0UB8MFWpf6jYjZQwf1rMH5XHFvrWUCi5IbFNJBUPF3n3IfUlrnjUSBEcW3tmodJa16/biK9/iKqh5ImlnpbQgK7CStgQ8ByJqddJre1idCiK/dyR1z+IXHTu4qm24cJeGUk7la4WMG2O5U/otFbXG5wTVgbLsxfXlE6fzxHAzvEftEE1ZPNOBpRZ+LVYEHKFESIz',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 09:41:15 PDT 2007',
+ updateDate: 'Wed Mar 14 09:41:15 PDT 2007',
+ accessDate: 'Wed Mar 14 09:41:15 PDT 2007'
+ },
+ '6564169ac5bce1a632c602c51e9e5d637bfd4e87c1fa276e2cf65f39405fc4c9': {
+ header: '####',
+ data: 'fs5hydWDsT/FxWTb57K6zYKwVF310zjHHHtRS/AeBN8XZqTcirhV9oxJW6G6TdDkD7nQfWf53AbsivXn46Tx7oarzoU4R+1mz94TRCkEe5X2X7Wa3HbTj38+QwbkomF7np4MUkVc06aRPqkUE5hvSDbGn4SyKCjo/AnGhuW/QJIqnWVj70tf7CNTb+GR/y41JhJd7yk6U3cIP6Imik+DAvM5pE0KqxGLfLs4c1ChuTFNHfiQbYjs3tANqJCO185t4S8UIY5VxMRcnqgRoloFK3uFACIXoyDGG3FjILgxRCw2ePFsrm2Jtxv+JX4BsM+KDk67OsN91rjQnK5vBP72SzSge4EDCKJXYKdA8KJGYNwRIzk5d5ycbZgW4YCizVw8v7sLMn60v7YrDfBwXAJvvlTP1chA7HoE+WALqXkfBW29AOCNodE3eTXbI7iWz3vcWOCPvSm3hho=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 11:25:28 PDT 2007',
+ updateDate: 'Wed Mar 14 11:25:28 PDT 2007',
+ accessDate: 'Thu May 10 06:00:47 PDT 2007'
+ },
+ '7674ea33b650e84f9a461a91928bfc259de5549ce905339fc3b23623c6cfd09e': {
+ header: '####',
+ data: 'D7mLcDpylLnklOtIw/kvYX0M+CR6Si2t8CB9bTT3ZR+bTpXP88OtI19g1k9iPEUPdgbtFKPVw4oNmynP3x+pc8R/zzn4v697SvVtQxdF39Jmry5dnB4SMx6oRkuaISs0nxvTrHJe8U+s5ehzvQ2WWxWZ+LaoBWaYR7slgUFKLdJFyWEalPwMPVu//DoLZeWg19n2C/0Sy8u0DGdYHJVserWrQqxxg0h0m0x1wuKhF7IGvqgyJ31T5w00nMHNZbs89cUuqB/2doMgoUD9BqV7F/53AveuBDcdCc6jlEe8NOdoUyMuhwwwTyKONfjY5e5Cu5W9I36o7GpeKlckoKrTIWFO+NLG8XZvP/f2WJCsIOrCk/LI3C+bxBP+bK4tHRH13iXLeJYUlMK4ibcf8WI445qNoggJSbZzGr7Dav23KZWPcxzRxhI2u6j25/kKGnu4kcMB8ke5N+4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 06:46:36 PDT 2007',
+ updateDate: 'Wed Mar 14 06:46:36 PDT 2007',
+ accessDate: 'Wed Mar 14 09:40:01 PDT 2007'
+ },
+ 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec': {
+ header: '####',
+ data: 'u9HEcfobxZhG9BY3dVG68ZUYkREFcZ4q1o/xWyt3qje3icA+Nu9yCrZip/4fqe1daUX/MHyzUQdulIfjSwATjj3vvDSPjuGvrtx8oUjJ/K6GFsL366ozi45LkqkOaH02/nVrb+ik2HWIgcne/OzNrwf1mWLJoBF+8ZwQ44xqQK7ikG1mblNWWbZFFQE1B0QPmE/I/1ovm2hAr1ZsNj1l+N96hwGsdsdVFTzn+S7Sg8GTbxEFAxDQkBYEw1k/R8i9EIBndPoDZCebr8vP+c8qSEk/YmBXJ1MGVVvic0/Utn67iNLz9aBnv2z31DvvBj8bIwOxQpB+tom5Ivwe84tFkwwvpxFqYccrEg4bbMcevUo67TBVe+Lb2wzcK0zOr7iHhswbXaLzzOEQ6uF/v2ibTbATP2zNq09AIJjynoSDmrisGHsBrHgeXjiDspc9U70PVC83EsjPRwA=',
+ version: '0.2',
+ creationDate: 'Thu May 10 06:01:21 PDT 2007',
+ updateDate: 'Thu May 10 06:01:21 PDT 2007',
+ accessDate: 'Tue Jan 05 01:38:37 PST 2010'
+ },
+ 'e699fa287c2de3d483144b48064a47cd0bc56a436431ce23b48cb8d8c42ce851': {
+ header: '####',
+ data: 'hVD8NOt8g/DIe48JbUUo77e2hMf2UBN6ah23PrIzGTpq0LifC2K/0/s0yeL/PHUOncdT56NccKpF8Fp6EWJqDKoKZPWASuB1vHCEkdbcxlqzqo98VS3A7p2JFwQzSv+5t6y909hhbxobXMCUfZ10HBqGo6TaFc6+pkYqQ/d7MEnj2NuAXC9X9TLLuZSrZ96NCKGr8YVKzxinxHdiF3TdRvIppFByXPlbZ3xiielEnYm6pu/GffW7Hkwd7Vou6jwyggxVqvoVtuAdiIy67l8GX0gQUGipFkvvrAkXfm0sgtWGQvpgDuV/bXq/L5vX/sFpWI2u066lMUOsJQmptNP/Nkp31+ZNk1nCcUIYDDa6vcOy/gRrOFcenPTUQjRkE95KPaCqYBSIWsjoFE0EIB+iBnBCTK3laBSC7pplOtuLCY1YJcJuOkzCVQCVXjhWrNJM77s7a5OyTuE=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 09:43:29 PDT 2007',
+ updateDate: 'Wed Mar 14 09:43:29 PDT 2007',
+ accessDate: 'Wed Mar 14 11:23:51 PDT 2007'
+ }
+ }
+ },
+ 'f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732': {
+ data: 'vxOgJv/v3pP8GFqbFLTcgtBqw8V3zhCN9rRXUuWAfatABtr3pySWvt74ITeGw+sDtApBsu+zTY/95BFVtK3y0QJkC5cjJYhLDwvMwpqa0lRfCXWSYmuEhbPETwkW1MN0kAEOMqsUD9cQCH9GDD4A17W89AoTG5Ce//X03YBG0cDjbotgENsWjQpK88LXABHBQAoTF0BPDjN+xai2QPCgN0l1IVpUzI87oZJS7x/4r6DjGTOgcc3+vtEujr+8dGNaq9xTEfAFs1kv6GMeT+R/VkIQLVO+vSxi2fd+954EAXQplt047+aZ3c0c78N6B+GhSi9DgNnbTLu6sl332Zdgo9R09uucS8nvRp3HcTzxriKpx0ZMDh9K9ig5NT9Z2H49pDjCJKTukDU7b2ktOEUNZt58s+uIlw1bMFY1TMETGAHbTq+hld8Szg8f7nJGDQF10kV2ykVEQ2oUBMC9y9VCLyYD0BWId6DUcTNXyI+MqAC4j8pp0NhURY8VSjtnV4Rlq+b48ahP/ifJdq+xrSiT9ykGqc/EyebC1uCTIZewk9MtIAndVYPckMIe0xQ2xhX6/m2bdNboVa3dnS5eKFdbd++un6FD+QAjgtcBkXQnwfptottZoghclKL5h5gPePCQL/66CLYy5+3xctfCG9u+VkH97JKL2hW+XZ/KuxLPFkIAYmbFKsNdIizfpbk5WJvoSzacpo1mwNjZ53zn9xhy/VkSIz3lGl83a6FyoHuR9VklyhTaKrj2JNWzjLaQPiR9Sv2eFNjLTivxtxLwKae5Tz14WU2QlXATC5xdcLeF9nK7yYVarcKlRsYkkvetrVpRiWUVfy9mZQIHOWJtY5AcptKso2Q0v4CuD1C/wV18DMDXzwMXeOq0cKxCsZOuWjO6RwWKzfeZnJ99S+EsFmdI/wxqiu9slJ0xXvgLvjiJhJ03qWwZV45peU1qmvKQrXS80QqLp3kUfRGLbZNOvkZbyf5OK96MA7lok8PuCZGg5jZHFX4B3vxSQ32P7VGSWO5CqHpF45YwtlONZKB0cuvKTRazZ+B2zJfwMYRQloj6sL5501oPqmjVtDg+0aoqKe5DmTf+fHV4FwAxQ8RuW7/BVL+lwf+zjtd31I/yrlDdb/Scs6yayLV026yuHxdQRl+ByogtrXbY4ViuU3NCkVrme7K7meRHnQdXyidhjzHdoJnRPa0IoI4VW3VwWNENRRNDTta2whOdIKsQYtscWBWZnQplRmDChGikERYQVCWejDNgvnbnGrlyQYPF0/vcv6PoDpIvh7Pze9y0MLBU8DnWqAhpdqHPNVdjdq51OKlSitUk5TSN9kxePe0KNFZueLjxZHUFIZ+SIkTxoCoaRWYMJIWvYkcT5S9Y/7NbdapuUaLZNGDc6tgD+LVYRRvGEdPWaOHb7G+qOmdtx8vYxZUqq5mtwnIBRzEllTJyKwwK/kOfAxiRjLxf7SOXsubPuA7bHR9fI5rROSR5rcU+nOfSV9Wf4wZkYBlSmQYqzQfmwl0UCiipJVa1DwYwLimgo2RqhI0M38gEH+mrknnevE8zlUIaEWzxoOnyWbtCecakXS2XvE9j64dswJ3bbeQ3fDQr1308x9qKSjFdDl3eNcJx2e9YwC7wZnTmHeHzRXnZwXsJXqMPDQV99wEDBr71BjlDjMx7vG9bOWrhsyJ37EOvO2X41Ij3j0X4MYpbNgxBFP6zJSu3gILrtqQRpQq6mQJ1bWHyCN1ge1zKNT9pG6rGTRPE9LqHROQuROpgFM1R+DqW4XnGOBYSOtznnsnj5fxfdpGeFq+v/ftvVuN5XsgX6dnT8R77iNUs86Iz2mkxLaQokkNzXl5o1rnQIse9+kcKVZ72mf5SG9s9DD7cZ7bOtmkuZCexJpieIosqLV8jc0IA',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 09:39:39 PDT 2007',
+ updateDate: 'Wed Feb 13 06:29:04 PST 2008',
+ accessDate: 'Tue Jan 05 01:19:18 PST 2010',
+ currentVersion: '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74',
+ versions: {
+ '33ce5a03b6d36f59d0fbc9445dd01a515cb56eccc6d854cffbf8aa66f3e4a45f': {
+ header: '####',
+ data: 'pwMmqFOwpW/uSys3hm/AcoERF3eDj4dO+O5SdYsR2mJtmEfXcjhS9altLhVOsck0KMQJdxE3rNDFbduF35yVetXuQrrL+bSRlXMq03EXETyrRzIVhFEM4BjoCSS9nKGgixp04Ve9WSuwD4cXRmcN/L9kCJSCqflXqhkYkjAywQoj1KxHPdAqMaGRpEWioUIfX+NiWbO/qtOu/USAhHmWFXla6/A9kKQeU2d+P3zl9KF2Zm8qm8NXjPKmh2dkd70ATbdzxt9P3BafoRf/Ud8zLIVdQYTbv0pn6UMIiUDRK1ryvgfSY180zg4qkP5pBnxhEgOxbjT8JO6hCl8n2jUCRJLdUXHwgpeuHcKYDyZizc+p9Kbc4+d8K/2UEKgSR6gza6Cpw5TQbZQq+2LxWUoVb3HM3lTqBKUPM0FdY2/3twZm/1bI1uBMPnyp9x/JsQV+xOpu0ZulTA==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 09:39:39 PDT 2007',
+ updateDate: 'Wed Mar 14 09:39:39 PDT 2007',
+ accessDate: 'Tue Apr 17 10:09:44 PDT 2007'
+ },
+ '686ea579db132287e8e322194652ec57cba6e60274c00f734db7a0b36702c817': {
+ header: '####',
+ data: 'ilf8U30hSq2mqje9kZkKQAMiEFV0aptXrm8fOtoOR8pp36V29kXyUX6FEOh5eXSRr/jbqGytxKENJeAGxnsv5U+8GgbvlYaR4MPM8lbKcpAoBCc0+CCOiwnp4XCoXFCNttbTzfb6qgR7wqdK7YLnrvfzJieQqJukQZvtWtsVZB/Tis+5niomz8Ca8lo/FjFOIjAq6xtwrW4CS12+yZdTKNbj8e+HwoUcesF9RbCKQlpVHuwhZ/8ghdzDgjEE8z44rDepEv3Lx/aUi+67velLH3j+1crnxBUz7wP/dWzftwWgIxDkCR/vW63yY2Xebt77swDg8g1Qj5OJdYiAq231HKaZjxr10y88JI5HC1EvbbduDN6pknKUgM+qEdojpi2BmjK+9MtV7sVhJoWqwHG8q9z03kgGoFnWEb53HyMVes1n6HYfzwnw+idPFWGZJ4IB25WfJLfQuQ==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 10:12:39 PDT 2007',
+ updateDate: 'Tue Apr 17 10:12:39 PDT 2007',
+ accessDate: 'Wed Feb 13 06:27:04 PST 2008'
+ },
+ '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74': {
+ header: '####',
+ data: 'l18dnf2TRfinuu9KDraIo41yvG3mNFqiSCOkyMI6WZZD4RnF8R2Ob19fJ8zXv04eDx7TYyyGP1IlFWEdT3LBrOmmbtUmIvtYanIfKTkT6UGHNH2jh1HyHqJbpgIlr67mOm6Es/AgF44BiyJrk5R1y9tA90oeUQynMufiM2MFLpdalDYWEh+W7GV9WCmbBIU/soioTJ1ep2gvy4kJvTSrXENaxHevKfYwn8ucocvY+hjkWB4GWOR40qtaG06wWMLeRsrTBH1jBG9srzbBa4u2IQ0+NJjQrYdiu7nfu6Uyu7Ya/4bxV3Sukao91XvXSFIhcI2OuKl0njUshv6BDEfHwXIQuPtn7KaTx2uYl1pUeTv/tAFvf8Ng9OFNgK0siIMkeg1thFwRiGSmxjP0QZipDtcCekIxj2k=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 06:29:04 PST 2008',
+ updateDate: 'Wed Feb 13 06:29:04 PST 2008',
+ accessDate: 'Tue Jan 05 01:19:18 PST 2010'
+ },
+ '7ee6a662d1980467eea86a58cd7299ee02000740693df2a7ab9dd64347dbbaa4': {
+ header: '####',
+ data: 'ZnwtGdkg72+TQKCJQhZQIqP9sz79FcptnmH8VJEDQY9xTburh4cyhgbgROBis+awp1C5OyiAAoWfPnuRAN8Ai3d9f8M8yjnDGJ4BAJ6OjQ5r4RDQxNycCApXWO3mJpBrx56wMsCVWT6Z8a4khzPrf5HlDtus4lRV4GRdhU9FMpwuaCfgVD38MhlYXDaPgyu/8N+6eQHuFxquXjOJmptfO6tVhP1+/tEHo6iUAX3sXMZAionssRgPllQJxfzrsu7GQk3h66PakRzgStTHUCcdyoEe9c4VnvUgaasTbhENA4x8xPrxjo24zwxfFpWNEb1+pe8N3+dOXTsIdd3CMKrxQ5KkwzyN/Bj9jXNk9YX8PC0geJiR3bCGtPsAd7aEFB7E6y0RVX/RL5f6x0utSYw8mg6lfprlr5A=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 06:28:28 PST 2008',
+ updateDate: 'Wed Feb 13 06:28:28 PST 2008',
+ accessDate: 'Wed Feb 13 06:28:28 PST 2008'
+ },
+ 'c860f9bbcab5fa70854212e18c11a3e9bdc2382f91cfbd25636955c443a05f8e': {
+ header: '####',
+ data: '1rztZ6mKVFVjlL1kEoUsXEMketdElGbOpYK9iy3g1/WeMcTd4D/UjgHvmQHzzNuYJc/yx6cCMMU9dofLe3vWLKhqDAPAVCo49qiH527hP9rQE+0SNO1v2Ymk80hL/gqBfju51bIYxPKAD0uYA+GMX7OdL+S7qdealebERcnVa0K1AHiVU8lu5yIKk55U8zwitk0u86J1zwcraiM3RGXir/x3oZRIKDwT+lhUJPr8GbVjgKlPu07Ii8OdrAGdHefETDlyNnaKPJHTbGXkd3HZ2CYhJCQZGn1Hwfs46iRd5aO+3UErYtgIHl6CXuXd4E+DNW4UJZedP9YV860DBkpqMiQokEMYTh8Y2sOUyf3ZEOshfGvJUhj8O5p7rNm4+2BYO3XhREdV39tn4vUj56wYj+GL5CekEl0c4Mx7ViTQA+gLvk52V2w/5gFyFNQ9U+jUQpb2n+d9cw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 10:11:33 PDT 2007',
+ updateDate: 'Tue Apr 17 10:11:33 PDT 2007',
+ accessDate: 'Tue Apr 17 10:11:33 PDT 2007'
+ }
+ }
+ },
+ 'fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6': {
+ data: '4zgqvaaWm7nJO09LKN6o5hbWwGzOv7VVmXDu5T+JCHTSOXbteogax2Zrv0uKLkfooGFThJBk0rXfXxE64vMOq3AeHXGw7Chg7hz8Z2Lpjr4FfE6q7Em7UuAlAuL1PiyXXJJK5iSsRY9tkizuYl19aXW+CgpPznYD/PyXgeYxqt9WLqK8cl5iAU87R0cQDhwl16ivzVgiiFeaB6B5FQqWBAHCEgXhqTsaw2gv4snbmPOqcUZbHy/Vb9hv4lPBJwGFNxQzeZUad92VBC8YbIjmbohDsXjteqD2/k1qOgpUB/U5BpyVwsi+5ahgb8gbS+AqYoRDYzkaj83ksPI4JzWyZhpqjhDauaI6M7hGnJ4GB8UZc0M3WPgrlf1r+TXCgpcfembqL1MyteM+C+ItPRP/QdaIXxLOmvGFOBKQYEI7UceUWBCSEzORlS2S2lltlqt+K4B8QTULiKaXCfRmF/u60FpJufIkUX0pE/rQVChxswSWvh7uJFDBIDx8MplTX724A7DN5d4/Ad4Yi2cj3V8X/DEErnHTvirP3tZ2F2oAe7kIdu+JuCqKcMaGB4hVijzv+yim2TCPvrGTFaMmg9PvcWHpik9jEIabCkdqAR8EGIkD29+yvG4vD0DTRKv2vPIfr60ZQnsgs8nlPPoNa6lNHvI/EO0nBGBYBc1TW+syV5h/zOG3rHX0XCHhISZmDMjra7eUETWChncR88P7ciC4yJQtzXFGzeXp2ktzZ8m5g1EQfgtlUVZsHN8e4OQ9DjKt0unfq5RFBj2jlG8TBZn6ZpebxWR2qOxp81KQLHJND9zRTy3h65+k5wo3MnnxE3GbeXg2dFIORRvGUT6bWsqW1fqR/pg1GO8KNtrt3CryZofgE52kuk6hlcmSk9974JR5523+1/hbts8n5VrTi1C6GWhnxpiJb1XIvICdag5g7C2iYppzLKVzbJcFMegwDUrapbmGhkqnGwSY1EQSDyagPr2xlziWhdWdCOVAYcyw8dOpdD97QhVef0OWrJ8nbgFKD6wn21475OFxooheWiMCyZwXqESVG1cVCjeaCsymBtEVPpmQdSkOfMdXpKVF+3osb4K2XDpPeU1zPWVozeMp68YhLztQ/g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 10:43:29 PDT 2007',
+ updateDate: 'Wed Mar 14 10:43:29 PDT 2007',
+ accessDate: 'Fri Jan 08 12:44:56 PST 2010',
+ currentVersion: '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a',
+ versions: {
+ '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a': {
+ header: '####',
+ data: 'QfC77EWgmmnxz9JqLdn9Tw7mNztfQZPdNpaML03EdFpphsjgLloqBRX0UZ21oozjQGHpcUMMOsaJgzCuDlfh7T7ePVV60Ps4AJtzv7bHSVGKsj1iALU1qjtesOYJayp8bA/3peo4HEnVgP86jc5NTwJxpsUhNG0Ae93xVu4lPF0gL0/yjgZUHqYZXkb+oXrcybL0BSOjRnB9fRpA1dEhcwJwoelLTvg7il354qp/Wo+S9Cz5E/K+xnlJAuSXCRXboWea/ZZ9TX88q5uUcY5jLF7Xi2HoFVZw2f5tbycxwGtT1CKXp+OAKn6mQaBAYM51zoMNDT7MvBDXD3v4Cidjgh24GZ2zndfkYT0kHCtY7OVIVSTsXTR+5/XMedojVvDlX9LBa9ST99NLCUy7Di94rJtX72ev3Ei3I1w3qPvCl3jgD2VbIwLogCzqLtY+2IkLAa8M2EpX/D+h',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 10:43:29 PDT 2007',
+ updateDate: 'Wed Mar 14 10:43:29 PDT 2007',
+ accessDate: 'Fri Jan 08 12:44:56 PST 2010'
+ }
+ }
+ }
+ }
+ }
+ }
+
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': ""
+}
diff --git a/frontend/gamma/tests/tests/Components/FullApp/index.html b/frontend/gamma/tests/tests/Components/FullApp/index.html
new file mode 100644
index 0000000..d42d112
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/FullApp/index.html
@@ -0,0 +1,243 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Clipperz - online password manager - debug</title>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+
+
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/clipperz.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/compact.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/ytheme-clipperz.css" />
+
+ <link rel="shortcut icon" href="./clipperz.ico" />
+
+ <meta name="description" content="Login to your web accounts with just one click. Never type a password again! Use multiple complex passwords and forget them. A password manager that enhances your online security." />
+ <meta name="keywords" content="password manager,gestor de contraseñas,gerenciador de senhas,Kennwortmanager,passwords,security,privacy,cryptography" />
+
+<script>
+ Clipperz_IEisBroken = false;
+ Clipperz_normalizedNewLine = '\n';
+ Clipperz_dumpUrl = "/dump/";
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+Clipperz_normalizedNewLine = '\x0d\x0a';
+</script><![endif]-->
+
+
+ <script type='text/javascript' src='../../../../js/bookmarklet.js'></script>
+ <script type='text/javascript' src='../../../../js/bookmarklet_ie.js'></script>
+
+ <script type='text/javascript' src='../../../../js/MochiKit/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/MochiKit/Iter.js'></script>
+ <script type='text/javascript' src='../../../../js/MochiKit/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/MochiKit/Format.js'></script>
+ <script type='text/javascript' src='../../../../js/MochiKit/Async.js'></script>
+ <script type='text/javascript' src='../../../../js/MochiKit/DOM.js'></script>
+ <script type='text/javascript' src='../../../../js/MochiKit/Style.js'></script>
+ <script type='text/javascript' src='../../../../js/MochiKit/LoggingPane.js'></script>
+ <script type='text/javascript' src='../../../../js/MochiKit/Color.js'></script>
+ <script type='text/javascript' src='../../../../js/MochiKit/Signal.js'></script>
+ <script type='text/javascript' src='../../../../js/MochiKit/Position.js'></script>
+ <script type='text/javascript' src='../../../../js/MochiKit/Selector.js'></script>
+ <script type='text/javascript' src='../../../../js/MochiKit/Visual.js'></script>
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/CSVProcessor.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeePassExportProcessor.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/DOM.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Style.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Visual.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Set.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/RSA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings/Strings_defaults.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Toll.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.JSON.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/BookmarkletProcessor.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/DirectLoginInput.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/DirectLoginBinding.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/DirectLoginFormValue.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/OneTimePassword.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/BaseComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/Button.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ComponentSlot.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/FaviconComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ProgressBar.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/MessagePanelWithProgressBar.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TabPanelComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/Tooltip.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TranslatorWidget.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/DirectLoginRunner.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/ProgressBarController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/TabPanelController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/WizardController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/Page.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/PageHeader.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/PageFooter.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/LoginPage.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/LoginForm.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/LoginProgress.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/AppPage.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/UserInfoBox.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/TabSidePanel.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/GridComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/ColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/TextColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/FaviconColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/ImageColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/DateColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/LinkColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/DirectLoginColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/DirectLoginsColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/DeleteObjectColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CreateNewCardSplashComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/AccountPanel.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/DataPanel.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/ToolsPanel.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/RulerComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogRecordDirectLoginComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/DirectLoginEditingComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/DirectLoginEditingBindingComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/DirectLoginEditingFormValueComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/BookmarkletComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/UnlockPasswordComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/NewUserCreationComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/PasswordTooltip.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/MainController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/LoginController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/AppController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/FilterController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/GridController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/CardsController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/DirectLoginsController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/CardDialogController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/DirectLoginWizardController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/NewUserWizardController.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/Marks/exclamationMark.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/Marks/questionMark.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/Marks/info.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/Features/store.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/Features/protect.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/Features/directLogin.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/Features/share.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/Star/normal.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/CoverActions/look.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/CoverActions/download.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/Tips/open.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/Tips/close.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/RegisterButton/normal.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/Logo/normal.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Canvas/GraphicFunctions.js'></script>
+ <!-- script type='text/javascript' src='../../../../js/main.js'></script -->
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
+ <script type='text/javascript' src='./User.data.js'></script>
+ <script type='text/javascript' src='./main_test.js'></script>
+
+
+</head>
+<body>
+<div id="mainDiv">
+ <div id="loading">
+ <a href="http://www.clipperz.com" target="_blank"><div id="logo"></div></a>
+ <h5 class="clipperzPayoff">keep it to yourself!</h5>
+ <h2>loading ...</h2>
+ </div>
+
+
+
+</div>
+<div id="applicationVersionType" class="LIVE"></div>
+
+<!-- -->
+<div id="javaScriptAlert">
+ <div class="mask"></div>
+ <div class="message">
+ <div class="header"></div>
+ <div class="body">
+ <div class="alertLogo"></div>
+ <div class="alert">
+ <h1>Attention!</h1>
+ <p>If you can read this message, the chances are that your browser does not properly support JavaScript? or you have disabled this functionality yourself.</p>
+ <h3>Javascript is required to access Clipperz.</h3>
+ <h5>Please enable scripting or upgrade your browser.</h5>
+ </div>
+ </div>
+ <div class="footer"></div>
+ </div>
+</div>
+<!-- -->
+
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Components/FullApp/main_test.js b/frontend/gamma/tests/tests/Components/FullApp/main_test.js
new file mode 100644
index 0000000..fa21581
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/FullApp/main_test.js
@@ -0,0 +1,114 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+function _pm_logEvent(anEvent) {
+// console.log("####", anEvent);
+
+ anEvent.preventDefault();
+}
+
+function handleGenericDeferredError(anError) {
+ var result;
+
+ if (anError instanceof MochiKit.Async.CancelledError) {
+ result = anError;
+ } else {
+MochiKit.Logging.logError("## MainController - GENERIC ERROR" + "\n" + "==>> " + anError + " <<==\n" + anError.stack);
+//console.log(anError);
+ result = new MochiKit.Async.CancelledError(anError);
+ }
+
+ return result;
+}
+
+
+Clipperz.PM.RunTime = {};
+
+
+function run() {
+ var shouldShowRegistrationForm;
+ var useCompactDesign;
+ var controllerParameters;
+// var iPhoneDesign;
+
+// MochiKit.Signal.connect(document.body, 'onkeydown', _pm_logEvent);
+// MochiKit.Signal.connect(document.body, 'onkeypress', _pm_logEvent);
+// MochiKit.Signal.connect(document.body, 'onclick', _pm_logEvent);
+
+ controllerParameters = {};
+
+ MochiKit.DOM.removeElement('javaScriptAlert');
+ Clipperz.PM.Strings.Languages.initSetup();
+
+ if (window.location.search.indexOf('registration') != -1) {
+ shouldShowRegistrationForm = true;
+ } else {
+ shouldShowRegistrationForm = false;
+ }
+
+ if (window.location.search.indexOf('autocomplete') != -1) {
+ controllerParameters['autocomplete'] = 'on'
+ }
+
+// if ((window.location.search.indexOf('iPhone') != -1) || (navigator.userAgent.match('iPhone'))) {
+// iPhoneDesign = true;
+// } else {
+// iPhoneDesign = false;
+// }
+
+ if (window.location.search.indexOf('compact') != -1) {
+ useCompactDesign = true;
+ } else {
+ useCompactDesign = false;
+ }
+
+ if (useCompactDesign == true) {
+ Clipperz.PM.RunTime.mainController = new Clipperz.PM.UI.Compact.Controllers.MainController(controllerParameters);
+// } else if (iPhoneDesign == true) {
+// Clipperz.PM.RunTime.mainController = new Clipperz.PM.UI.iPhone.Controllers.MainController();
+ } else {
+ Clipperz.PM.RunTime.mainController = new Clipperz.PM.UI.Web.Controllers.MainController(controllerParameters);
+ }
+
+ Clipperz.PM.RunTime.mainController.run(shouldShowRegistrationForm);
+
+//Clipperz.log("HASH: " + window.location.hash);
+// if (window.location.hash != "") {
+// window.location.hash = ""
+// }
+//Clipperz.log("HASH cleaned");
+// #credentials=base64encoded({username:'joe', passphrase:'clipperz'})
+// MochiKit.Signal.signal(Clipperz.Signal.NotificationCenter, 'doLogin', {username:'joe', passphrase:'clipperz'});
+}
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+
+var proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+proxy.dataStore().setupWithEncryptedData(testData['testData']);
+
+MochiKit.DOM.addLoadEvent(run);
diff --git a/frontend/gamma/tests/tests/Components/GridLayout/GridLayout_test.js b/frontend/gamma/tests/tests/Components/GridLayout/GridLayout_test.js
new file mode 100644
index 0000000..1c06468
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/GridLayout/GridLayout_test.js
@@ -0,0 +1,119 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.Tests.GridLayout');
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+Clipperz.PM.Strings.Languages.initSetup();
+
+Clipperz.Tests.GridLayout.Tester = function(args) {
+ args = args || {};
+
+ Clipperz.Tests.GridLayout.Tester.superclass.constructor.call(this, args);
+//# this._user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+ this._user = new Clipperz.PM.DataModel.User({username:'joe', getPassphraseFunction:function () { return 'clipperz';}});
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.Tests.GridLayout.Tester, Object, {
+
+ 'toString': function() {
+ return "Clipperz.Tests.GridLayout.Tester";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'user': function () {
+ return this._user;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'run': function () {
+ var deferredResult;
+ var proxy;
+ var cardDialogController;
+ var cardDialogComponent;
+ var component;
+ var filterController;
+ var cardsController;
+
+ filterController = new Clipperz.PM.UI.Web.Controllers.FilterController();
+ cardsController = new Clipperz.PM.UI.Web.Controllers.CardsController({'filterController':filterController});
+
+ component = new Clipperz.Tests.GridLayout.TestPageComponent({element:MochiKit.DOM.getElement('component')});
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+
+ deferredResult = new Clipperz.Async.Deferred("GridLayout_test.init", {trace:false});
+//# deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['joe_clipperz_offline_copy_data']);
+ deferredResult.addMethod(this.user(), 'login');
+
+ deferredResult.addMethod(cardsController, 'run', {slot:component.slotNamed('cardList'), user:this.user()});
+// deferredResult.addMethod(xxxxController, 'run', {slot:component.slotNamed('cardGrid'), user:this.user()});
+
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'saveChanges': function () {
+ return this.user().saveChanges();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'hasPendingChanges': function () {
+ return this.user().hasPendingChanges();
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'revertChanges': function () {
+ return this.user().revertChanges();
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
+
+
+init = function () {
+ var tester;
+
+ tester = new Clipperz.Tests.GridLayout.Tester();
+ tester.run();
+};
+
+MochiKit.DOM.addLoadEvent(init);
diff --git a/frontend/gamma/tests/tests/Components/GridLayout/TestPageComponent.js b/frontend/gamma/tests/tests/Components/GridLayout/TestPageComponent.js
new file mode 100644
index 0000000..a98f041
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/GridLayout/TestPageComponent.js
@@ -0,0 +1,102 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.Tests.GridLayout');
+
+Clipperz.Tests.GridLayout.TestPageComponent = function(args) {
+ args = args || {};
+ Clipperz.Tests.GridLayout.TestPageComponent.superclass.constructor.call(this, args);
+
+ this._element = args.element || null;
+
+ this._slots = {
+ 'cardList' : this.getId('cardList'),
+ 'cardGrid' : this.getId('cardGrid')
+ };
+
+ this.render();
+
+
+ return this;
+}
+
+//=============================================================================
+
+Clipperz.Base.extend(Clipperz.Tests.GridLayout.TestPageComponent, Clipperz.PM.UI.Common.Components.BaseComponent, {
+
+ //-------------------------------------------------------------------------
+
+ 'toString': function () {
+ return "Clipperz.Tests.GridLayout.TestPageComponent component";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'renderSelf': function(/*aContainer, aPosition*/) {
+ this.append(this.element(), [
+ {tag:'ul', cls:'testTabs', style:'', children:[
+ {tag:'li', id:this.getId('list'), children:[{tag:'span', html:'list'}]},
+ {tag:'li', id:this.getId('grid'), children:[{tag:'span', html:'grid'}]}
+ ]},
+ {tag:'ul', cls:'testPanels', children:[
+ {tag:'li', id:this.getId('listPanel'), children:[
+ {tag:'div', /*id:this.getId('mainPanels'),*/ cls:'mainPanels', children:[
+ {tag:'div', id:this.getId('cardList'), cls:'gridComponent cardGrid'}
+ ]}
+ ]},
+ {tag:'li', id:this.getId('gridPanel'), children:[
+ {tag:'div', /*id:this.getId('mainPanels'),*/ cls:'mainPanels', children:[
+// {tag:'div', id:this.getId('cardGrid'), cls:'gridComponent cardGrid'}
+ {tag:'h1', html:"Ciao"}
+ ]}
+ ]}
+ ]}
+ ]);
+
+// this.append(this.element(), {tag:'div', id:this.getId('mainPanels'), cls:'mainPanels'});
+// this.append(this.getId('mainPanels'), {tag:'div', id:this.getId('cardGrid'), cls:'gridComponent cardGrid'});
+
+ new Clipperz.PM.UI.Common.Controllers.TabPanelController({
+ component:this,
+ configuration: {
+ 'LIST': {
+ tab: 'list',
+ panel: 'listPanel'
+ },
+ 'GRID': {
+ tab: 'grid',
+ panel: 'gridPanel'
+ }
+ }
+ });
+ },
+
+ //-------------------------------------------------------------------------
+
+ __syntaxFix__: "syntax fix"
+});
diff --git a/frontend/gamma/tests/tests/Components/GridLayout/User.data.js b/frontend/gamma/tests/tests/Components/GridLayout/User.data.js
new file mode 100644
index 0000000..6fec8c9
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/GridLayout/User.data.js
@@ -0,0 +1,977 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+testData = {
+
+ //-------------------------------------------------------------------------
+
+ 'simpleLogin_001': {
+ 'users': [
+ {
+ 'username': "joe",
+ 'passphrase': "eoj",
+ 'version': "0.2",
+ 'connectionVersion': "0.2",
+ 'records': {
+ 'record 1': {
+ 'notes': "Some notes here",
+ 'fields': [
+ { 'name': "username", 'value': "joe", 'type': "text" },
+ { 'name': "password", 'value': "1234", 'type': "password" }
+ ],
+ 'directLogins': {
+ "record 1 direct login": {
+ 'configuration': "",
+ 'bindings': [
+ ],
+ 'favicon': "http://www.example.com/favicon.ico"
+ }
+ }
+ }
+ },
+ 'otp': [
+ "12345678 90abcdef 12345678 90abcdef",
+ "fedcba09 87654321 fedcba09 87654321"
+ ]
+ }
+ ]
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'joe_clipperz_offline_copy_data': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ 'f527cdd90d0d47f8524b4e165398ad1455eba515d04abd101d1e93b3c6ae0674': {
+ s: '186f0c40bf73f2af236eaa6c429df225efa933050c9aae65240e93b7b362e3ee',
+ v: 'ac61a6e325ecf329926a86084f591d8852d0ad3e4a6080f2adc901b82395ecaf',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5":"0","13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551":"1","062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80":"2","ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c":"3","507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a":"4","d5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d":"5","de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4":"6","d620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045":"7","f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732":"8","36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113":"9","fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6":"10","6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18":"11","9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291":"12","6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a":"13","6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728":"14","8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39":"15","084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d":"16","7bb69b6366a8012f181c01e368ba18d4f7a82bcabb4959189736ad124c4bbfbb":"17","5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4":"18","c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065":"19"},"data":"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"},"directLogins":{"index":{"61e87fdc4f1d9112e3b30c1f6812d095dcdb24f014c83319091eb6c9899ec348":"0","989593d4c48929f0c8f1581aa96969c622807e99619ed4732026e967530a68ad":"1","9f7979368fa29f66c44bd97ecaf6c545abc800b1c7bb21b7655a68e1514c3906":"2","dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496":"3","aa18149164302d5dbe7e2d3724565b9550e00887b49978559783b2e38c625584":"4","1f9bfd677b531a03168d3f8bd8afabb5357244a7bc355dff50bd6c0a072114a6":"5","a48e38845713462ecc9f827149eeaae87da882031f98ef8ebbf9ee9537b63468":"6","6f7bbc4e42ea462b5246e6f51c3f86056bec50601ce2de6067c8c1d26f21c07f":"7","2df54059e78f5771f23bd285cce19595b38331b73d67020424d9a1b2257db09c":"8","065cd0c270e5e8ce50e4ea8e3828dccdae18c01ab030813d756a87d03fe68784":"9","ddbc8d01300a4f10631cbde09e1246332eade3a877a2205209f9eb9e5bc9da0b":"10","9b7a30e667afc9f76ba77600658b2c13bff52432d444261d39bf3d069a160afe":"11","9fd2929cde3d32d9cbc5f1d787f2f64729a5e12a14410556b31c0c099762c46a":"12","f695fc36ac56bead80c0d20a88e01e382819c18dc268f1679551b7c83db7cb14":"13","f22dc41ffabef4b3bc8f7af804fec975bd50718098322a673cbe4aaff9464ae1":"14","03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c":"15","a7b32e72502804bf2946a2a8856139cbbb759c5777e6b3e673db1fdf7e3bd06e":"16","cb9ae0bba1957075ccdbfd3b3481704d62087687a2ac7c411a4f07d444bde0f7":"17","7e1d069b7fa57c03bd7bf48807520feb953157834503aaff8c9d493f37dea69d":"18","24404059cabc63b2dbff0f42ba57183108b8189ef53ab62fa25141a1caea824b":"19","33cf9758477460a8056deef0295a1ebe65b39b392c361ceb920a83edacfe5d78":"20","e9a16316f330e3d150f6ffd194f6fd8acd1426757b097de4b88ca0db875202e4":"21"},"data":"xuiWbu5GjkueQhyH6sKg5Cn9/CSsPIjYgbhaHmjgwnnB+GL8UO5u0uURxTY6tkG2HbaFRpYZwLnqUUulEkVY6iNqJajFI0qDtrKams11cF2y9LaAalbqyv6U7EUt76d666DkXW8tf88nJ4HYfyAhhPCJ0cw5053K9BAVPbQM7fMA4MYY29k45U3HcIKNZcNqMftCc+fZB+fmZl1g7mSbrXaZyagRkwWwTdJ6/ecVOSSVOkWpckAaQWzGhwbO6zVWLtR9XQReIQZV52TwDMnV5IYJHnlw0Uvv2ZCVSu/oMN2TneW5fcIwQ0x/SRe+n4Mklzucpvasza+ZhRaRUFS53kvmbfPFI5tXqB3Z1+9S7LRLr9Ws97suTQ6G5eW6jKT2vf65ehnQJtA/gW6uwH+3IAT7ukFxO1knaRf7dRJDLuIc4Xnh+bRDnZUqfA+B+04pp6r0OS9oysD35t/HydVFeHgoyMCbL4RzduZvmu7y16WhIznn0DEfRmrYmC68C+DNcAbxeiXU8v14PgGycIg1++0v44Qor/BXfP5JW4WnYjVLW3aXN3FgI5rPuN6PqTzMn7z+eF2V28GNss5pui1xIbR2bTECAAnaRQiaz98F1LH4z5kYG1ehmyjIOLqz1nAv3Kuo7+DZKaSez4nX1oWznbXEnwd6uguukcCGpQllZoHYso/fz07e6p/9fskXPmg7LnMMHApP7Vay6XPhXV/AG0imU7uREFLbgnw3305Ey9fslmD8qCzi8LlqNALEt1TFNpAukvqodkv8V1o6zqzYNMSKaqJV4E9dWMNDpOFFTKv1FuZjZfzyPwyCcePgP7vcJGtUSYqRJwl56Ia8UA+l3FBiX8DCSW3GkG+wusf7bZ5kV6lV5DQJTScIyFxWwcECJ5S8/2QaBPTopeLo2NuMmFwjUwhBGVrDkUmtqjfb6DSfr/dR6AbmraRLXrpd/KUN7wWgp5GdLUAKNT+RdsUc0mLsLF3oT+XshfgfsQqi/pDnX9x3QfH/WuRtoywAIE5APU8Rnl+1NGsEidzeYrBnryA8VRi9vxfhuaxe3+rx1ewB1pgVSERPLF+0MYtetug01yRSxEUYJgYHxQmfnmkCoz+kKCejdpYVqKC+RzhjIMytRbFXNmS0NpRmtBxZrSIskKXjjwjUeEzMAttqAPC4IK1kt5IK+5NZPNZbf2Y8qDsWcBNXfw5sh7pJymRwPCge+S5Jy69tadeSAWpX1YMuq+By/o2KWawpokstxmE6w2RNPFhKXtGPvukoDnpV9wDFgBcoNDJctDVdIPqNolLxn6Y57HoOid6CO2s+PqQcfZSEo7V70Rk6OQ+02M0ED0/4XGq6vflc6IlQ5LO1urRT4INrAQmWdulHnmLf+HESJAc0ZICO1T73aQVaGVVHFQxDMVgaTer1UXP1xxfB1tazfJme2aycsDM1WS5lTwMRRlvgwupkzS+YwGq+nB1QFsZknKgeoacGYxQjFo6EGvszitNU+sK4U/EeAShS/nM/96c10awZVwQnal5T9sYOO31mA2pxyI4TwxkgWw2wkj38msz+8afHvPlFlqlU0UiEm7hYMj5s4L08msIY+GVc7tGgaRYklsnRFUU6s0Kql8BLPkbpdM9RAoSczy4tlGlaBAPeC6ouPgyNf1+VRfVZnqlPF063ok1KcEbd6QqQHo0kgsUMLbtdPbe752dmUo64sZXkuDKISmFEwQjn3SN4K7OOg9sk5QEz1STMvm8pazq1yb+0CE1iad5e+HoNkrGT+5GSVX+YShiItu5eyZXjZ7m8GQ2HZTA7mgv6FwGSI6o0URPIRk/UgKMCggTSat2gf3oVk+aZvRCvkGg+ISjkEKk49tQasLDAfvVjdue2JHpM1UwNhTlurHNasqnwNEzFzhflsMuM+V7dv/6/3AiJBUSC9Oyd/kWRpt5DS0nW+BkBcL5eBoofyssj0tAqxpWe+nNwCL9ljVPdytQCHWp71xEqnDxSq1KWV7u57MmBSaGStdyWtShBvEQdHQIDpXz8HVfOWOxQKttNYkupVJcbYhHNicwLzc3Ox1TaT/trfkmTXT80XXfQA83Ls1VVsYKjHDBT5/bIOx3IzjS0KNl7C5E8BuggSL69t8ogHSOKwH9CugZje3vj0BuzhZsl65k1i/pNS+vYwOifv6BhhbgWS6D2s9+a1Xi5YLGLE/EvMlw82N+o/owUluZ2vhekbYJ0HkuyrL+18l0L5B+8iJS62LzdD+hC93cGxqD9RVQA37yxzpN33l2y6teSrypYU7j2hMVv1l0Y6JU0l5itSdWT3VmWyHzdKLYNFjpA2WY3UgvsWRTJfFYzFEYUu2V6OqY7HzUiuKcVTYwB5Ky2qESzmIFiLRv0E9E+fVoYTKjk8v2gDaNwKWq7AJTabgeNaQVif3lUdZ1oQerb6aRc7PBBBKBD1YE3S8+wJ6C4MIs+XIxuJvjhhbOav5Q+G9Tk251dlt44cWQ61sCPi5pCMAgzcwRH2+ZQOZeYslt6g4XS3TorVlHveIpQkBOPvzO3fUkfUQzKPZ1QXFIBZnTLLIcsV+L/tt5kep9ucrqUjNcREPODf+nM/mQlfLGT8SLU9r2zMFkMm4zXNWswWTsXO7zm1YEErAtyggWff6gM66wz1dnNMiVXMQ=="},"preferences":{"data":"EZMrwxNFFd1sMGycoYE7IrlGGrfLixLUnLZmWMkFysfISe2ay3ueO0PGCApuKqh9hA=="},"oneTimePasswords":{"data":"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"},"version":"0.1"}',
+ statistics: 'SfGy/4mpXQdDOv+Bcfie4Yt/',
+ userDetailsVersion: '0.3',
+ records: {
+ '062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80': {
+ data: '7sgxSQlqR+wh3g06M2+sWp7raQxjjQ9jLIz2OcEB7SckuQcXNrhMlDCbL6ncSljtzgqhioWrOB409kIG8lc7h6ekghOE/Mhi7rVwAiRfNGB7r3mYxpEXRe96O2RG7E+NcSp8ezl+5gJ9D0o1abXPeFQYGcr95hUioCfyY+xrxY8TJVwdb9nHkYvBdKV7rCl1dTxgsKWK3nlo1T7e5uyiz5YUAE6BrCtTFAqtprLI/xOpRti9C+llohS7D6s8hkCBPZfp3chKFDrgpsCBFLhXN8jrBKSjHi1PJdRQzpJsgrxyeBj0dZx3gTsYOXqrYgdIzFUo7K1Tqb30yNprBiDMr7j0YYXiSvEb7OuOIP+HTXGN+yt09bk9LggyY6Fh0e+tenjQQ3soySN/XznOBpEjXbzXoz6fR1MXVnE9GgaX99LVNqwWfq2rIBdSE/FfspRiWP3BY5jIrEkNeRclS05U1zw3K3wxOL+cB9r2IynSXnK8QcrDNNRZ0W3PhsSFfByUXuviLSEOPuJa1mYP29L9Lj/WyHL1Gyl8xLbt2H41S6+wvIleKMuc7teH6wPXbnYphvbwBowoI6HZTEFkz3dQKhhY6VF/81iCXsuaz6BjyrzFX6SkQ4S3lN1tv4opQMJFvnmHb6EkXqVWfeIXzJIJO+owL4vDOf4okpAD+HPjjlVXhq6fvyM5UBIK9+tzJW78X/zifrQOfWRIhwjVsfUdZWmZ/S35vnHWNuXkM8GBYrDysqxanDtah3U8XLAiIhFtBOzpzr6qGaNDOKKgG3K8QXT4bYHOq1rQVUwzQuKhlCyStrRMQrC5Ry251xmLy6dKfppRarVeGDtzB/30BbtFNdZmzMNG2g+Jj5tFCrEtCMvMiQEWZHMU3tGMFxDef/KKdv1fFTJC16jmaUiCHUZmNjB3EO9R6xPVcMlAVKf57n3efrpRk/GTmm9JhAFkuF/wsveH4JjPpDUdkHYFu5tHbb30sbga3ufBAXbQL4ck10S24akU/cKraFGLvuKGaR2U0i6ih911TBSf3pAfZ3RFbBhVIl+6rSknC5+IXoBR7MRstBPW/xC9pQVjN5Qyn0g3aUjUSI+q4jcTuvMl32NtTJbWRMGhfkrpVzypZTyPnIh6XJkyBghlUARXw23MlbjiZxmY4ScDmcWZRZJWIknHlqjDKFDKNnwrfnEI9qWyMDno+jA/DEQz0mnpdZYEsoz1/qAmAeDt89vx',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 PDT 2007',
+ updateDate: 'Wed Mar 14 15:46:44 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:04 PDT 2009',
+ currentVersion: '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3',
+ versions: {
+ '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3': {
+ header: '####',
+ data: 'GCNNIhDQjMJQZGVSf+95fPtU6eOnFWVhuGm86r8WZGVR2Gf2EjbG1OJ0ZIGpZ/AXgirCMpo5AFxJe0Bay8IYg+xmBqMFhwFxzAgJBYCIts+raSaNRipuY8dTEqDxAqD1cChcG8EhSoiFgQ0fG0I7nNEUDJi0pIt4/ygBcwvAhuAenEp9ZW+oQA0+YysPQRqkz3IieFaOoSEbe5/SqpUilV4q1gTVyzNXvrxzxx+rlvEyGFgFN+vgtUZ1NrwlPk4gVksTpylvv6CFaMGEWKhgMG6efo0rJckKosaJTu1pldJdnmMK4EKNMLOd+jZ6pEhEhYyadrA4+zYU5TlmZA6ASzTaps8piSwZodoi9qY0ch2StK4mAbzeEGe2HdfHuAU9Tyq3Ppk3+VfNdKgpQfYrQOiSlXbKzK636tzXTN/gyrfOTHjBrRl117ywibgSX63ayAYNfcLpKotC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 PDT 2007',
+ updateDate: 'Wed Mar 14 15:46:44 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:04 PDT 2009'
+ }
+ }
+ },
+ '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d': {
+ data: 'fGzBu1On7e/6rAoSB1a4fq/CkS8Be/T8UP5cQ93asBTWndSYu2lW4DQ4SXQXSindIi3OnNx/f6SNv/extb7OrMLREF92wXI045ipPwy+DIICb+cQNMJ82Sh4cXaIcAWcyrm+MYri3qq9LBKbpwkILcebZidJ86lmKYHJozUezmfbMcwNCljHs/gYkHVzVcuw9L52Ugc6wC7sjsshh+UH6i4/2Frlrophtx+b1vervNd8eoYiKnedHVXVfW7UJcQoF27eHFgzwYnGvRW0KNXFFhqmPb61TSkIvNdCCvBKDP4SXrWvGgzU89wipvWdUPpQ+fCT6Mp3hPRrbJxwMunmjujZOzBld/HkjnXoiNfBb5akA280WvdyzWYATrjV1ZFx8yQY8G0+lRt/MxjKDc38w4y+Rf5WeRbXboJMvFatwooHUggk6qSRmZVvgOmFmNuDRnRYIFzqK3JclhJeVasnqhR6RiGSowc1Ffr1HhcZCMnXpQABGBkZcHD/zw6YjHRyh9Plw7XAm0xb16HMDtiwt7WLJpxLH/HP99j/A2hvMGWiUiFCaYv7AzyEPTmYbN32D1IsAEE/GC3FG0HypGTBolP8wpAfTRdlvWpJz8oRRdwuLV3Pgpu+kXh5sQyeZI6tnuMPQFmRDcMN1oo3E5V5V585nVMnKTFcXhBzD4UnoV+DQNkG/+iSPybQzz/EZmucEqGEYyjI3kl4MAX8UMEUxE4JO0fF8MzyBI13nxknowAceEammx1dGVaJCoIOdhadaPVPyOzXM1Vp1erVm5k4TsxSx1pll+GOm6hVoNHIuQLDueaMEpRxMhfwc8cDyXURqRGPTgTc0bint5xVjo10fnpX1gcdc/AWL6y3tXM80NW+uFJ4GI7VzyzfcMRzTiRaGi19z8MIx8PbIVGh2sw4FhgGujNsPrpuESvUVT+17M0+v8oEoABNlcizTMFs/sA1uqlPumFASltzmViAzClOsDuCh069hFLjdk/Ex5jy4vPYlwOT8Uq9DJC9ZWuZgiI1DrhWN/8QGAEGxxbvnSZPNCQ9kpD5p+iabinLLWOAirVNgKwIRJRyAu/uR9xKd7J9Wxq8q/ii+y5lGilbo2g24wbDwrkXYVhqp/4J0g+p8Wv1NBjCTSCqV39WEizUCRHo3ee9HnQnBJQDOyTBRuz2odTJtJ5tLYjWXZRdFzFSJrEq+Z1z3oq7LnhZy3YWaFXPeKmBCemMthtNt0nL',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:49:20 PDT 2008',
+ updateDate: 'Mon Oct 27 08:58:49 PDT 2008',
+ accessDate: 'Mon Jan 19 16:09:39 PDT 2009',
+ currentVersion: '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac',
+ versions: {
+ '0ae362285f103722abbd046eee2b7d10aeae6a1d05cbaf2081392ce9df882bcf': {
+ header: '####',
+ data: 'sG6TUmPSEPFpiJ5YdtghWHmHbvUK63tZCZ+Q5iz2ALas//jN+lZCBhZcjEwPEJskBkK2R0MyAh14wWGh2bBHMjsokgTe+L+x+0c/Zi0epE/IC9gtOBhsTe/hZ2e2xOGF/SbzET3DAAYXvxduZ36f7SvvFnrkkKvpj8wGSdTFcBmzqMb9DL2bRyRCLGLMzE3F1a0q5CufCIRz2TgHm+Uw+kfvvwC7ig/F/5iLW90Ypz3vmEtMEFYFHZ9a8Oh0rsXGfevbMhFqALoywzihQEe/NiB8dwn7GEdYKSQ35rhvZh29ULWOZinqmg0ONe0HYaxx7DbKsVoue57S0CIUlgHLajzHfLfqQg2sFI0OT8TnHsGg0YZ6mM2EdKmEjJiER0cP',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:00:31 PDT 2008',
+ updateDate: 'Fri Oct 17 17:00:31 PDT 2008',
+ accessDate: 'Fri Oct 17 17:00:31 PDT 2008'
+ },
+ '10f45664bbd979a92f37886f1ecc6e52e49798b16dc997aecd37259ad9b2090e': {
+ header: '####',
+ data: 'RdKVaV/WWWchrCse3KtcXd47Bfm6IAwjqVUpaxoed3HeunI42AAm7xYYSjeK8edHpbNRJbhobBAX5OZtWIp/HmgkobKM8CIiWxrWz89FqyrbnPD7+fXdtgF2yTax/0sC1l0ibncdOuJKX6U829oPlXCpXIOjlomc4wEEAD/5V6FbORvdZ9IE/ME3LsG2y02cT2tIpx6+R6wC/PKXhZA2UDsTE6R2Op2BtIzpVORZLXsdyAp/4wvWQxq90i9cEpbsVQsMB10JVyNHNsRTFhIlHi9MVCaMxQvcrwRElMj/Y9x3RbsFzSGKqFLqdg7Fn/U+KYkpYtsgHv9hraPIb9lV5FH16+iItU/HBM6FGezIj1ZkoQ+dgjPfSjTZzgzDYwyb',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:49:20 PDT 2008',
+ updateDate: 'Fri Oct 17 16:49:20 PDT 2008',
+ accessDate: 'Fri Oct 17 16:54:23 PDT 2008'
+ },
+ '2fa7b67e569d5e268d2b70b3d4d3a960d7e437e1937bcb324b67d0b9441db8ba': {
+ header: '####',
+ data: 'dpnI2qKjk0+bfyKktw4ZCWf+rWZ12hO5bda39CwD29JH7KtdpLCLe2LoLd+KKF2wOdpDsoI2iTiwRgFpt77e7DoWJABxq/0aaRCVN9XpqZo08iHiYhJyNlIszO8CdEhX+M3AeZqzTnd6fs91VfIEWggvku2Z+jwr0CbclY6FnOcNnS+1fj+W79Z9XC383GOm2ujjfo3SX/fyNQSw8aX+7AgJIRGR9uHK7M1cVfsNNTbmDb/HDgLlYZ1Pqm/9poHpmS7G4HUoRM2/WjI0R6F48dy5s8vZRi11SCnlnj5oRykScJj6wh2DltbCyesiaTpAjP6MQjTXsZzKpaosaQcQClZw+w6hDD2cA54IaBIv2j5KAHyhxDh2ERdwbdnCsDKPz4+zP+fmKfW295d4OY0l1NCSdcY+75HWTmBWRAooZeDTo7AE8m5sRwxewE0Y8J2MLUYsrs7Rl4kbZCiRRHU7cs+us3fq2DVn2OLGEbkRrK3kA9swT9W8ABqINoA79+DmDaIr6TGxe5AlHkCAl5sYAN4g42UX1NKhl4fWI1Scj9O1Ixds/1UUvqzavld0mE2cR9yt6LntjE5sQSAaexvymAJbU5IIM5NTk7NlY7G3PEvAPjcUsL9SGw==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:00:13 PDT 2008',
+ updateDate: 'Fri Oct 17 17:00:13 PDT 2008',
+ accessDate: 'Fri Oct 17 17:00:13 PDT 2008'
+ },
+ '5a17723c34226d8cd663f91b11bfa14979e694e461818113ec8abf7194b46b6b': {
+ header: '####',
+ data: 'yRTvhkoY9zDRBwFYf0G5U8zhfS1XWIUfwes6ADNnFyOrHOr7JZvZZHSgkOPnsmN/f5ngcvFaIV9X3TNTmmPLzD/ewgGVMR+ofMLyOIMGhxUDzosSd1+HKqwDZWneZ6xNsci87W8UCfJgoEGrkAtAwktqyS04pcAas74XiRGBWNcv5mHZONwGPckYUnnaVG02Zf+qif6Pp7ugdvXrgncO5oi2AMSoR8GQxMP+tX53YzLwOpabA32PDT6o+aDPwMstJNQjWCXjeYLDIlb0GjL2zgjglX5CfdGw8vNT5hwGEK2D1FkvHkw79m++9sOWd5w9WdGgtS4mrTZP3JHWC1sPqvsIpq6PsrzRrbfCFH7C4X/ya5ciOIZTCNl4dEGAif94zgN74ueY5BF31PNFtaRaQ1waKkbsrU63MrbQbBar9b0hDZoser3BdgDGb1Ecc2GbJM1HbDITttmFDrzy/Ugh2kistHx7Dci8IGgfT7K94TntRFc5R6suEqYRrmOn57YJTZYrwSgbeTqAt/KOE+gL9LawiLJ0IdSC2RQnO3yu/aOEThHxpdLIKiVJoiEQXYVnq2UpnO79GNtplNnUe1hETQ/JT0o5X1bbENyInUsFjPuitAfChXofkAysIhDOHAdifc0Y+pxOHbQLkL65ZOsEDXWSlwMcduMNdQm4LVx26GLIV6yVsaDN+hGta2CxUuSvEIMM6T5xhaPfJ4K57LVw9MbOjRXpmFQz3QgEr8ZZdUxgE+Kj6CtmsjvzXtCQ3Bv/SccTLJSR/LQ8XRdIcPoOlDDy5jSQDF/8lxkgV1V7M3+SI1iWESPT8My5C+RH32F2MNZzthYq5hIFUB3wsM/AaQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:59:31 PDT 2008',
+ updateDate: 'Fri Oct 17 16:59:31 PDT 2008',
+ accessDate: 'Fri Oct 17 16:59:31 PDT 2008'
+ },
+ '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac': {
+ header: '####',
+ data: 'RgIWPbNN3sPkIPBE6lfvf9/EoDFLemTZe0Qh/1wZLrKxLRNzFpUk9+NmeGUp5f1hM3XjXw4cXRvP6GrWq69mz9zGja+1TA6RoW3dFMpSQkbONcrSD1mIjxV2zIvzA/Pangz0ZixbEeHCfwXLvgnevbTXXFjkti3kLHQlk2pJpM3zMl+rMJtcsefszuJ/0tE/bO7sBcFqcYgKAht2OyDQORBAGiW1kI9USKM5OOfJJIZDQ0gDhRgl2U92l3kIOO8hdnj32oRedwfKFmdSRkuMY7ykU0bMuVEVkLi/FWmhHxi66C2ovAztVtMd1IiyoNcHc4UH942GC4pT1A8YQpIHxBAJbrQVhpl9LfFkmJ7xUc6Xs5j0Nv8+z2JGCnJI/D4nDJqYW+iCYtRWu6vUmbg0vGfaYWQFGRZRk8zWfHzHXBvHU8p0QsIjYgCLKiUaU2SRRD2P7JCjeTUrm3I1OI593iPsEH9J2PHCM9OMQ8/Fsdgd7lWgH6P9jLdGUwtb1hGaq8mg3JGrHFXcrVkUEBfeR7xljeSHD7j4YahYrua9EeR8nvq6CNaOr406AWyHse9SXhaOxt8qXRLoELpyQPsaLgafUpsdLjJqHz7J76Rp77NSOtXGplKjAtU1xj+d/agaAKYCjvUJC8/APJI2890Pn7VSXr/TPc5biPEIopyVYEHFqaT4e5nZW1Ku1HXC9gwUwUI9rITG4GzIH1WMEm7oFLNUaSMrdK/UTdTJZ66ENE3B9v9cTUpR0NTkbI+iGKDnc8GHPRlr2ZJwN4KFTxi+o/kkEOBjvRHR55nRh2+dke75LS/fzHQZw5wlyqBv5ZeUZfRA7QHfkj9acR0fJSqqNX25AUzZQnRL3oVpOxFWCMU7QVf5VpnRm9OIOd/5F5EoY7Be4doM/UV9U40F3E6XPZQ8S0GKQzrDjc7jKyGPLNPLUWTmGB39mTNDHZQHh5Xv5Q==',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 08:58:49 PDT 2008',
+ updateDate: 'Mon Oct 27 08:58:49 PDT 2008',
+ accessDate: 'Mon Jan 19 16:09:39 PDT 2009'
+ },
+ 'b57a2d2ffafa8029123362071c09709bb9192f06a17140440f0e41d22143148f': {
+ header: '####',
+ data: 'PQ53T2Vo2D8PoLI1qNX//jLaVZFTDTYk6geT9+4RoThTxvlJ+beDPnQzgYhd9iASaF9GQEEL8JxsBnNpEPa6JPOY4ndFLmDLyFDKXMprxq1UIbzFV6kFoYAk3uCCCa3UCDzdr1KXB2CiiF9HrilaA+xkm8krAvH8I5kZD+j23gByz5cAFvXg7A77KEURpjujURL65DW5M+ceIjo6OXaPW9VO03xhqGt/M47ayObpoEGJZn+X9C8s0SE5wOXHbn38YZlRI480OMvtDAxbEYUeQKMmzu6lO4Nw5hhOUjoPSLr/i3tmDx3nPcDwnSafx6jyA4y31eW6yazqTEOP5I5ArC5mUrF7mAAiFvbHIsMoF8PLj6MONlRIOZgbf9HzCpFdt8xBrX/TXp3LaSAj2XTWgSTFI2cgmU3qqPyibvIfUsB5cVHQCXi692JpC+B85axJ0FLyMl5w3vq0txlPkf6q+dadPYDaLHGZEmDjkWScA1GM5xPJHWFwqGE7ejgXKG0sMYsMKWYk+F2LEUmMHtEvSlpgJBntvcQ1ZjYQxeu4hg5txu1ykkif6fXgkXF6wn6qu+5caeJeNhWtAB4q7WVD47111woYMdkmX7AnDTXSAQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:57:17 PDT 2008',
+ updateDate: 'Fri Oct 17 16:57:17 PDT 2008',
+ accessDate: 'Fri Oct 17 16:57:17 PDT 2008'
+ },
+ 'b713e0a1e2664ac7bfa7ba887329ea023204d10298973e322983b82b222debf6': {
+ header: '####',
+ data: 'H3gIieYrH7Oy8LEWCZpl9vGp9qYdHNCoBNGijYqlcfXt+1JYvPj1abPp12xLNrDUHfaOZklU2Ip4tOf0CDNhgAan7LYyPqFoy9ss2f9/5RLcbjwiIwSduySIL322HTAwqlzlBt/qaJdHHPUrczmu0fb7fT+0dO4gCL/e/IjcHLefUUgNPAbpHG0Nv0+4lNwKZkIQM3tLRtfJyFBIgWKcMcP1XMic33kr24rwybR8Pb0CHZrOOvvUiGqyoED3ZTZf1twUDVNXO7MWCAC5dBc6/Mk/vSmbbGhppXAH02N0g8G5qzZfp3UVikls55VNhRYLHByVsgpkbIrKXyZnBPTwzm7qefpYAXDOgO+164L66/Art2FYGqZQRZLuh5r8oF38',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:58:00 PDT 2008',
+ updateDate: 'Fri Oct 17 16:58:00 PDT 2008',
+ accessDate: 'Fri Oct 17 16:58:00 PDT 2008'
+ },
+ 'c4cea1cd88a86b05f48a99896a37967c3456228283a0406331ca9f67c6f29f97': {
+ header: '####',
+ data: '1znWPwc9JwCe7iOFiUd2iGm4xJd+824B4VRqEtzCQkW46tg25RWfo7XagvK46USB7t6pC8WMLU0M/EC47KucsfpWUqHGbseoXT/8g8E8GoLnIsk9qFyJG7LGd1sUvqBgszLZwjWWG3t9zifmpW5nY9GialBYNmeSLS3bg5xDH+eCEilUUfDe7zGuVSuu/XkHacv/DYUst97e+6u44F7H8Kv8dTywJZpqbmveNPeWfCej2aBXdVV616J5lIRaj2uIYuQYG7blYJh9KZ7yLStdPndl6h65hIJpfWo0PM8nLJuo0lWNHz7misrutnmxJEjkwVIZ5YAmqp1Zz3VC8zw4IxkXrC/sPmp4PaNXgKz9ZJRaY2KV69WmHf7BUQ3QneGngbT0tN526SS5qDFwTGiuIlnYGWvTB2jVrbns68n/d8Fps8sSWfJBvvXJUEkaZB+1WqNilOPGXvyJ5k2O/iucFbRlxwlEHDny+AgsbtXZdp8cHQ4C/O4G0mnUMZuS38gn6e2kQ55mUhxKeORM+J6Rx1y4Iiu9KKNbxyS5eBpAlFB4xS/o35CS4g309vyOEhi37F24bpp4pM0xEPG4mcc/IyChHzaHUGEp1IX1ZO/r3ut9RIN2QWrGLUlZV/9rFKpLLAy6BkY/g8VYNrV8PztOL3rqy/qwqNZouONwPw8w8SA=',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:01:59 PDT 2008',
+ updateDate: 'Fri Oct 17 17:01:59 PDT 2008',
+ accessDate: 'Mon Oct 27 08:57:58 PDT 2008'
+ }
+ }
+ },
+ '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551': {
+ data: '0/BjzyY6jeh71hwgASQphLMgnLz6WJJPg7sDskLKo5gCumpebgHBPqN0OPyHqTq4Lyt7Um++ckx2VA4yoX4cojXC7FBnscHtN18RlVNRvkfhhFPWBZhFwuVZxlFNb/IueDSjKR3dJahbTqao2AU3HXp0xOdsO5Mb2CfMz1/C4rtDuv5ee7GJNEv2hb2tBTzxbB8PZ/TKYZhlfgV3rJ2Hc509OeX/PuD8oYB7sUnB9UhDZP7pVY0Vz3LP/dFUf1cPGFh7bnxxYNphpJ2SxhIUdgxpmP6UCFxdLbCBXv13+7OlhCaO2eGfsO4Qch996otkSrVxfTvOTLuwiwSqU7hLlvOSzm9in69Rf35ZC7bKcZIdZkTNPeV0a+dR6j3LY7dBvIzd08OtBSqOdQqo/6isG8vaQPLVcWkFFZ//iHGgjTIduSoyzMb/y9cr8J1Qj1uTayUVAHQywCYdKgT4UccLoyt96vKHRcPCw6iepEfSrc3aZOtTg/aS3j2CGTih0i0gfrA4EbeQtIfobthsbTF6Oq5xjrIAMv2LRiJ+8JPj6xw8ODvM8SUN/3UxlYKsqDpWOW4tOztQAMSijoGtBswIl+mLr2p50Cul4n8ENfrilyAX4AcxUFSbH6tVd19ErQLsj+T2H5qhIF0Ifo5NxL9bj+Gx/5ul6dGH6Et9dvaHv+CZ3FKc7wrvItd6GXexc0SC16VfEOUps8yBahEHvNYAo/r5UG+wDCMhstHzEjiSV7TJ5ozjf+C2N+5A81TpJS+zfXhuiyupburyjYX8KQfXSvc28FG9CsgD9u9NcUuqC8L0K6MTB7k8RPSrG9xcBowqFDaH3/afLBsKWHEx87TiaZ7GbxKKmiINJk833pNZMYt36dr0fT0AH6WkvD4iSIWcFjvAHrW0CUBjOkhooAxjLDwNS4xBcgL0uGf61ygYBUH9zV+JqC3pullYzc7gL6Z1uKTdB9+Rzq/1NfZGUjVrsIepYO6k3Jf2j77qRNofSVtLr7VudUv297mIypV4jFNG/RoPFtQ2WSbHZIYIVepPCqWkQQ3VaaBZd8NToEYPjeSP7FQCrIjDtH5JVc649wgkEHdLS/q/lsToyCQh/47fiaEU/OJUX6UrzLG50J8+b+ijzIE3A3hZJf6nBnUbcUsEN1WzNHama57tMsWCUoxfcsZjEeSk8CzUjEFvxToKpESwRX7jDS7uWyRjuIHE56nuy7Rhzy7kP3hjE7eZQGMA7h3yxItDxa0hjvUO46IjZpmfyLIftSd323J9K7y9x3q0OGs6cNMNll+M8eSwHgooJbAGYjftIYVQ7t3l19LKEpnemXuObFFJQMvu6KQFRkHS3A2OROzC7hy3w5nSZP9Nqvygvc8Nj5x2IlHlK+pZeQi9E9WU6mGKIPzAOjSZg1FRLULUmahWgXGvJVIoVbHL1WX0/+g1BVsVcEZEAviRczTaFYVrH3zUIb0hql9p5EmHXwINnWMpbL1oh2LEsOUIpRCzjeBX1om6QCwyrXKzE5WkKcsQ7WbVvJf2q8Vdj3r3I8D9Kr+a7QqnAKm1GdwS+e5PcapxDzyhIAw0AsrOyWpIHFKvoJGl9/CWiD6Q+WxLDjG/KC3ms5P6hxY2Oxyakmmp0JGMtSIpOIV4cUyxfnFQ0LVX+vcrM9DpwZNHYLfyEVgg68xpLkUhUSHqYQhHgMe9oyFrzjmnU+EAzBY2vn7ZRrzxEowFipZpmlxFb81V9KRLT2l+3sUZ2yym7Y81HNdY4u1NKw2a3kwNryk0lID5FlbqvswxDJ60aWKFl2jrRW+EUoAX0mmGLk4lw1TYMKimngJap2ukwFky5/yn5KwCq4GjTkxzD35A52hFbDq5juINpyuFKb5X6sTkzxmIQ6d+1ePO6+kkN5RrZwjM2022BDoKJ95OyaR6kqUsIikDrgxHQUD6LR/2RMZapGa0B9klNlPm2phmQtAy3HLWfByXxRTHv7CP0keJl0f43LCHx/XPglb+QCs7mkgBIlp55xWugdKiBgMxzBkpjYWIXaaRkJcFrd8VmAwrXuRBvxVFzXh9/jHxuUMYv4WPaNX0SIhiNzaJsQCj5GRc4ftGD6Ot5rOaYjOxVM4yiFRzJMCgjCJPkL8EkU4l3M0GP3udgCfVqoHVFAAKmgdHB4o+hR4F8JA8U9+OCAMdZ+U0TL0oCcZPvQqVKi0b+5dePa8xTLYzOAuO7KF2TvKIujYqkumvg3zauUxxq7Ncklv+ddruQd3KAJ+H7rB9+g/6mTUpdyhNs91BD+QO0q3AYqmtTjSb6eJ2cmz7h6hA4xdg1Pel/sn+B3dePy7BVXLe/G2p5W34L0ZItuAJlIUo8JqE7IJ+BDJ2HPHMT4t/QIde6A76LDvKzalpZ5k5DXwnwGIj4DUdMXgYB8GdtTAhusOraNCNXTCyqU+EchYrO6o9UOURzd8wWj49jce/XROvWtKBuVbAXDNZzcIR8ALmpNTJKv0fz2Y/9/yxxvKN1dpBkLj+MpAw2++NEyylGhMC5C5f5m8pBApYziN84s4O3JQ3khW/1UttQl4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:53:11 PDT 2007',
+ updateDate: 'Tue Apr 17 19:17:52 PDT 2007',
+ accessDate: 'Mon Jan 19 16:09:25 PDT 2009',
+ currentVersion: '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854',
+ versions: {
+ '106a1116d22c2395906a346da4d830c7afbd2da9a46210d0b7a11de238016783': {
+ header: '####',
+ data: 'jgDUvByveAFnchBQKhiHGYDNDtj/7Aja2RePMer0FCOkkEu5GRAiLkxA3/DD3eiU+g+mCxnjnOaEIYL1O5o0+JP08XapsblZHTRKfveeFfs6sWwuqEHGYULBaXx4XSfK2B12HgpBwa5aD49489AkuyXi7t/aAXcKKJcLB1sC61DI3NsmajUaXHBi31Sp7nKAUpMuiWyguW0JVfH6KUPqyldVDBTBqHAis37c1qoR6aFHFfGgAfb35+syfmPRgemujMRkj2XO6dbt9zAYlHVSYFp9393rwPZoyBfXMMdDtSTmq7H9qbmx31GecHZlFN3NymtPPDYUbQ9mpPVRbxE9NjtiPrI5eGFvb++OdOx75PKjYjCAPWWFZ+4aryNn+h+yqab7pAuoG03ACVVrAFIOn09g1ssol/vqvalulEf3hAIviedyiNAC9D0UDHtzUwyIiELvR9qouXLZ',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:13:41 PDT 2007',
+ updateDate: 'Tue Apr 17 19:13:41 PDT 2007',
+ accessDate: 'Tue Apr 17 19:13:41 PDT 2007'
+ },
+ '111a8a4b6b912b808a93cf5e8785ca223112628d05f0bfc5dfe1eb40cb72ed8a': {
+ header: '####',
+ data: 't524etHmXljCnLC+IM+WPD8Q5VE7wDsSHVNZzFU4hQzk119t/N/vhtfHYz5HgNstU5T8c7h7RHKvFk5f+4ZwgNgDqSH7H2PrH+7/bV8+uuqbe+/3GYOvELjTF7v3xMyYs1B7ruHpT+291HVNZqxajqCl/+9nbG0e5feqNsTXWUTdLzF0szJuCTNr2I+fhxAO0LRVaf8h+MBPYyuBDnfFDuKm899IsgF9YoYRvjaYO69DkElvf4VP2jrXIJsRnGIUfUaIS/wQ54+X4JBZM/9M09MVOw1SVe+cwG+P3xyPUkqnSb77ECo86C0MktzeYFmPnPv2SM2KFA6slctXsyudoaNlReh1k+6no5J5BjaawTfqYjYrAtWSPsuhxYVsZym/X2CVbkz4rMSn+J5Uio9N5uZ6AqgCKdhAJlwzVb3fIIJwvFpVpy/0LMskb7aG2i4eAxwzx1H6rD3Y',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:53:11 PDT 2007',
+ updateDate: 'Wed Mar 14 14:53:11 PDT 2007',
+ accessDate: 'Wed Mar 14 15:24:35 PDT 2007'
+ },
+ '144d6eff3eb5f1cb70c8906741d88018cdeeae3a618ac4066598ad6b04242364': {
+ header: '####',
+ data: 'NPgSZF0eSOzy0/Ns+15Nz4bjSwh4o7fWYgKgwXLRFrF8y3EdbiOH7AiEmmPrCpT1raeYLWCcDIrRTz+/9uvIrz6kK6BjU2emr8YdyLai+PTCRY0SafWS3QiYixX6DJiKIt0SC2F6dfmSHwNsbfTHilFhVXn6wXTJpWvC+sRzw+h42cYpQp0BoLSuFV7vPz/+wtuQdl28BiBgLzGsrtPud0tPcfldGox6Ia/1SrOPcqUr0tnFlNQiUvPU7N0JZgRNyr1PfpAEhmYRI7aEJidsZ36vGQpE0ZQMmQE/9tLS/InALRZT1YXfMsytf0o3y4QlgJrvRgBL7fGiQOZJpU7igLk15xAwU+OLIaYIbr2xlKDJvndHOcrFoYKry9/A/aZSnEYv79wsaf64bBgIVD2WJGLuSFFmzlFnbg/O4kGTin3A8XBpvFA9V6iCMvnEMkrqxD3Qgf7WhxFE1A==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:33:00 PDT 2007',
+ updateDate: 'Wed Mar 14 15:33:00 PDT 2007',
+ accessDate: 'Tue Apr 17 19:12:56 PDT 2007'
+ },
+ '1f1bdb7a21440ac20c6d913d676aa30dc360252d27059e77df51a1be36b2e263': {
+ header: '####',
+ data: 'TaOHH6IoHPKLLoyLyvsBszgsPPcDs6CiLVXzXuXjFSTrhPxzUw9suSsisgDRRs0ncjZ6BCyqoCxMnw6QVvGN4viUwYVR8AWdCg0NMQZ+LkNfq/2WN0M3KyASI8sIdMCwTb57NzOn9soB1HmmmETZfjr7HpY2cc+lS5/4f5rxI8XTEK60lLed+aEuJamAjeZUdgIyu30mMKKjxPfY3Y9iWMwn1OD0zF0mAW+hyEoMhhK7EYlWKCy+4qN0QM+yNFXQyERb04o2n4XrM+qr9df1GtbQMH8igK5VzXIrKjdHjKoLo9G7D7mfx6mRLsmoAJuE0R8gyzotgdBpOgWasHJ82iWEa1dLRKBHJ1d0Lnumv22tvYfasx2DIR5Tmx3kIQ3hFieLSXq48cYMiaZH/IbLiapIOlMgtWDow8JuySBLei/8FAV8jCxSc1Ui/SjbuK/kCvywaSOhDVIxGw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:26:35 PDT 2007',
+ updateDate: 'Wed Mar 14 15:26:35 PDT 2007',
+ accessDate: 'Wed Mar 14 15:26:35 PDT 2007'
+ },
+ '70720f026f37b571e9765d27c51d3d60c7be0293c3266f1f987c8de9c6b5c416': {
+ header: '####',
+ data: 'NYaYljcgfzrlN1DVgrbyj4AeVhXGjXPho3IQwEKD3ZOx/yEZxldCNSyFsrk7PoRB8Q1T/6VV4CGa4HLRSB7QVCrtVqWyu4KbbmFoX8NIQ0H3xv+TSo3S/b3dldUeyW32ScaGbspaf8nFf0CffsgpGusd+kHdiE3gSLJvH9y5j47KgpyyX4TteVzqgez4dcXIs5tdzJq2eUlknwU4651QeKIuRSmRaDRhhOP4yRgUo/qXMlTJFmHviCh+IumvBdmDoPe3Vc1vZ1r8PxpDJLvDoB8GTDE42NhqHfVrew9ym1xlTD9wswwIEikfOyTq3JM857qPOHRqSqthEvr4WHbm1VW5PReIyse0lugGyOzqtCnADp9NvNI440VjaTd4NBQqF7XrRm56+1u1uTdfYGFV5BRiH1KmrM1sxXQ6PlOF9Lou45ALo20xxvJOLKG0RKLMr8gmVT2bNtOSJw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:30:09 PDT 2007',
+ updateDate: 'Wed Mar 14 15:30:09 PDT 2007',
+ accessDate: 'Wed Mar 14 15:30:09 PDT 2007'
+ },
+ '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854': {
+ header: '####',
+ data: 'xI3WXddQLFtLVzxJaZWQaw8wAgSuXLjLnyoNXnFuLecTH0BzU36PatglVh2HK3LM8aDLzzbHILdlLNnJ9CY+YnhmGh8hswF9oKTgq0Wsesgdc20QhSMNFFjmMljY1LSXmcAYK04Q5mIzi6Pe/04DRdj+e4zbe5QI4vEBhp/ohEpxZnNqc4BoX6J0eVf6LA1pwrKWvxzMxorWsJrrr+mn3svdlF437n+MMr89k5sQJogufes2GZ9tTvVZ4247ITxXqxgAhwXtbuIs/A5UqqnNdsxlHfpLKG5KjxB6F0h7TtFA3gkZCve5UmAibBnoBCFaIVWQyVq+VO9iqDm3DeXsK2pepvgIvpSID8Poy+uwN7T95mivAsHG5p7MtgN9KwQzNW3Iu+BfO9FlPBMngSk8L29So2CIXe6lEsXSGEi5Yrgyo6hZi6IkGCXwIQ7TCEMnlQEGyKnnAVik',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:17:52 PDT 2007',
+ updateDate: 'Tue Apr 17 19:17:52 PDT 2007',
+ accessDate: 'Mon Jan 19 16:09:25 PDT 2009'
+ },
+ '9588b523f39cdfc14efa1e15ea7716c2d8eac45d8efd7bfeb19d716f9df72d66': {
+ header: '####',
+ data: 'q6DKkxhgDFs1XkqOYf6dvojPF+yhJbniTLFpSOS+I1sum3EZIJfYxJXyi2Jx3KOVNBMILw1+vrSLe/fh5SSWj8ZBoeppkPPLjyRNdiUyd4IfcRM5OSv2YcTxCubKCH2kIMFAzY/29A6ZGPG+AN8/kxkEHc1fxKaNcj2Cs8qejNR8yK1iKT1Ut9VfEee+Eqy2Ohgdq8wL/xAD5mUzdqHeQl8BY16pXGIYncLxMzR+EJ8E5jJTuGv3O41UbO31lvBSfCt2pfz2MrtsuqNoI8LBHJkcR6t17Bj+rHZUniHlyxSW/1rQJ1NnwpPgUJ1fhfQJZM8Faoif+0bvWFY4xWs/tCCD7oEvf0xM0I3FfcJLbYX8M+wyO08t9BmGdEjnr3VUcuS9qKaJRpdpMP7aQf+vJvioeQDXdOJ6Ceo3BDFc6JdNta1Qc+agGzN2KPbIPrLDL+08hWl61yu3GQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:27:35 PDT 2007',
+ updateDate: 'Wed Mar 14 15:27:35 PDT 2007',
+ accessDate: 'Wed Mar 14 15:27:35 PDT 2007'
+ },
+ 'e5b71df0d4d79a195c7ec3288dd7738069837a7c4da3bccc1ebc05d8e4f19d79': {
+ header: '####',
+ data: '1NvK9Y5r0Q880BfB1W5IqdOR77mmqQU0d1GL1XUeQT75R2EgYE9rK1X1jLygCXboPhxzegEe7TDhUsn5XcHN0LkXcLYz8gD/7+He2HiTFxoHd2oQbI3ceBxDJ7+5kWA6Aiqy42QSCuA+TWIQcDVthSyFU7nNdqNxeBYeXiI4jgwcH3xvm0+pBf1OYLtywjUK1JwntP6o68b1LMQJFinDG+sqRcm25ggaZyxDtoLh1IBdSpmXk0papRnyyTGNgsws78dLxnH0Iqxb7FhqYfgLDIvN3i7+IALI0lF0EuTS0hSPlr/1fTz1/6bVt++wI9GpUsrdafUJJMPerXoCK+gAP8EMneLq4f5487HIkwWh1qON6Hvpg+tB95NOSJpqE72VpVxN4+wTQWyDMhfjqXBuQ1wKvTsD/mUsdinU0Wb/YT/zIWBNZPdqur0rjOC+mrOtSdlYSCH89Jj2',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:15:09 PDT 2007',
+ updateDate: 'Tue Apr 17 19:15:09 PDT 2007',
+ accessDate: 'Tue Apr 17 19:17:01 PDT 2007'
+ }
+ }
+ },
+ '36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113': {
+ data: '6fhueIibbxKRA7Mtb9TPcWiUKajnikM3D7PbOROBkE39Vw9E/nG8KrtJlwwPQeOGCFhssO/KX3ymYehCR8rfaEL1f9pfdh5x69mSxKRlOmtEknWqUgPzcb1yPenRbQagERadh0LF4zu91M4WjXK9qynEHoxI/pBhwQb1IsnhwtXl4ELtajudv+2Hv3p75v4XOXFsGQMsHPY+Zw7dkFFA8EXhvuxjiGvnxCUkFwNICFRdHTEovkW3VSerLdrYo5lDgjY6ebr/g7wDGuu4RLfUK4+HpzFwZ0+aOrjpFq2ePg2xObvkkMNNjZ2PcR6Cue0sf+aNqzIHIlFPpY2Hmrob8+bwxocKA6aagBu7z5GiUmZNXGE/Vtr/WWBV2+xIJyzXZPet0MLmSnGiALjPJveeKnnFdDtA929ydcAb8efc0/snfU/uDoXDiO5SWEQ8DDNjj1bSo7VPTtvZyFormE1KjqimqSwaUJzbIS4CxPnoDezaBtQmlG4z8mc8jXq1HfPu7s9PUzcbG30gbF0ch2pDj4h47AhE0ZoeiV+VYZTaYateSifQXKBQKjPcuh9PQyDI0HVua3itbbwxXpRubEM4fbvlcd+7gu+Zq03slYICD07fP0I6XGrRHVTfYpDbEb4GJBvRIeZLwRTQzOeFbPLpBU9Lv3zXxfHfcHy9oK+giIxefPdY1ZR2ZFPKOO0xYJsTr0vmTuXeXzy56bKl+yP2lFst5l9QG8j2JcQEotDV1KQS6mbcLjfIpEnltu5fc2t10Q25Noh+F3kF+LcMIYsDjwanojYlOC93mZl01hmSJdimRTk9otjlRTyC7NWwiyy7fe5IyVi7ACNPZyeUYJUPtKWcPbT73Vtf8W3/+HdhmyYNyMQ9PDCBb9WKMon+qW2+ZVH5yv/KqMHRY1fflAfxpHNhrCkwqcAAGw+G/cetbvQjpkfVT2/u/uLupMsITN2Tgvr/8D2IMm3cyDBUCshrp0AfzARRygHFK4x/0uLfCtQSNjw6zMK8mn80R5aS5bZi5gRS8JBMZ4Q0iG4kBlLpIYtsXSBwl8faljjdl/4XvNNWWrdGJn2k0eM4cESlOFFk4s3Yu0Zspo17nKAHINjHAiP3VlhuKSnk5C9hMU5i3vZO8anQmx9UEwUgQVm22azCjyNtUl6jVPYSNsal7A==',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 18:39:35 PDT 2007',
+ updateDate: 'Mon Oct 27 09:16:14 PDT 2008',
+ accessDate: 'Mon Jan 19 16:09:35 PDT 2009',
+ currentVersion: 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463',
+ versions: {
+ '381201fd3b67549bd6630841e8902be1499f3ff0c3514dd464ad9679f22f3561': {
+ header: '####',
+ data: 'DgjIW4YcJAYnckuEUzBFkfEC841LuanGopPgp+YkyMn3xuzdpGq/ObLFMVQaeAuyErh1B0REHPbq0E/SRUZbeXLXWN720GU4GXvY5bnen2h7pHvl/H4yz+kvyKh3EHJmmBjuz8s0kclFJQB48lter+G93TEmUaFke9c9m0IkKlgzwZ/PQKZyIyfZA09KFaozdSxdFRbswZj2Vq8Df2PQsKLapZWX1wYQ3lXOcyvNdTULy9MCXwPwX6te6hTLWxQOiSPsvB8LItlhQUsSbrJcJEvWPlBupPu5SeI25zDnqKDETPep63Ks2GWf45nXZzYYmQMzL0l2cenYFxlE18TcOd1Ms24TQ/iDKMhi60zZoo13qjVT5AKZ80KNu46t08qbACxjv/LeK2aM5TNycTFixGskPywpnb6MCo8ibRe5rs1WcTJRMD04sNoiuriivO2fiyo4rxjfdyfueMlOz+Zeztk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:39:55 PDT 2007',
+ updateDate: 'Wed Mar 14 18:39:55 PDT 2007',
+ accessDate: 'Mon Oct 27 09:07:56 PDT 2008'
+ },
+ '99dc86ebeb20a3db0c5393d6d94bc1150187b04316a876970dbbcf517b55d6f2': {
+ header: '####',
+ data: 'AJwqCWNKC9z8DC4TUI0hWnqHvQ40Y/x+jXylnVAkyO2QYQcqg51odLFSfgP0GiGEGPYwDc+kUxRrfO+ITgTNm+hHi2iIWkP/ljAC+AQ56MAEKsU/USTbvl6ShZ0XTAdRpwI/oqqOhYThVs6jTm/J8+lx4tWoMtNj835py88c/9eW26pLQubr7VysLSWuIMi+iDp7zXZZz/0gxGKDe5xNq4MGIYw8/OK1iJCOsjBdrRygLlS/Mz9sRlKkwdrDsohtRG0F/NdsIoaU4FttGs/rY91SCedvHy6ovh0zXhxOO44O6MiMbP085D1jCjWJn9S1RBxjxc368MGfMJeZja87nuvgSnLS2tGDL6zFtVJMNcH/7GqQPXZv/sNEykDNWpypchCnwYUJxvBVb45FcUzagPm+SSiekWK1hrEntZkZuEhQZp7Ud9RcENpa5h7wXUJSV1vPl8xBylx9HWmxez7D9OYRqbOlCRAEDqup4ahNhYB9',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 09:09:11 PDT 2008',
+ updateDate: 'Mon Oct 27 09:09:11 PDT 2008',
+ accessDate: 'Mon Oct 27 09:15:58 PDT 2008'
+ },
+ '9fbfcd3e7fe30d549a813f0e6c1be58ed45c3ae7305d7367bffefa097b424ee6': {
+ header: '####',
+ data: 'nZ+Lc5LWWLxnPvUrRrHhxG35PHq7GMbVENHfV1oS0Qw7/63NecssNoEbiOwFVMjAshvfUK7IjnzyvfQhNtFRbj2yzHOTWCd0eJ0O0MmvGzjpUntSDu9/G8RFeEu9jDKugwi/NhOa5legjT9pcsEAqR4s4NN/Ac6juQb6D/Z6Wd6wO0JQhT5/QPk1KllDpDeo2i/GPUKvEi/dXpik0KQcVLVylU82rf6hwEgvRQi+j0O5hnFW1E4ttxClrnPBEBv60jkNwcIpD0r+rvomDe8+398xUuB4DVDJoM+WUYfu6Sm3qI0yBfET+tJvjn8WsHhKTgZpOc2BXC7EdF99nNEg6kV5pSxV6AUA1XUz5kW+YfcSzAXzUH74OqroC0SucHe4+BtRKnbJy4h5vRfjTD+FJaj1Va02cxSR55tQhxm/k67z0QeyB98dnU1l/pPHwBlIWa1eR74gswNSeQ2jrzu5JeQ=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:39:35 PDT 2007',
+ updateDate: 'Wed Mar 14 18:39:35 PDT 2007',
+ accessDate: 'Wed Mar 14 18:39:35 PDT 2007'
+ },
+ 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463': {
+ header: '####',
+ data: 'm3yhZu81UAjCY6U2Knrgg8mK+LX35Y/iZgIEm8MuRDAlg6UUz9Z1Anu63COFV08YyYQRuBzTgR9YQ8wrUD1S9FG2ZmtCDemqvd+5OUMgdn4sK7G3CuzAc5osOa5neU2m4y19WuobkGnhO78ko7pVVjO42q0DeMT92uFL6KE/2UCkWlq5SdFyS5qXEJEWs2IO5C8nVpdlO/eZ36Pl2+v+afl3QQMTthCVIUR4/zVP2ajbO48yjDXhYxzskFjtXMYLApEn0wO0dcifcsYhPkozz6Locrt/R6IZXnfZfuW5XXHbqhutoJFPK6L6t0Ib3B2r1TNkPaMsVs2g5V1g3ENRd0IlbG/uBk2o5tgeu6gOYlA1scEiL+/ad9ZxiqYB2ENCGZ8DXA4VNMnzxVPbO96OIUCb9suV0fldGOg=',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 09:16:14 PDT 2008',
+ updateDate: 'Mon Oct 27 09:16:14 PDT 2008',
+ accessDate: 'Mon Jan 19 16:09:35 PDT 2009'
+ }
+ }
+ },
+ '507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a': {
+ data: 'ncSFmp/+n1pYUKi2fwhMCevSwFYO5irdcpOlSxC6YPOKYavK4iUbtBsilYWd0hpvUHW2ItaDwiyNFxs2Lwegex6dawKrpMYkPBcaZQDa746yACGgCkhz4MAGnUn5HCmz6xhpCVXMMKe3w2nEOjRB+pOMOeJt2n7aw0hCJ9tQ9JTFNrZOxeXrqoexrd210Rmr9FnKhLIvhNTN1/vXRqP0ys10omJ2mowzF4KoEVmz3ET6pS2d7tGjt9M/OYsH/ETWWc92doF5PO84g5/3HePaCo8NCqq4ul7AWJEbdnkxxmd7urJzIscPQPcoLxL7GfG5LhHTFyHlfFz9dNlccfA+OPftjyfjXTjLYZzbxxbi/nAB9Esqj5AoHfqaJM1ZOrZ+qAvm8Am3+HAXrqtiybDITrCLmGH9ukWDsx7R3lYTlvjArwORBUH+4w4/uYGscVm9kOYj/Rmz/ZMH9JibYFcPcOnr3rWXPFUL/XsXTrm9lzOvPyEYJmkENzd54AHC4Lr5vHpeuipWFLiJOrtn2WcgDG/DdLaYGKsmISXj74XDtP6Ee5lKOtbwwcmVNrl11UCQBEFHNybhXvpil5laKddOauLJDKtaDL/mKYPbr5YSk7HPCzRyE7HM2dC1MpBHuJ8g+hDkgU3wQcxYduKLRpuC0uOqrODigGWhVrdiKdZanlWUq9EkE3eH+E2A/CA8mHl7UNaH89XSvgV7uZyOmK7iZ+1kd9OzhBLQdJnK9qqP467Y14KsTt1E1+tqlqVAuK79QMnllaR0e3ztBRAQsyf5SD0KuSGXWz+z9/RjbhamW1s0UFRGh3voQMypU5RcYfYUA5KVg0BiVKFaiZBZKLo213hKbrgE2KoqVDEmIBFmwsu/S3EDzUY22tTB+o8ZKQiYesAUafGtnvsOLa+h6weF1ZvQVBerbD3fhb2o+d4ZyPkoRAsop+5it0QxsWuZL+J2oWybaikxIP/1ZM2ow4QZLaAVqihyHxqhF5UxZ9zrWxfp34BIPzzU9esSifrD0gXZ3mwutaCukZoijnGODJZtFOy9Rl1gyS1IbpyRbwz5O/YRl4BsD2aOk4InajT13Sa1BLPblQcrau13aeg/IzQhcUJ6n7enkrqiJFTP8N1aFAuYv8ilu0V2ymIuCLUtc4cbo7KyA+gnHhZA+DjjrhG/izOyWtQY/WtDsqvo/6ILwFk37JDjHfkchPEVcdl9qT7goG/4zTGX+lx8UTKKZJjJhLjA',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:01:24 PDT 2007',
+ updateDate: 'Wed Mar 14 16:01:24 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:11 PDT 2009',
+ currentVersion: '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b',
+ versions: {
+ '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b': {
+ header: '####',
+ data: 'sgq3FGcsnlbhTLetMa3TQQE6uFZv/JL6Awha1066IimKoAtQGbAr6E1+mxRmvJle91sL7oRfi6suvDanYHfAI+rrG6qCOtESn70ssS+aGFyO3XwFgypzG/Qa34bjxJ16Aqd93H8IdhzdtOxs2Qmou3CjyxbT7Cq+YW/fAo1WfctL4yE4GBNPWC5lfebxSmINlBY+zTjhv9Pf2aK6vL4p3obHl+zhz0YdKAMBwbDyCLa9tYvhGBnq/W6lFUsyZCPVJJP3bQCQww0TNCcLJLm+SYVSiC0NwCQJq+yNqDkWTvv41p5EDB06eOQ2VqC7l4i/JLE/ql9h9Z++gck74/Qs3ppdVdG7sTzWyPya4v3RW2OTc1awFRZipAX5Zd7I97dyw6Yym4y+/9UT8z8iMDYykQ4+QnOhksDIE9a8q6agDF/rbZ/BCRcMWbFylGTdudk26mu0GdPiuLDu',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:01:24 PDT 2007',
+ updateDate: 'Wed Mar 14 16:01:24 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:11 PDT 2009'
+ }
+ }
+ },
+ '5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4': {
+ data: 'Xs+z3VzIqsWa7dGBqepwq75lTsx3yemNhTdRYYDDc3Kzpycyp961SgnKXHjE51266mfmj85ASFi/FKCOwk17lbD5UT3iawtc3TdgrQ18vBhBsmOA2F4JAa4yC58bTaXbyld3c4izDp7i9+iyRaFN52NWJznN82SXuRtPdWRtAxXB1V5Tyg==',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:45:25 PDT 2009',
+ updateDate: 'Mon Jan 05 17:45:25 PDT 2009',
+ accessDate: 'Mon Jan 19 16:10:21 PDT 2009',
+ currentVersion: '00b3a4cd7400cfc1e7f7b369bdc3dcdaa50d6020233e131b30d755c89249ea9d',
+ versions: {
+ '00b3a4cd7400cfc1e7f7b369bdc3dcdaa50d6020233e131b30d755c89249ea9d': {
+ header: '####',
+ data: 'uGAV9pZTjrTwBy24TX/OUQwGmgzTnXv1JBIxdGkeoLCUhP9tAjbpUVylrUI5+VRrFYkXYyZ0o2HEgKrun2f3PODTxlmAbfkUldOV5tyV/EUxN0vYSBtgsMpqQm3bOKRIAo/uzrhSE3iwMjvKOTH2jUrkmX6hmqhXWZfa4X231GovrnOjek8c7t+LUBmmIjXEr2GSc/UbBoFnni+Q7ZArwtU68xoeCjLame1e8Y9wvCO8gIfAzXQAHsDgzn1MVeiWIqiCBTs8YKCO1yaxZpkzXV0yWzX+bHyXlKWwAk7Fu9w0CuaRULZmRCQhv+MMDw8DEXciTm0R5dRiVmSCFBy8cL9qlSeSX0GlnKl8E4/TSqvhMJblwJJsgmGSZ9cEt2u0E08tHxKuoeaaT1rpAOoiqx+z7BdhqjWOQZOGM4gR3EwqvOQoNYFUaXjAdmiUzW+e+TgE1IBQ8udRFl/D2zCcqFO90Hgc7hHsTDI3aGYvi6bHADu8hFpmZtJAjOMv1JgCX4Hm4n+SsbHd0DIfkEUMeGlVO47lcGWBZNRRm7xl8luZ4sZn',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:45:25 PDT 2009',
+ updateDate: 'Mon Jan 05 17:45:25 PDT 2009',
+ accessDate: 'Mon Jan 19 16:10:21 PDT 2009'
+ }
+ }
+ },
+ '6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728': {
+ data: '3oUg1TD+Lu4ou06j/MddOTXDqRM+qSKD+6Iuzia1Hop1w7v/BXidqeoKJZQI2VY9oO9B70Nr3B3wDROF+ycy6Rq+FM/xqUGHKXn1lAaSc6Wgj6TLQ6eRF6YZKSPqTj7TDWyw/2pEWk4HjcT8drTrCaC02tzAXMhYWlYPQPW4fUdq4hawoHIdopUN3vafQuFjY47OhqXKav3bNao=',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 16:36:08 PDT 2007',
+ updateDate: 'Tue Apr 17 16:36:08 PDT 2007',
+ accessDate: 'Mon Jan 19 16:09:33 PDT 2009',
+ currentVersion: 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc',
+ versions: {
+ 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc': {
+ header: '####',
+ data: 'fehYRMkg/wFj2t/aWu7szbXwrCyCDpjQN4UNck4/OiDlth70a2ve6ow5lAi2jgdlV9WiFrPejfa8dD0Z1g19jx+BBsuUYnBEKD0K+NapdJBBeI0We2nj9nYIij2dfZVx7cuvhy8sN6+DdylUQLsFHbga+Gi5hWcMuULT4GOAIy2WanSQL1RSR4ruA6zm/t+VVboEkkm7PPT+w3LuRl3wRaD4a8ZwYiSV/SzgWooFrh2S3YOUeshdaGCiYpTbXscsOxsCxc11i6wQGBqYSjksmtZDvEegdQdzCmxvq4jaVWJElYYS3av612nD5K/w7Zei6RccBiODBPATjrIczYg7HwmQxIM/6QI9/LQn0LP0yqRVUUtfzaODf0uWNpFzml9l/1lwXuBJyQFBp7H7Th46ekw9yEuPD00oZ+eXvKwbwfUU0JshT4hnEBtIjM8fH974PU0y95f0yLAJ1+M6DVXCxGsBix2aKJx9fuZP4KGpaXg6qCb/6327rph7MGomcrGPIiDjYwD/NTMdGluc55OZfGXtOZUaJCUM6nihqDwU7Ly1ZzYorgcvkX/t/0RNcOkFzGYNByp7mdcotyiHqCDKspqz9mEXAd7Noz3HO5GFpPqbRo7htDigGU1f7dvgbbfRoTz17Bt9Mw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 16:36:08 PDT 2007',
+ updateDate: 'Tue Apr 17 16:36:08 PDT 2007',
+ accessDate: 'Mon Jan 19 16:09:33 PDT 2009'
+ }
+ }
+ },
+ '6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a': {
+ data: 'b2mcYUi59l434kGl7ij6dBu3063UL1dToMIu3Zsa9RV9RzeLKnezJhLKunqoAm7KwiJeqDo/REexHI1cshGYtHasVXXuyJfMx1grH7yhoWnkSRF4Sax6w5E5wnGkEpGJHOxXJ9rOjWHZ7yqCUUCB/dqLw4FwPOtRb/ynkBEYztEJA6EKGJuz0vrrTOsT8HMXtj/w6MEZ7qI3fPs=',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 19:12:44 PDT 2007',
+ updateDate: 'Mon Apr 02 19:12:44 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:08 PDT 2009',
+ currentVersion: '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3',
+ versions: {
+ '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3': {
+ header: '####',
+ data: 'pZEWSdYIkrX8/r6OYmO0GEuKG9baUgn40Bmw7hXZBd/kfWuRjWsL4/pc5F5Ojrx+N0dxmQn5ZqKAzOOri29Rm4ruxnCbyK+oDsCDyMSnWy/VJcvystnDKzKmBRQVAOSEJtzEb3OtGzvqm0PQ1Dhx1YUAx7L6KlXysmG9h9+MjOcErRL9/1x1LZ33ytR+zK4LvTAb7gN5/9QgwysFyCkNP8bG4nyCzPMiUrBnP0odMTUvDkJDlY0Oia6VjGW6oNxnGIgA5fDraRrW4JH2oejQcrL7+X+jpCp05g==',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 19:12:44 PDT 2007',
+ updateDate: 'Mon Apr 02 19:12:44 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:08 PDT 2009'
+ }
+ }
+ },
+ '6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18': {
+ data: 'jzjPgxRHApIJA/6hiY4XCtb5+eKzHlOeoiGwfVDvip95zU7ThHbdmxOUomeyCOZ3S1SGPT4lHvqZgfVG5m5RvH3JaAIa8EY1ZElRohoX3rETVPJzI/Ov5Rp3lZjtWlu5meNrcJz811HBHrtBuJxAmSjYcY3CCal+oC2zcK2fLZR/iOQ+69ONVFhdV9KiOqzNf8IisIa1sIgFopqsdHXiZ9oLe0a7Y56q+OplyU3A+TmxKLI+Qq+WkjvdMzZDDqzYH47me5niugYPdkQwN6WQUE0sK9QPs0uU4TOwqCwN9nPH/DoQ6oXWAu2+R4iCyt6ZjLNkClbps4s8Cwz6wfFQ+4T8bcldjveJenmrYwiUzxSd/4xa34yFVXVw2OD0n8yZhtvNFvfoPy+X9z+Y4f5HlM0qzL9zYya4KwWjFQzhOxFjni9JyGM2PJ1BctB+q1J+CHuhlVjUF0Y5zIS3zFTET8jjDGBZDWB+Ao9E8fUD+0OJJUdKJ4kUfn4ZUZUG20eLBjmJqWBGYZX7UFaPv8ksahoK26Ol6FnBE4KpPStQeDgXZDzGsiLlEsxHJLUFkNtAUXozw38bWWQvi2VIFtkw/ZViPIenmSNT14kUVWdrlKQC8x0+wECeh5ffv0i8UUw3v8QC2ZE7GV0OMl4ySlRCuDCfZ53YFoB3HIR1hSZMhHlHJDPUz8JOuXdHcUQaJeNrfWoC2KkKb0ZecBj9iXooDh9yGi0g7TS7eyhlz1LHpzEWB0CPsZqhNGMxmfFWur7v2hrYzoHQOeB19ZSmWzfUwd4dRpqMp0x1lZaF97jr+yyYhnuQvuO6lru15Pg6FqjzhsNiLtaqtyoaMiHZ9veZs04qZZ9Fn3U7HeJzjZSAssdLnvopXi363cXm9JqoClyV2OemnVoRwOZN2gdSZxGeOefKR7U+lrBAbJwViMnmT0Nd7AC8C1k34iEt8HJmpztXeOgX5CQpwUPENMCUPsookFbIh7e4aByllEQy0gBbxUz8JMIWYyw98hdASnZ4s8bQfSmiMM8Iw3YxCexKB62LYYJn1UY51NSnwCtwRep+NhaKDk2d6SLh9owxnFbjhw22RriPd5f1InJycjtpvMzWLavl/hDsjjj1kWpnCUBTM46LbERmjz+s4x7fSf2FhhguBT36elz69ivXoiXI+7p0E8f8HsSwm8sgN/AA5m1svsXsdWeZFUiWtAwLg0tI8YNHlazbvFCXfIC6Uhq9eDv04iqdZ3rn2c1rwSx336A7ySTBFdxOCJ46F7ShIhNKm2N+5Qf0K5B2L882fbwqiLsa64+X9aKvufKTsd11vyf19Zivg/Ze0FWoGC8D63Nh91k6Hu32RT+uAtJIjQIZxu9yXJM9lMaRA8ieER+ghrLHaGQqF9J3WmueER3UzU1midvTynOV6g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:09:05 PDT 2007',
+ updateDate: 'Wed Mar 14 19:09:05 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:15 PDT 2009',
+ currentVersion: 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5',
+ versions: {
+ 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5': {
+ header: '####',
+ data: 'BbXNAy0GcKKyDPiwhP1Jk9mIi3uXMHQdhuxpDvoR2C3YITOUBpurxGhhvmCg+a9pS+fKJdZPxL2mPbJj6GfWTEsm7K/ECEjrVkSTHi6PTUUgYVbCumq9EHjUspos+7VrifZry3c73+qAvIKamvUlNB86TchMpOXVJIyx8UgRX+bdhrxk9ZCEVOiLCG1zGPX8IzmcxPmBRZFlHYqE4ibhl/CLEzWXZBYCofTusClhOh7YM/jBgvDt64W7aIN2y2KiKwmFySkFZdnOvbAb34tXVimwqjqWPvPwd6MujQeX1bmaDD7Y0kXac8CJxqasIezLo2WqzLUbEXdIHGilkaPT2ZKpKhKkpHJHFrV2lVuQJVqwPUr0Gf9qMKgVnsyU8kUfq9ox+fhH70+v7BQSjT7bxxDLs0UesQeL7G4SqvNet5hPI4GQEpOY8p5MUFReIBTRm72NQEU=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:09:05 PDT 2007',
+ updateDate: 'Wed Mar 14 19:09:05 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:15 PDT 2009'
+ }
+ }
+ },
+ '7bb69b6366a8012f181c01e368ba18d4f7a82bcabb4959189736ad124c4bbfbb': {
+ data: 'wYPZIt0UHiNVefNwtGc7z7Lu3YoQrXdfKmWqilZp8yeIrNfSLB9p60DLMrL3GDq/CsvDYkGAZgj1C/6NVnzVsXsJKq7NDZn1UPOGt+hCnw3lEVbD7zHkoMM4VgFDn1sZdjLe8wdpIFfdlQESTipT3GVXv3swG2qX2O2yuwtlopR8yZQTLg==',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:44:30 PDT 2009',
+ updateDate: 'Mon Jan 05 17:44:30 PDT 2009',
+ accessDate: 'Mon Jan 19 16:10:18 PDT 2009',
+ currentVersion: '23f5fb503e54c0cafe3d4944ddaf40bc74fab8b5d96e2bbddf693b1afb225e5b',
+ versions: {
+ '23f5fb503e54c0cafe3d4944ddaf40bc74fab8b5d96e2bbddf693b1afb225e5b': {
+ header: '####',
+ data: 'IpYj+7t3DhSVD8r9PkLbF5xpGrHhg8omY014P1vkT2KkGDEUj+ekQAbQ1g66Z7oNhRDpjS1/dcDjzH0IIQLjGuQ0oRfL0xZefVTx3N88ZLE39m3cJz10K2xyg3xp06jFBmdNJuCkgRhMzeUXeEJujw4lS2kv7cO04Uh2Maui6jDR7E498rgePY3L32vG1S66li/xU1vPjNn06aFTqSYxUL17/mlJNbgp3XWjGC+l0dXLLfXy1wOm+/I3zp2caTs+a2zDUZ15s+3XeaAWpBH7QCaQsvsQmoBqPbMvkjOQwW3taDvV7Hvkh+qTjCEcLjRFwhZkMNn3N2ewcLWQa2aVIjxt6Z0F4s/1URztWlKVzCfto8RmrLajYRn3ggG12kX2xDJFjNPNfs/7A3tMn+FqXQCCNG5GI06JZ32aQfpnjtmXScUuEs8UeFgsNeYclQhcm5R0sUwISK+D345B8859w+4+9OTY38NgYQQ9o/tmpCjWj1tLYLx/m/GcR2em7iyDpBdcnWUb+tK6Ah89qvXriHwPLSNzhOH2wxmi7nXTRQWMv7g2',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:44:30 PDT 2009',
+ updateDate: 'Mon Jan 05 17:44:30 PDT 2009',
+ accessDate: 'Mon Jan 19 16:10:18 PDT 2009'
+ }
+ }
+ },
+ '8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39': {
+ data: 'pOMTY3PnUAbwMLDEYNJCMzp4iIA42YWr6gqoomg+P40e7LFUtbt/RQRelQwNIztyUSVLl0rilkZZkBUVvxrtTqvibKITCjJQGQIzvcb+Yl4mNosl2Rpp0xxMU03f1+G7eGbuCc5hJXYVAglhEYplaAPzHbRWXMY8iZXZPBuLVf5PN+rdpgAfkGeZ7Uf9RsQ9p/EglrWXYnTwXi3saUfzIjfvSHm5C+dXTY3FHpIc1YkjFrdVgMkhYQGV60JtZcwFtCEL2NpVljAbRgHoIXTOkzUvep4vxrtfBBWWMuAWEI06432gtnH6IQbrR6jOpwuMt7k/09qy/fARPHs3r4qTJ9r2uqWHJ7tjJw+IChQPC+3l5HcPpFURiw8LGAN1NyY1hUrF6N84RSn7AKS0bLa5qN++5lcjjxn/k8+JqmeUqN1/SYIbGwNnJeZ0vA8yvOxnD20iVADX5kOVqJDwXRPLaF6Oz9KkbOrmANCh+PmGw1i6PduB+FgAU4HViYCw5IGOUZ30Pm1NJofqfbhXvgzn7ey2+kUIAwDyOUpJ9fW+9jW/JU4rcawmzwBYN2V8apOoyc3wQJICm2984wIfVBpygCOZM0QDyVgNo57qKtYH3yMDQSkKvpEUmuhklMYhcV+4X5ggdqx7lYXO9IMDnFf2ZDiZyieTlOlRv/nNVecUB177Xpnq2e+X/ik2rCQWVrIymiV6ltr1DEv0krXKfvXGG/FMZHUmo3m+B5bG4xVhmt0GnHseqvY2Vrl9NksLgq3hTDOGSGIy5Nv8kfrd8B4/6Tavh0SumiyXnrTXyYXzCK9E7IqO/0KAln63VkcHsbOtS8mj1drN0YQ2KKaeIW+Yr3Gm0pbcODsgA6aFfz1itZVeovBqUklhXS+/Es8J8xOSvvSyD/TmlFjuErHa+wwNQvftosfwk9ZTt0eIJS5aLHdU2QsCjdfSy0DEPkk2siGhBX5ZhRzqyIAyXApSmy+e7PIqn/dDR51+D1ZHwoTQyTrd+F08jBWZgU/OvS8MRxNZSxQwsi7bcWZG+w0utrIDB8eSOMVBXI5XBeJb4h5Bzut18C1shGHeGkSJp04=',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:10:17 PDT 2007',
+ updateDate: 'Tue May 01 01:13:27 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:02 PDT 2009',
+ currentVersion: 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8',
+ versions: {
+ '8a032b53f7356e2d8b28665211abbe2cf1c79fd8eee4752e83cebdced1c19911': {
+ header: '####',
+ data: 'OXpNHHSkdsaD91hw2LER+9XKpf8+bh/O+OcLSgG/gAx228UpifOCD4HTAOs0C7IJ5zhAq1L9NjCGb1QWWTFErYEtDEBRBV4kogscP9HWPxYyZHxjwPI0wE7Ri2eD4Rma76Utb+xVnXWuT+vNb8eRUCK8Ur1rlhYafS0uzAYvVqHDNfZaICksxeVQojil/kSPZDMu8ASz5pMNFNCF4SlwDKPRrJJDbNZ62A3px59YJtsla91DGVyOLhb7VNRxEwnXyxENfP78yA6OjvQDc2KhKFUpHbZws54IolLK1I1mY/Z8BiDXPSnOa694Q1eZxy1Kx/jLINZUIPgGg1++YWITx213awOISdf7Oy0/dUpu10Vr1hgAqCVlDp0IuGK01CswRzEdLVpUk1DaGHuin1rryZx9vThUkEJgQQc3ivr8',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:10:17 PDT 2007',
+ updateDate: 'Tue May 01 01:10:17 PDT 2007',
+ accessDate: 'Tue May 01 01:10:17 PDT 2007'
+ },
+ 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8': {
+ header: '####',
+ data: 'tvSUu+NPKHkwt/ZLXdLGdDm4jSxTEtJfsecdpjJ9UGN3Y2EBCmijU5i7q+hMfNDqBJ4/m5Ayju4zYDAKGp2pt8l1TFoDurITdFcV12jL8j3dc4TTD//uC6OtowRN+altgC1Xc0LsSvEPabjAlwfVC5xqirfm5t2mVmnFZ/GALkGLGxRJRduylT6goPwfunkVGwUdqMa3md+9mwYn2gm7CyC0lpcKX8AZ3B4Oa656yRa9m3Wjgb007TtorLIpZO2MzVwxcHBqqy7YpN+zpmZz6Md9VK3L4F724tuXXWnDeVzGxBO7aZVr62hwPMXM6ibCjUScsaS4f0chivA/tBJoyx7OqKhBxREGeGjpHTeLxyHcekbwXhXyeqxBuwG93yGKutUhGLVYcXwe8/+xSeaBGj/j2RWutKbNKG2yQyNPGj2cxJWsR4YfOQJTSOSWT3K6Mmf+r6hLhIo=',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:13:27 PDT 2007',
+ updateDate: 'Tue May 01 01:13:27 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:02 PDT 2009'
+ }
+ }
+ },
+ '9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291': {
+ data: 'xXZUJjgxn62OqnzAvScHJNo4WjYEFp1vQ4ueBe1sk8dH4pXZUKV6m9c1d2cLUgBj4rUNP5cC66GiFHV7G5BDZGLrfrxUlYU6BWvzAz4eG463pRDhHXQgPrhlIGDlK6ovaIsjwaifvHaEfLREoXvLFluqu406KG58guhtWdIFK0rLypyRo8uyltGbTz8wZdu8atY/JYQnb8NaAf4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 16:29:06 PDT 2007',
+ updateDate: 'Wed Mar 21 16:29:06 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:01 PDT 2009',
+ currentVersion: '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7',
+ versions: {
+ '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7': {
+ header: '####',
+ data: '7wg/yWfSasUjJKV/5ygFfteazVSdqEJ8xGAqtS7m/W2q3rOR+2fr99Il2TzxXCnOe5zV+iir2tOqPQt6BCGbVf0NVwZtvfO/lvfMc7DIwyWuhZ0sS44LBTD9VY9fruuIegktVHSNBoJTCIfAHN/ut1iB80+51An+TdpYT3SGAVM4RdenQ9IdvDOnQo2KE0E7BzHekga800VJrbqI8aJEtmm5mOjte2xHYSPFDCtwURQclwxbNv32hAY/IUkaejqg93WGIzHIIK0+SSDzQwHYQo4yzVGCKKy75eghpvGyg1zbzlv372bND+OuA3laocARFfe4rRd5I5nh8vmSJ+vybh3EIJJzloD+qWk6hsEagkYI0RYu9I2uOfA8drmZ02GV5/ySDsBHX7uhaTPGx4J22rNJoj8s1L7UoaohUHFvUerBvQTir2LPbzqT+B07wZOU0ibtHlaN5C2XMKRxfvGATeR+2J3l7WisCIoRdpQcPFHA7nlTTShBiCVstLxolvd7MMzPOilsi3ecxXLQSeWara4JILqXQCJ4yLbQCMnSpIrZ3TXbwbPZ8fjKjogHNUaBPnmd1hWoc7IVvK9RSFBEdCh9U/hbyPMCiSjdsUCTclmhFmhiVIlB73IyWixmLwHSWSl/ckMxcUK6rB0IPuWcT8iJkxfqOziFhMvC/cNydpN5Nj4WX21c/1M7lVlX10FRx6NIYH5szEXULmLnkfEwr35G9mKJwR2pgZ272UiW2cH64/+M+Kh7XnPbQKxTwVR3FOhR/qdSHeA8MTc9FDslFaTT6YSeJEPoQiLg4c4UdbB7w5nA0o4qg82hiiJbTfT2zFHZeeWOpVO1z4V8SidJrQkh8aL1/Is7KaDVNfL+Lx73gfO6tdSviCJJhD29iTgn+MW4MlGwpeLKpvq+LkXNXi/CVjIa1VqtR/Flk2BqwT2hccgw6E1ML+QdW1n3TvTtdLIvSGheOM5kLdnF76e8Nj0kHDFbnxQMlO7lutngaNBRAvhvSLccT76TMG4OTxNZk5aOre6AIOuUfrFD3KDeOqWie5zpkvTOd/JK/JDFYgbYQh8AqhwJ7VWUH49vfd6AqfwHwdNWymI05F6/0Co4xoQ6qN+iYNConUXz78Uo7AraJuBDQ3a24+wL2mLjnc8jUDFUaAKM6gZUv9+bx1vk6zVdaZcuqgZc6dcyo5Oy8lmbJ/SmRb8BF/Q2nW3SDv77R+p0bKPLmjcytczlMNct58Q1LoiLnGck5v0wByQ0XIMd',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 16:29:06 PDT 2007',
+ updateDate: 'Wed Mar 21 16:29:06 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:01 PDT 2009'
+ }
+ }
+ },
+ 'c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065': {
+ data: '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',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:45:43 PDT 2009',
+ updateDate: 'Thu Feb 12 12:54:37 PDT 2009',
+ accessDate: 'Thu Feb 12 12:54:37 PDT 2009',
+ currentVersion: '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a',
+ versions: {
+ '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a': {
+ header: '####',
+ data: '/mnLRePyLGwPaZ+EkbTRHdE4jz4gY99jnHcIp7AeMfcktEpPmUVNWLwGSJUH3ANP/cO1znxACVQPzC+g8IVIK0muJ/lZ4Iw+HkpsfPtBjPZc+bfhsY5Mud00YBsImleIMlbbJGv3l79eSPcea49OwG30xro6b6I0KK3BmSgr+BG2AmBrKVlFRTPFCHRbO+hG/LgW/xqYgwd9f1dnbeVYCm5lA2zdAnwmMwlUIi/J73MbnsSO0Qg858iF1SPQ2Ne9Q8SCyKKEZwBY/YeSgDzoO76Wvqbzk8uPdmZldaF4zql3ffBeb9ZS9KIyyk2vJcLk7c3DUc65vaT+w25+2GSpEXD4YIV6VSr6Brz4w4gzcDMeLve0U6oruqWijz3CDe40yhd4mMt6wTVs4xo0KHc6yKjTuC1ZUQwZvuCiS8T5czaGpc0+fLyfuE+pVBxTlpOjkoZqzk6NsH5lcKMzB1TCscJ8fbOdtJso7DRUvijIE5+ayY9IktZhMeHsk2zurKV95A==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:54:37 PDT 2009',
+ updateDate: 'Thu Feb 12 12:54:37 PDT 2009',
+ accessDate: 'Thu Feb 12 12:54:37 PDT 2009'
+ },
+ '4ebfe3bec6d419d61eb68a1f25407824e404e3439c23fccde1ac19225b40cb06': {
+ header: '####',
+ data: '6VvjRN9LKi7tt/HsgqmU0bUdZQNVjVAYNLdCrfKdRJCx3W/GZHHR/AQF0FcvuXIn0MWMUypHpTZW86V459OEoV4W18HXEisQKEiqBnUCBaxBd1NKZDpYsThISXXOhZSbXylbLoB+kBaYzT+Fc7utDheVvVPeMo+iEb3ih42B3En3ZXcgUAdEjfbRUm6st9Jiaz4onwXWknVhkF5QewA0GXDhT2JdakFxfUDay75wKvspq5IszbEYwsu+TEgsbuO4/R/bktgsQUrbhtKIEIiNSccDNx1JkUKvIxrRfp1m0Ar3XJsDfv7YSJSLdyVheOEdIpBkeZ40LN83uzGRMZw1bQsKf+XOFTfacYZBBzwVj8e1rJC6AWlH6Fbn0jXw3JcEljA4zUh5IrYhWtyIZW338UVsMSIp91USeM4uCvPsOLAdyCXiWu5H8MMYGz1rJxVlTbMiq0tn1w1f+CL14v8EiUft7l8kfZzBZzdLvzdedD/wHQ==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:45:43 PDT 2009',
+ updateDate: 'Thu Feb 12 12:45:43 PDT 2009',
+ accessDate: 'Thu Feb 12 12:45:43 PDT 2009'
+ },
+ '7ef137cf242e00136e57ddd262edfe6b418b6f57f3b5e5e15f3ec1232867f6c8': {
+ header: '####',
+ data: 'N5eWFfsQGHR1WytyXuVySzJ3zenJEB6IaKr2vgWRHTlJFzexXzJmSLoozTP9Z4TumDOLsNrp+EUeIa3Yo+RqSyQKQRFDHXlUYa6c9PPLPXdexSA9JO3AHzMSpL6K0E4gN3BybjL2rbcQwUqJLvCKy44OdiJvORGfIIpTPx2LQ1o4P+chcpOwwe/ZhgLWmNC6FmkTvsU/xJlNuApyD7tPX7Cj3lP8WBfYEPr68BqTKAa9cxai6ZF4BRC//rFob/4pQNHE+7qjOSY9HOnV5uCtZehPYBwfpBiDYhaxWJxXN6sxtpe7GC5CM7gAAHs5lgVaFSWffOAL3zeX7I4vh3j1nYdXoh5KowZJVVUUfhwqJo2T3YDVsaXNibZIaPd9GlbeBBk2HL6c/ao6B8QNwRU7GvMHAdJKta2I9mtU2NCnr0Uwi4rZRR05V4k0HIMLEJxRo/IYAysAYETNIAXzk0twIokOF5JPjP4uTXRZ8LdiS6JqfoUu3Jv/7yq8wrKZM7DaQA==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:47:39 PDT 2009',
+ updateDate: 'Thu Feb 12 12:47:39 PDT 2009',
+ accessDate: 'Thu Feb 12 12:47:39 PDT 2009'
+ }
+ }
+ },
+ 'ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c': {
+ data: 'zbQlGR1fT8HoH6KvOPBoaIjMUsVMh8MSNIzPO2muIMJDVfXB2rEcPnIFl8fNv9BtE9OLecuex3BQVJKGXdVGFYVNiSS0SgPoEpyD6GJntEIOaB7GnhVflTm8fT7Ba8ArS4r+fIL32Jx9F8sYrL6jKPWeuImGHK+x3X32uORI6znkRac7J727TiTPlbj03X/Fj3Of6Bp9Wa4xbVMwzi+R6NRKD4A6Za3mqhoSpYFeHWld8+ChJU/w2wFkj292OjPBzvvz/SR2Zth+AXTChreQ3Zl1hWNGmU2Ep8ijFCYwcamgPkQwh4vBk9NJlzIgadORcb/0EPDxn638VNA0dbpW8MZUCIMWVe3A8VgdllWxei7dDy1ri6xsKlFovLYjRRPXgAqRSqVATqwyXqhBWhoV6VZ5NaSUGvM8okC2GQSweLuz29py0F987MISmLjav4gdvcMA1wn7FOIaFTNg7oy2CxZefGhHT3sHfX/PIvs/ovfj+7TewI0k+HR414az2D5reo7S5I4+roCm1QLVpPNcXUxbAmEbjF8JCsTtECZ4kdpG39dN6BaMlHoHSN3wu05uTSn+sL7g3Cg0pVLlnHo9baw3fUnVJp3MCEgZJELaiI/WF1Om2y2S9UeLur18z5T7hHFv3Px28D7c22HEDdF2CObeh2uOlZGAa06lp7YlYeoNtb4CqLlZAMK0xIHfNUceC4OMNvqyGswd5WJsYQEnMry20OkxY6YinnQfjAml54B6WlvNVlg/YaKjw5AVinUHjzEFfQbcBFnFGpqg5qJk9hZmb1VI6Ujhq73fPydSfkvfScTImqxCNPD/BR8ovoaJtNpE2gmcoX9A5zhZgu5xUnUnXoaQu0l7K9kWof/UmCCl0O1A6j41aebWr+aoFMalaOPzNJ02vfLuW155IwjFQvRuAp6EuktZ2dFKyFl3QnLbwsMnitReXMoW30cqTYg7ODQnopE73RIb41Nj07qdx6FQMzw4gAIEFBe1iRvlMHQazZCb2ndVvgtK3ZcPNtDoahuPRxMLaKZlRnpa8E5F4o8NHYNivshawZi36Hk6w0dOimCiuk/zvJ1mtx8hhX7B5dsXlNcKxLSvI1onEm2x9HL318xJeT0y29alzPYVFuQs5kq1+UV3h2hL4E/H8h+5mWtTLf/MjaTZ09okW/etuHFFjCmLoKwugk70z2yLWEJGmbjw',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:51:17 PDT 2007',
+ updateDate: 'Wed Apr 25 11:14:05 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:12 PDT 2009',
+ currentVersion: '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926',
+ versions: {
+ '3895963f82854530ff754c8e2d1eaef8d884a8cba7cd058b8b7adcdc12be3da8': {
+ header: '####',
+ data: 'rXmjQYZgxv9jpFus3T/qa9Qc1lxt+mDF+dmZeDmDG3IiE/LnonGt2MqL+YlbFzisF99Uv0IQGOZCPigtBwOXB9m6R6R3lEy/YhD/C6b10s80OBj3yr3PoTsoTmbnmZMYd4r+qx8SaoLLkR0aK6NADYZXebR5QgVtwF/a01EifI6YxH1wm1RX3kyRhIrMzOtL8zHbstPvW4sRtv2YpZqlZqBTdoiqztDUZTKEcCcU5QLnHYMNAVpDHE7D9WvQy8Il1taAbxg97Ir+2ktZLjqfJdKhU7ZLv8fcJiRgnQKPqDWcqpjA+CXM6Ak1HCf9SRJh6Hl64+fk3jEVAPmHvry/xq2RPCG2YnVNWZ+uL3QNuH4zt+IbP4FnrxkCAprmEiNwvuEefMgliGRd+FowIaiFWXcEtYxxQvRDujZN6eoTUU0KVnuy85PKi3ih0ZECoDM88MFhztwCG9/nJQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:51:17 PDT 2007',
+ updateDate: 'Wed Mar 14 15:51:17 PDT 2007',
+ accessDate: 'Wed Apr 25 10:37:27 PDT 2007'
+ },
+ '5311936f6a95cf123007ef867388adb5c1ec5b2cf1173d66e501daa16488e42e': {
+ header: '####',
+ data: '+VirbcZ59SiN9UJKrQkjQx0Z4avHIhvw12Hq7fs+Qnoz4RgCS17fqzYyJe+jYorjlMPjzUcALYOTobqJJp4Sp8v5nOilHW64Gny2XRp59PQPg0zE4TP22l1PzK04+qJusR5NLPU39hYbW+InkDapdIhdf+nIruqeA311bRLg90A8xmpzio6PkZxXmhZMabbEVfXsYFBQKVBFloTMusBG2eaxTjeK0hOAk0uEc9RGOEwCOvZvjRFCP8DyZ5T6QV1pYYgBFBwSFrB/koXmBmObj8zscJXQ4H4UWC0yw1B3ABbhNX7vC9q+vgZTxnGqI6GvzLcrzaXKTEyfa9twq+vKFX1hqDmM0UVLw0dPOy0/3tabJjFrYbz5EEKVin9UqWhuy5YIvHEJlMkH190Zo+lPMuHvD8TiAU1M/n1bTQSBQb/8STD6uqefbKS/s/bXcS+bdVKBmSgCuutBznYO',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:39:26 PDT 2007',
+ updateDate: 'Wed Apr 25 10:39:26 PDT 2007',
+ accessDate: 'Wed Apr 25 10:39:26 PDT 2007'
+ },
+ '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926': {
+ header: '####',
+ data: 'P1LfM+8PA/kyelFsojabLfBW9D0Aey5qDClz0OTdSamMT2Mv1U35eKcr6ilUrbtW+dKJotAzs3B1dYGzaEQ1j9HnhiL2pk4wgT1JWGe5c9frmFX/3YGO63c2ngnaC/Rrv3LC251cLVS1aoWNPskWkjZLzF7EiWbAeNYTplSa6MWm2LdHAm6xq2dcgYx53RJVvjnsCzpghQdzL96G8ScJjnUx8FC8mHW4Ds0rkHTeoM344Ao8J3o1XwoFqFFJ2X8+lSkj8LVVdjff1EHIicjrMM0oJG8VyxK2TxMvg4mnLWP4ALfh24Wrb9XmrM0NjhQXBo07tL9dwa7sHHKiBrM74644vBR7NB0+Laedg8D+6FmgNoR6icB+qvxCIIvAhOpJ0er9f0CGDDS06knx/lDtVVNewzxx4ATuG0HQn8M61eU83EfbKWG4Mg+9jtRcW0/bdFW/FQr/OeKg',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 11:14:05 PDT 2007',
+ updateDate: 'Wed Apr 25 11:14:05 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:12 PDT 2009'
+ },
+ '5c622bec0fb939da012beb98a858a4e16bd670b3e6fe1f7c92a247f88a65c747': {
+ header: '####',
+ data: 'XGlplDTD1xamZO04H6RiqcLd7XaPwxI3MqpKTCVHPBoMEkwE4A1izGjFKdPqHbQIuYYcT9xDgPOknlkP89jDTfcR4UfENtKHFgFaMee4orSER+MhldJRxMwPLorZmMNNZzVmTmwJS7FI9jYiXEvDbcyw41kN+SA0mxzWpc9emaX4TmZHzlBpY2zXKJLyN3otYYzcTWzuu7DJejWrB+CnNp925X9vVomBPfp/Gt4tiOFsE2ZyEf1B/7cDmMszlQgEgGJONS+C8Qyr+X3GEh5iPoYsGpMNmF7aYnZNciE/B5lP/ABVbZIi2KfmRlSf7Cc+kMkUXyHxOeZHuVv1ZlzfIe3gXlD0/yUJFHNju8ai+F3hpSkhMatf71mLQzD5oFrTmKatH+zQZhGPP9dQxG1cgZRcjbyUQJMazo+0TJuNXNndi/oiRzRJjYRUbZKsfRzIAEU=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:51:49 PDT 2007',
+ updateDate: 'Wed Apr 25 10:51:49 PDT 2007',
+ accessDate: 'Wed Apr 25 10:51:49 PDT 2007'
+ },
+ 'bad48f8ab053804a02bec678db01baf24de35ef04a17b90e1362e67fa352e4a4': {
+ header: '####',
+ data: 'SXl3D4C5Yt81L/117xsHYjZxT/fANq09VZsMNAz3Gcn2+2gopG+1K0JFg/1Mbjt4EMbe5Or42zBlJPo5EAldAfWu4MoTkQzo/wKPzgOWlIi3A9QwZegw3yCuHvJv8iNcpjGfpY0OCzTZKNomTtwc75l+8FqgwPDW4wDkPG98275ERDR8mFSZfUAiQxlTnCbskFneUQ6hdN2gywkyJKuTEcrMkIpzwe9uqPaQg8GjUvvy162/LVaSQAVRIiTbW5URCD+hT5cKOkmFeBejHar8zR3SQQ+tIJlKERBwfE0sNR+RebSboYxWPECYPp0DMj30FnHbfYIVTgRCIlepy2hfis0+9C7dop0jK2nFREjcxSIqonF+juCrfJDt4cTlpn2SmcoMJQsUOedSh6ZoWweXm7lu8buCbA2Q6SY1L6jz7okwIikIinxGDq3qT1pWSgpntI8wvYZ8RD0umJsoAzPYH9zlfQ==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 11:01:21 PDT 2007',
+ updateDate: 'Wed Apr 25 11:01:21 PDT 2007',
+ accessDate: 'Wed Apr 25 11:01:21 PDT 2007'
+ },
+ 'c03d1fcf5b6981741f5d4787315534641c61daee9aa3c063540fbb704989ded6': {
+ header: '####',
+ data: 'sbn5IDJM7VtYov3sqW9+/0USxZEw2xq8di1XVPMMZ6kN6oZZrAY7ukxXHYh+mfuIa1/uV4i4v1YCaKZQShLgUS4cchlK4nnNVL8zejGwB+PaY0E8Um/Jg6E4UAFAZ+haZwzWLQS8lJ1r4hNMTeFqsDRUhC30awJRz8e0rBejLZiS2Hk/jgpH3i8Za1GwDzogw11iHXejYI7MaQGB0E9eQsYYTxGjmzcLfVYkd4AKj5pSEHvsKZklSuWIyDzwaFiIO7xqcJmS/8Wkm63JGNOW3nLR5Ao9V/2vthFHBqS2lQNRnkPWXbmNK3v7vi57zu461w1Nn1U/70EvhHRMk8BdML3XI/U6WgDARjQuVsB8FnTkzapaORG5vUd7nTtWjPdyQzOqacm2YKWpAiG6fUQTZiBusEd8jdnv8BioGUTbXgNVG23zcRbbbEdjKc1aizXHQE1LnROvoHZHkwg=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:59:57 PDT 2007',
+ updateDate: 'Wed Apr 25 10:59:57 PDT 2007',
+ accessDate: 'Wed Apr 25 10:59:57 PDT 2007'
+ },
+ 'dbc283f49de6e303c06a52725b8187f344ba7b433b0158d704f094edba782710': {
+ header: '####',
+ data: 'fbNrpIoYF+gpMUjSxoOc9Y68qRlE2yk7FPPkrHTu07HHWkAWy7H7nFw4BwGiFViMkyEC2orUrMeDYhKmMYFj8DEcALk6452BtNutGZSoqDhD8xnSEPF6fP2Xyy+vZHp4JWDXZt/xHk4vPbxcwTTlmRz5aO8ChXIH5iqfRL9+Dx+gJDKgKmCRMZYMT1pyOUewmsT6QDYdGFJTRRiDmoLfCVAXhJRtqQSBcx3kN3kuf8gyOMAeJnFGISTAj7THzo7eGuQol1omTMgGbDZoL7WJNfZIDamiT9TWwzp3UmQcKIsRvA2ZKtePWRmpWyq6WydJgFXHUuUDVpwT+kc1Rn9Wq2zwm1VBw6gqKCp6W9bZO86rRMs2CtuLT+agSpqb4kz4SEYDCW0+aUsJDCYBXx5yWRM26r0XAbU6X0D+xopGuaVzsV5G7chkCO8mUsjHzZCK7hOAz6OgjR2+',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:38:17 PDT 2007',
+ updateDate: 'Wed Apr 25 10:38:17 PDT 2007',
+ accessDate: 'Wed Apr 25 10:38:17 PDT 2007'
+ },
+ 'ec525dd942f72b71b5fa1aca0a36a9960b71608bb27f32bc7923713bde021b12': {
+ header: '####',
+ data: 'AHP4MFiGukFCCnjLDGoqJUDEr6QNL+KoZlcwOqJIYusRtl5qmhZSsODHbAEpmadxLGogDPrWoH5/XLZ85ASGRF5ALzDgrFKP47/bSEzKVTDABY5BJSqvKgS/lCf2LdR7+0HWUVJ6Z3GOb9GqsXC70pMxDo/RfclOQPa+k/sXCW5u0TmLb/0i/dZEM8N++4umXsyy2WPLtUVzQZ/VdTMDwl50FeQxu3aNGy4qYd4XFk/7gxBH9skBD6/GqpNajHJrcbi/WZt7PZiN9skoVZHhm3YLmteP5hJnrcCGBFJHWuQpXfB7NR8rNmd2c6maemKYmUlX25wQF7JPcROOcyT8iYpF4Hk/eSPs0CSkaDdqSD0Nj9E4kqZrHfVGMwBbDFyAzdHTN3EyGuC4cBXdfNZbdBqwghuB1x7RLXs/pbXg1xqukjRdPLTxUogPdaQBHGo=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:56:58 PDT 2007',
+ updateDate: 'Wed Apr 25 10:56:58 PDT 2007',
+ accessDate: 'Wed Apr 25 10:56:58 PDT 2007'
+ },
+ 'fda6581f0137dd641387a7be193b06edea4451835817bcda38d22ee24ebeb77c': {
+ header: '####',
+ data: 'QwDMobl0Kds+J8mknphumnONOIF9gH+pC/AJpxGmuy/rvKfHSeEuuWAZ/yWj8J/I4V7OjpyTs9/uCWeKs9khpdkcxtObB36IfcbWBHGOgFjvqKgwMa7eZSIUPZz9k1NsqJC9nU9U7w5EBzQKVIjJaey1EdhsggdtNOpQTzt7iu2mWKo33dJKQCQ5VEwhpGh6SH1TgKFbdMkOJJY8d5xPYUxR66LVFpFzgHP0ML5M5U53PK+apT95UIAlqf7N32BjPK63Nsj1WPsnuuL0vWA3KmefHzwKGeatTdsgck+1mwnCDJncPWv7hTwMLGPUaY+Yww3K3YPihuyCUtUdV3fer2VHVAn++JdzerHiLI/86T8gHiLAi/anFFh6i2kMMVxqzREh+62n34MrgdMqbSFQb0V4Dhm45FVJH43uuEaoe3OJPtyvj1HbcSR4VEVgGkDeced8aAK+Dg==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:58:33 PDT 2007',
+ updateDate: 'Wed Apr 25 10:58:33 PDT 2007',
+ accessDate: 'Wed Apr 25 10:58:33 PDT 2007'
+ }
+ }
+ },
+ 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:06:54 PDT 2007',
+ updateDate: 'Tue Apr 17 19:23:41 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:23 PDT 2009',
+ currentVersion: 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf',
+ versions: {
+ '12bd9887eb84b99ad40c1e413cccaa9ffd4deed340c71fe53610088faff349bd': {
+ header: '####',
+ data: 'MiAIw+S6GDmLLMcGtkl+wveV7dZAFrL1zGZh/FPvG4kpOBbnyaolRynNrL1yeUbEp4gLL2cK2BGYiVc9196PMOvKPHR5Rqp6GlT6h4RUJ+nFFF5/3LNGzQtJbiY0rrYKptqyPBC8mhlqtdK7sQkQonj5LPhKeCX6AyE3juBPEuFYhvTv9a/iRPub7BdlAocz+bb8ObpbVHnNvbGhiRpx9MpUg44JRxLQYhtDUMi2UFtURidKaK0k2lP81ckPDCgVgxy65FjCq05vSaCW0hanNrIwl+zAgi+3ChriqmflvsZYC7TQzUBPXrAQ8bKmzppZWlArIOppRF7+paWrHA3Qcz4uO5Sw3DvMwbgl+XINnmkE/EbA6VJOjrWYJjsibvbCw6vNr4q1A4Yxwy0a7EXbjFiwpEr+jMUhsq8+d0DxP3tQTusV0l9wcT2OWrDRKdjDUXLQOV9BVw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:27:40 PDT 2007',
+ updateDate: 'Wed Mar 14 17:27:40 PDT 2007',
+ accessDate: 'Wed Mar 14 19:00:21 PDT 2007'
+ },
+ '35af99615d1be9d9841b4a37488fde9aac291c73c8c3aaa570cd05b3fd0baf5d': {
+ header: '####',
+ data: 'lv0pIfnhZZ6ktahFGl3AgAfdcveIcUyAh9x0iVOCzmQ9VjelBztlvxZEo+uByaFh1ptM+eqOFT/Vk9IKhNjRWTXrDXioP7oZ8IZ1kLfk/XuMFH9AgYzm3H1T/yLq5lg1WqqZ+OfO9m37Z4kbTjK9+adIAJ3TwsMxIDpIHYz+qbznjJocubYCbi+DC+4wo6qu5C44gf8n5QF8DOCGaBCyamxFvkqrSMo/Y+3SG3yt98MSgeMScGESuwKKGDHZX0v3ZXvl4UFbxywUtdbipDv4PAlzh0aadMsGqYwO8bPKEUElCWBXd6kASugaqiJaZFtb02EnC+nncv33ZSx+WyJqwKIBk/Kpd3/YDJnX9t3QU60j0YKf0my9oX1746F5u0XGX1DNRaw/1g95zRHoMu6j2cSTTX7CJglzIlTU8kglSO1LOasxm3Gt8iT+8+Lhh4Dw86ugqHXl',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:09:07 PDT 2007',
+ updateDate: 'Wed Mar 14 16:09:07 PDT 2007',
+ accessDate: 'Wed Mar 14 16:39:40 PDT 2007'
+ },
+ '7cc6c6f2eccd8bdefddca21a59669655d7515f440b025144b9ba6b18472cf189': {
+ header: '####',
+ data: '3W8FqWzBVaEbMZRukwXcm03WbvITt8WVKKuJlcSszN0dCJEsIZ9vLAiDp6dfsFF4PEPcSkiy9Ww4FiBYSg5OLW6snRNdA7Wo62dJ3lqn8TjBzv/Rt+khf9mj/WwJZZ4wum+qdwTRPyaoZcAWgA6PAPPVp85iDBP8UBdiFOs+y5kz9GiB3psvOvqC9LZ/RyK3J+H7ierfWecnbqB9LT5Yuhfi8SO/gw+5vve6z1v8sVcexI0o8gk97rDV1W2gZz2WNtO7K5+233Z7aZlzouEbDZEOGG+zEYh6SctWCspgUATElf8vZ29fABsk3uZQO2tnBvINChs6jCRxnbmnjb2Y9R8u2QRtHjjvRro9E+zhQf3laJc0G0ZJp1zN0wwKx+sL7uM6kG1aszNJkzpykR/Uz8bKvoOfG9vkz9+4Pczh5xR+k9rCE8nbu6Yt4EMiUfdfjZJHAhST',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:01:05 PDT 2007',
+ updateDate: 'Wed Mar 14 19:01:05 PDT 2007',
+ accessDate: 'Tue Apr 17 19:20:33 PDT 2007'
+ },
+ '95ef5754f9a4514e5bf883436d60c38c3cbb15c3f5452d512a05839ce20125ca': {
+ header: '####',
+ data: 'Rko0V7wG9GEmH9pZtXSfxKGDLRhZr65ef/DjkwhsPoYfLryET/ViMjcZcM2blyiLKOxjiS/avGGcXUmInz2AyD5dAFTGge3qAZ3QtxTcNn/fvfJeN+JyGJPIsTIQ7P+jd0uJAb3vPuymISGJluTsP0MZ8zxahSSRUV/VIYwm10tiMVvWEq0+8FynKfWDqJ1eU4pnI47CAdN9CuWhxi12RkMBYgiUzNzTh/tbPTFMc7DIyRfR+si6TuPS3PmtnKt4FMFAX3FznGBCNsonUFf/n7Zy+EYEU/B8wJO+18mqbui5YvmPCPPKiW/pfVuaWarF7zcIcthYoKQfTaCaulO0VRtTA+Wg2LtJv+QcWWWTiY2A9FC/PppLZ8+nFDeng6LqJYKoGnn6qwtSVH38s3Inzbs4r8mSOR099tqwfCnZc9zZHisdIbVm82H3gnqelPmc3IXb3nHb',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:17:20 PDT 2007',
+ updateDate: 'Wed Mar 14 17:17:20 PDT 2007',
+ accessDate: 'Wed Mar 14 17:22:06 PDT 2007'
+ },
+ 'cc7ee01d38e4f1de010d2a235e3b76e838ca05fe70223b8358a5e41975bf2b7b': {
+ header: '####',
+ data: 'TJ5ClYK5JmZvEuNCA+/UeUJQ2rGXbPnFqWP31GAGXqhZmC0RuDNjl3sv0nFKmcdMa/BzvLSywJhkidoRhfKGwN8nZc8M0VpujFkpvdXgNsod6x+5LTMP67qCyvD67pkYMa7O+aosKi/ZWWnYBavZSdhyuWnU1wPxxk+wwcjjIrA5Tm5zTXM/68nLLnIWs2bQbUtcwHgLrBEUshG5oTUFGxrs8zYwodsYUuT1CVwODZrzMxvvbHfH6Lqt94m4hBF0oIrDCd1cSaXghS4PiZkJWQVxJNSsuYF/4PlPrV4ATZS3Jm+DqOxLOOnU2Xu1Qe9DxBppnXjs/WpohYuMV5YeD8iOJLXTQbFKhBJNSCoLp73QywWazuKkasC6cbBrTHYykEKXpt74iE6oKg67YrPkIZJ/jKEGnZ7wsY4ObeDTS7OUbHKxPHRM3ZrmB672R/8ktglg',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:06:54 PDT 2007',
+ updateDate: 'Wed Mar 14 16:06:54 PDT 2007',
+ accessDate: 'Wed Mar 14 16:06:54 PDT 2007'
+ },
+ 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf': {
+ header: '####',
+ data: 'CiJDd/ShGw3rE0xCNZspkdH6hRzvSyaNiuQeMBI0NR1MReaa9uVMV6Ymj+BWVQ8FaOziQ94aolsWre51EKwDWC1otdovPXWHxBXBBI/Y5A4dyQisBeR5E456juUwDtLKX5En4iIuOL14IGt+keUtb5JyfBGuTTA+EnohYzvDxu9MDh/7nzCcWzUxh2zHEBSyowfOwJhx7G2xEvbBgTg+TkejMudbq9k3Owebe9QNdhU9rsY1UMxjL8+HgJmgyo0C0SA91tZXBB3i5ePvg++ze/SW/r+XO/nnVzcEwCJE2UWAL+vNh8tUm+sEbWaqyKwjHNSquxV4cYOG2Lzo45Wp/vZwiUR/8MK9THf0FO1mn3QCd/37AMMneI1Gqk0TNwNtoQKgLVBNhhgX7dIVpRxB2iiSBYyUK6N9LlFahW2QVDS7kdnKH3vk1cP50dj21E45jEhhd75v',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:23:41 PDT 2007',
+ updateDate: 'Tue Apr 17 19:23:41 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:23 PDT 2009'
+ },
+ 'd65b23008b22e5000726db3fd22b074b08553fe82245c3526f708b8d89f70963': {
+ header: '####',
+ data: '0y9WhoXwZSfzfxuql8LBc5/RiclPKQxcBYjcdGv7v6B+WuGrB6uu6d8pjNoUtsZnFv/25sefW3ggVgDuI5iZNg2lBQVIwgcvK5jPM5foit49d3RSWl74XdHY2XqykRNDbboKAiNfro+abo/YYQXjkhNBOC0dWSUUw+HmgK/Bm5NmJD4fDTV7OYFsvX4ExjnX9pktaB6aiLZWN1cZruW3Lsszx/ryHpDtcPrmK2hgLQ4FjRSXunbqXKJLOADQiMbGZ8DKZchB5NcEWlE3AfL6ybJzTyr4jXuS7A9PyitxYNKFHAHpJEhxGkyuhUE66QMt1n9NKzkNx6yhhGdIUF2zVGsBUb/pRrL2gt0X2lsZ+CnWFu4jRAeSi3KfK4VrvnoYkVlJImxPiLrzJAvqkuA6TyQRpJ4yFVJ0dgxBoxZVSN1fp9Yvkph+Os8LZscJtpYPPwVDlCnC',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:22:08 PDT 2007',
+ updateDate: 'Tue Apr 17 19:22:08 PDT 2007',
+ accessDate: 'Tue Apr 17 19:22:08 PDT 2007'
+ }
+ }
+ },
+ 'd620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045': {
+ data: '+iiHiN91FfHKOXC8Z/tg+YynPECa5sgYGGofcoJeXt3FAAkAFu3NsLuwjYIaddJiB3MIxFccrCrB5eDDL0SzOS+j63GcoMCeeiXss9YfVunA4RQTTktiU1BknPYfsfHj8EOPDSVHkPFs7KhAnBlgyaDiQPjYko5Np1H2i7F7pRmfC8W5LGdisaqxFDa+1ghu8K6a54QIpbfOmolQU3w7T5qiOdoZv8GLDDoORvMMb4P09IzXpk/yDEZe1GJ4g1a9t+lHAhiKSvdnZf+MhK0jvs6R6ALlmO84lRP34DmT/35Fr5C7D6EJl0OxXkWgYWelTlfU4b8+SStYP5LPYeD38fodSmObpKmpp653T1v2yaTybI1hojgLbH2DuA5VcQAM5JHMjoSy6s76mf2AZZeRnej1dqdvIOTf1Q6CR+ZNIqnkukrtGq/6elF3eZZh1Ln1EZDiTzsMxUHBngtiRmRDofqRSJUGbEAjw90dBoiaIO/WwLAy4cTec0nJxwYd5M7nchEly8Cb+zz7naP+vEGEAWq991u9NFZhrw7WgNgHnG0E3km+X+SYvv0i2MkqjYs6ItDkBNyi0Udnc4CqfWuKa9q04t8mZiy49LU34Ho4/ijuez3rdOeCO/oIwkRkLZYfFO6IxO56tAI3d6iJqmXY+DX0YUZrJ6FT7bDsUj0umV1htuj/uEgQZyOnKOyA8cSjOTMRIkodI12HrtdrIA966BDznsKW4F7f31VaSxI5ezHsdiYEsTqwaZlFQMsjfZX62EvDLJksJTe3JG15BNgsDUUh1mqIDCmVswFTpUTTb+50ap56c/uERSET0iXP8mb4hKwJkmngrBEir3btuMEMS0xSFQ2jTRjlnWRQr9eZT2biarzgEhKHyu2qCUtsUj7TiieQJY09EXCP3g3Da+61nBMoAwi/VqTI6vQaLGtuDrA2+VYGc8x1SiahmAkRPpQS+5N9qPvxxFRbKforMOvmeboFVxdKesub7BHIXQsSOKsHFZnFHswa/oLBITomp3ewfp125RjBUf1C3hMBNg/tmE5pgLqPfQqWK7IOnfdyt0jc391XWb6H3CVcgC8DcPKJ68o7DBucg9xTNwlIxBTafupsBa9JUkBigqYOW8729lNjj/QTvTUaCxWub9SDT6/y1wQUI1wyyg+EaR0fHqumMhIMbuvIPd/SvKMmZ4TXtBc1U3H3IGbkqIfx0f5rI6AuNMD7/pXTAy2Ot1ZBohnQmEotXRvDwxPMqBvPU74t3USTrysyXfJqeFtHi8GTR5X0m/PYQKWCCHgKvjw3d1CJk7tTe3iV2ulk5cnO7tOydTMJFgPuT2oyDDDTp5jYJPRE0OzZcpAzvRSjELfJ111sFBOEzTqtBUHA/E4BnTIM13md0ZaMr33E7ii8rS7vaKrQAI5moonAtAEOVbx/ZrcZ3kGzHpRCISeteHgnM4I90x391HqDkc1A7b+iDQF8OY0H/0as/3gaVaqs5jsuhIByj0+KmoXsdq3ZBhEQRW151QDCdMKdulNUxbKTYV/t92z3slU6lO8fiy+ON/6sTtS6jgnM+oCLxTfpfBdz0uKG7jiSOyunj27QxNjLyu1nF2+mAcDhtMN18QkJGLXKYv39kx7ny1H74i5rba32/QEAFl5eLJNIQbJZfZG3HzKMVS19ZGwgsYNqV1G52x5+bZUTR8YcrLWmPTJ322UxlhTmyjQv+fVCnpksBtjLGntsGloemFF5YVlcl1AfyHb+KlXiAZn+8vpfVVBddFFMeehokzYE1G8Doa/3huhqdtC9qvAtpP54G2p3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:36:20 PDT 2007',
+ updateDate: 'Mon Jul 09 15:10:15 PDT 2007',
+ accessDate: 'Mon Jan 19 16:09:28 PDT 2009',
+ currentVersion: '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130',
+ versions: {
+ '0bea892da673bf4b3d3e4e97cd3e1645eb177a8423dc761583b876c5ffb1e2ca': {
+ header: '####',
+ data: 'BmZz8j6Khuz7Q11xPA5zSECcqn7BOcMtLx8AmX2iE4OrIwKWcZ+u4B5kCBxtFPRZWLdWcxAF8VfaedkHx5jxPNeWNIa7NEXXcFLYQv9lwUaxmtqodYtVapAg7N+onw28UnV1vB/h7ll26u263jWYohtd5eMnXhEjIEbrQYpf84jQYlpMKjUDhsVQeZvTI/KfiXa6O38ygO9R+xlq8xKgPPX2bkXfPJiyzlA+GoLSORc0tdqseGGOK4BFyp1V/KRUQ/7uQmGs1yNWt/ijaQtJXpWkWXmjHyTjXsi0z+1s0KH8TwSOfu8yjVshMyIyEDd+EsmZeK0QwMCm96v311cRhMgAkQOqL8xc2uRpGygtTkV2frthF237GOV5vwO9IoMZQFlvKZreV5mPPPBeqfP+o4QRpdnJRRCaP8Ds/MmzGBqE13ntwmo1UVX1k408ZtMCO7h1eQVTgCZ/Y2RD',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:51:02 PDT 2007',
+ updateDate: 'Wed Mar 14 16:51:02 PDT 2007',
+ accessDate: 'Wed Mar 14 16:51:02 PDT 2007'
+ },
+ '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130': {
+ header: '####',
+ data: '++u0MEaILPK8riF0UzCnb+MnC51GYcdqCFRKOP7XYt5QvzWtxhDMOvq8ugCDF8G9sYPAoBLiCxFcuCtnkG4fp563VeEeC/dRnArzMDvjILYKAETgpnLQAfyIR+D8RfUkCbr+aOJ4XEKcy9a240OQJFDT0whoTKuX/6XVzVM/D7F0r+hJiOD1ELsVEi/+U+dXXO/VDxoyjFxfa1+M+Ygk8ewecX4nVqwOiFWHNK2lXW90inip0p8yqDsADx0KhE2tjARWVsjoNdf5RSUOYr0Sb0syyjBMi7oF4jpbLvHpu9fe8vpIcve+aSA/MF0Acxh0/gToDcO8ER3K4wcJgNPIs9lXiSrmuklK7kmS+uhz/rWCtZZH/OB/ov5sez5H51EYLmSNQbx5wZGZhtJWNN+AkJobg/Nt4XKRTe98CutbeiiYUGPxQvwG431Erg4y/q216n55FmCBIHZcUsa6Hk7ezF66c52EuAnVEkn7TZLl7vvym+sv9lKev31xpAGwX5Gy0tx2A7cSE55ZoyqOS9kf1s5Kwprx6RSBzfy7sffLSWHxyOSBnd7B1MNZglVSsbB1r4gMgZdYG//MZ/3IhTFbUqqw2xXHzTvBPA2Hl96g5Xzx0dVx2wHWcPcTSH23VrLscQCwyiDVINwmIzyG4CVSW/6gzA5VM4QYOrUDX2ZA5ligkZpWs0HTqmCB4SoqYJUpafaF2sEtCWHUjuVdw+rQiTBCcRTr8f1Vah2q2xbXMedLCRS3Vq4vlT0a/3wGgVD05CsAom31ZzmHQm94hZrx3FTPenhxLtTOHtDYXnbzYWufWEBSJs6VNtG9F5Md63NZvzEZiggfxTREDRZ7I9MBOPhrxz/3tAo+xInwvLXOEnTNOHVATm9u50kDs1qkJgqiXlxi9pZKmrTu4BeXS8cOxJ8O+Yb0Nh9bExfw+CC8X5xiWE58OwalxY2qlvuoR6mOqdcd+L7YPbGq+hJ/7WgJlrvtQe8IjGF1sJg6jfO8ZeGaPMF5NnbQVxGAq39g00on/z6dW0BLZyA6uglv99si8aRLpMk=',
+ version: '0.2',
+ creationDate: 'Mon Jul 09 15:10:15 PDT 2007',
+ updateDate: 'Mon Jul 09 15:10:15 PDT 2007',
+ accessDate: 'Mon Jan 19 16:09:28 PDT 2009'
+ },
+ '63760358c7f5783d11fd769c78ca3f1ce787113368743655ade89bfa67d0d30a': {
+ header: '####',
+ data: '7lG/UvX5KjLbN+OrHbDeqXmweYeOL+0p3/UoLi2K93mCYdwsvx8mg+zghxwg5ITKPiZ9D/QWIShqiPpl+dvQJGWgs9EcP5W7k32CS2RNFaZ7U820rSpahHP561HDcBU1++5wHWszLnqFFiCuDja3OU90dsCTLI3g0igFgqpaRbjLcRTddI/1N48xNfV1YieC5Kei+jZ34zzrfKRn1f0F7mTkCqCSfygjnpRBgZyo9BfJ9rHULBvplvpslUUfFTShkLnCx0UbWPXog7DIZUCOwvPr3KJvmcZtCJp/1nW7gm0E5PaueJF10+ZlB6pKvueu+5yEgVmVu/lctmPX/UwTYZDgY5VWSWS3C+JNAvV87ZQKKmp8N6aMFMNOLCsOYL5hFN9uWGtMmvtgawqt7OhO9HukSUs8pDTgNeXoWyrorLM0cH2fa6a78GxNs3nCSUmqSQchJf5eWmASZgvI5xXmHXsNbuc4w5R9BaEPzyrrSAIa6r9D3rpFbUhMm+qPv9pZE2HF9liJVdWCBOSF8ZfCjsq5suyYz+YCsFHnwwpYmKAqJNXUMIhxkjgOTi5lNIsvS/iNSN9kdkeWINZk5iQFta34uJbGgjUhRy930ZGMBEV36T+Vb5tz50M6/MnlzAoUDeZAu54btKcrIpIq1Se+8zldwd6UKGq5nG+dMPk7CyKfZ5LkM065KGbgEJfHO651AMWp1sMAsbIAM6h1gVKbRjNyNwO+UK8eDpIX1nXHVj8bDVh96160cFbZj7htsUnXZh2AWuY6ahwdrGwYeSFoVAnd6xUF2oH+zFz2coLmLjD4Xm9IuQFsFO0U1Vo7EKUJHkPgIsXUT9He9tl8/K7UYQMXGgPTpercQFQ1ctFEqlPbFoVNO0j7Z9lmeSBcLdvY67CCbsoBDVJzj/wLRdBQStfeSUe7bEI6ff8+0gVkEFFACc48fWWA6NLLtvJkYjdojjA+C/Xf6EGNeXU/VENMJokB10EJUTueVWKHCLGI/JDBQBBB3HKX2VNFcEMJxES7Gfcbhysm5bdmltyRUJAIdXvw',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 12:56:43 PDT 2007',
+ updateDate: 'Wed Mar 21 12:56:43 PDT 2007',
+ accessDate: 'Wed Apr 25 09:59:58 PDT 2007'
+ },
+ '6e0dbb3c582039d985e80e10d94f424a63f0cb5b2ffac6388fd806ef89c1da40': {
+ header: '####',
+ data: 'f5hBUeedsvb1VBTpmpQ+XgGbnuVDMVEAdbEN7ZLK5k++4Iuw7l52zX6AHCWUFMDRfT6joiD2DMj0O8B2g55SeOQIAtZb4PZnbf3+ZEqKMOOI7iYSfo2PctLbzzzztma8EUXYkg7sJKCuZuyXhkWZxikBqVQIp9WE/bhRxa/atnB0jJyttnDMdTAN8kxIizrHFfT25hSbcPI1cSzsmF2nLabO6hLlm7mdLZCOD6DSv9hMeOXgqXo7XdfLA4k8swnOA/85HZFmhaYjTyoDGsK8yoJny/xBbiaRij1HQcHkbG6k2QKcs96pjmiJPoCv2dmsU3Bh06l1O4OEXl/RL4qBGJBKsDW/TXy7Qqa5y6LCEnlFAfefTHVgzuEQjJ2qb/z//oIrmujt+8hEa8F7Jyn6+FGqMNRxDvIQn5Ty/CPUStS1lNL1PEb7TA3ChYkYvnuhNVq8HHf47neGMpUwC5ppk5Zzb/5zEP0XH4XXkNbR5/TYjcb0Df3egNLSQLdO13CO3mKeoccmtfcmaFCtOLXWc2xNNcu09s+/QlZMuiu1TAzhWXU2CAXT7K794mTXHXjgGEaEe86Pj1nO1zHN7QhKDN92WMEdYasRAVDu/XYdzpsKJZ3POhNJp6pynotVBOkPk+2g04S8uujLVSIPZIwu7p3RmPQGGvfMviswhyPvSsPqND77j5msYOLCnXXjeXhOe0E7fIRpxPK1F6/N0R4tZCYNJe9Zo248XdqBvl5ZQWDC6aQH1E4djPK/08CS7/kAECqGqOCDPRvvMUNkGOnxsMx5eofr1YR7zWOZajr2GnfhA9fjrLv6KxXPVU0z702aS/Mfnf87ckGpOKA8/ssJiyZ4fzP6uN4pEb6wEta2DnnacUDd96nMvB9HvGCDoYZH646+n4oev+AnkYTy+ZRpmnsG6/3Z85iH3RwN6P2I3DWvGuN2e+1zQ2kaBMDms8qeXVY1+8qWr75ihizHCJr6E8Rd2Sw7xM0+6mKpu6gVGIi09auHg1+6Q6PlCr8Hy/pc4Exj9Hx1m14WKSF2SB1SYOnm',
+ version: '0.2',
+ creationDate: 'Sat May 19 11:26:44 PDT 2007',
+ updateDate: 'Sat May 19 11:26:44 PDT 2007',
+ accessDate: 'Mon Jul 09 15:08:39 PDT 2007'
+ },
+ '84f3b8571428014d04d7c05528af73c89cedf17e23b1f9541fe7060512f4c1a3': {
+ header: '####',
+ data: '2/zsq97zQBq8wE0oAC15HW5pbbzgokoDkLSEGniP1VL+sW3b+tXYOQV+VSFJo8ERNlCSoy679G7N8tPKgA+rO2/roGP/iKEuE38et9R6v9nhCPfo1vKt7XpvzJYow/qDwdStylXbfW9QN12Yx12r/nkPldVTXCYQDF0Vs0h/I1XMjbILpq1smbNXAUdn9I3W9o8KpREvac2H1ir2vYOzq9Ubhq4jggX/9s+FGm40f5MX/OM+lJGdRPCMG3rfWVeFeWEGWpmg0AXpV7eEuKH7sPrWy+QLXD1IwNE03QLhuOh0qEPsEi6kcCaZyLlCHYlzJ/hIAR1CBlCtGm+vqD+WRr0mGQtl81MMl6/BoW40dya/6aIKNOWfmYNgdfplknkVqxFsJnwVqjQJWfCzbW1KqBvMHx/7oPNjbMS0KKhd8ctOsTLSvq4zFI+mvR6BggwT8rwcfa66shJIaDDC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:38:54 PDT 2007',
+ updateDate: 'Wed Mar 14 16:38:54 PDT 2007',
+ accessDate: 'Wed Mar 14 16:38:54 PDT 2007'
+ },
+ 'a4218c7ece0287ebad7f3cdd6510f424245a4d7d42ceb083b664a4335bcb7690': {
+ header: '####',
+ data: 'hQ123ZhZ4AiXD25P/0Laq3MtRO2oSIrY+GoYe3UAiyEHc9HZDCvR+POEEaARXNyh+U6z8S12P1GvQbzo23ZCt5byhqC+UmbfF3Y4FikM7WmHaRPtWjv8JNf3X0iJ9a2IBLA1BlqgJolnVDtrLsFx+6rBIU9r8pI2jdcsw9w9feRbE9/0S0filh66azojT5RM1qLcIUVWGixROY6PALSnA9PCjA6IG5WUa/DX7DyRrosZ9V4ZheMlzlz8CgEKBTN/HREIbPrEocBOvmnbupIEpOvH3OXKDXf39KAGVBAU2IIkOrGyWfT12p9dK+Zf+MQUl4DDIdAbF81Lus+LQmqtQ1ieyV0nNiqFhPuglLvKRj7QZRFfHNyejkMTZQWjQhBdHRmfSxyEgmFrM17yVVz4cMis/44g3szHMgAAfFIc79wq09oNDEV+ZUMS2xyBCALjRmhedqYIMGRCAG15',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:36:20 PDT 2007',
+ updateDate: 'Wed Mar 14 16:36:20 PDT 2007',
+ accessDate: 'Wed Mar 14 16:38:12 PDT 2007'
+ },
+ 'c6613ccf0c1c6b65798c6f35657a10d4c6033aa32204a90d9d0274783a1098ed': {
+ header: '####',
+ data: 'ATU61Uq3Fe24JAEauMRtY8vMjzaQcPtnt1fshTD4dGuptFH9XoZ4bMC4XKHI7JKbx1NUEbR2ySOj9K/NJuWEGZjRgZbNI/KtuxNedlm/7jEpHQx4ZfhXQ8OiUDd+2bB9g6V0Ck2T1gM4IyaZMJ1QfOlYmGGv8n4flhHC5kUzL2OIiAxNHvKQjdEOccnEsk25Gg6FveKHD6NqVunsiCqhxJ84VBNzHJscuCTRcbt6KwR1+dw7Y+nhTjdDFq9UidlxTO0BKYsqj9F4Kq1LXORkSyab7zKooFH5kNd8torb5UFto8dfI8/+DOVHMxNRh2aWSn3O9bzwi1PfYO1nky2O6OKR48Y65Hp1sm3Xj4AAVHWSGakYUSV5M5XxKKzvoKY6Qqhz8GhbkzM2FC0IKTEcmINMvzXdzKRTqBFg6i0t7Qo80i3sQSoju3/4CYRozI2RrF8W4f3/0XgJf21oUAdTXOmSePSZoqhdejXeNQAgb89v+ZextxA6NJNYqvrx1NjdKmWKJIU+o3AgPYj4UIwWHwVADHITKrIWl/SbOsGP5aERtSiLnC+xqfRUOpgfkAYLcytspouHxvQjgNY4I1U/2S1DThG/N2EzuPl7GLYQ+Y3RAvLObFbrV8S3DS6vXIkigxyJT++MotIKoPBq0xDq0ck6joyvwvg4jXUMKlJa8/LQewJlbH8Lszx7SwjynzEQUJcpCnmxixzSNfRzpzgEBQSiClEEqArYykew3rjz9lc9nkdXUCzz81WYsvk6rGJ6ZdDsfKsG9+kaybuLL8huE0ERhznKDJW44ehDGQLr0phO3CI8n/9Px0PhPeZ1hvoiiH8CFSW5f45ZrFaaQG8hNyzWCpCFoX0/dNsNPsAkOJnO4v0PvO0HDOif1JjgPjCS51vBzxu8gYhkWlPo2hZxHhnnrbhxeBUU9jhLAx+NmxxfTjIWkbtHtVjm3ea/D2nuL1YrZKmQ3Qs6GamKlh3WwkRWRAVU3+/mbSGOISxo0u5v8QSmh/IPIXltniaQgWweqGNnCLWluuTyhoqnqDo0II7q',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:04:29 PDT 2007',
+ updateDate: 'Wed Apr 25 10:04:29 PDT 2007',
+ accessDate: 'Sat May 19 11:22:01 PDT 2007'
+ },
+ 'dd2b4cdeaedfc97c384f79c2878fca9a981efde6ebe212138db235e51b80c64a': {
+ header: '####',
+ data: 'd7ZpqQ4CTF00+/UnTvNnnkMXB2Ow/K9dys8V09Nedq4sgMUk08E1vqi9mdWbzNfRD7aV3blru8PfoRrxXRLTG/bjQ6xncecQoAJeUtSplKEO8fhuzGqbMqz47/y3aQDHBbygMAGV3wLgJO2Pv8p+8U/P3cEJisd9OqTNE+EYQz4eiq9dllMNUQjDY9aLHE8H0ny/5r9uohGNjXX/LfFMshjeS4rToCG5mzRaJPaRs1jkjzSntpF0RLxfU1acpJX4pNSuaLscdJ1lIwc17vygg6f3xexqvCeeFZBot1RwwbztZKbMfap4pRF5KoftD9bXJwoFMXigeMGLy0scpzsp1s8zBIwLhwUxEE0IBh7qeStg/3eRSW9slazuIR452O3Rysb+n/jWMyAhIOCSrnncjjH4XHbzV5GgT2d4f8jfBPmOT7l7C1ev41D3FGFxEb5TZGcJTaIW6ofLi5T5',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:52:12 PDT 2007',
+ updateDate: 'Wed Mar 14 16:52:12 PDT 2007',
+ accessDate: 'Wed Mar 21 12:16:29 PDT 2007'
+ }
+ }
+ },
+ 'de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4': {
+ data: 'ZYvHAVCnw96hB+0XxnBY6p+vwvup1BopHUeepu7yOOSdYNFFOFEvtCbxXXoyVaKZAeSd2Vd7YEwRP4TTJjjWNPapT0D65AFqM8x+0rEjhmVfQGZAS4L3QctzRAgBoR1qTr0iqI/46ETkNq6vHz9mPLHEL3MQ/zoh4Pp0T+uMsY5ptzuMPcG0YwajSm5J8XXV2V5ZBEANpgL91xjgh1I9LiKJa/Lv3R9HAZG1uuCvzqjA2LWYeH+6ZcSpadk/UPxDw9c78FUnSNbHAcjuYZ/yI3v5SaZTjEzsB1MtAh6AFiHtvKIMWpqoOs7XQPhz1xXPoGZ7VR64A+/bN2h+Uqn49bQrKjTRGegqkEWFcBwhFH/ZkYfSHCGmZQTVqOakqyofJ22tS0ief45gYaO54YvIliTNTY7SZMRCEhUzz6dz8ENqP7FxhUVcQRbBr0JTmaf6DAwu86iDgkvcp1cY2trnUmlvrgz2GW6TgXoFjFlchUkHIByFeIJ02olfJg4zP8PzgYp2zhwmXL8iXHXnwzuP9bQKq5j8o+UhR11zn4MFvWQyD1UEplK6vphMdS8iXDViLrOwuMz1XUf7RxNdW0gqXwx+qLU+CeypyWLMIlgTlOr1pBqD/S5Jx+Gbn5GHQViuFZHJUjJsU0xel001KjB2Wf1Y15OSdLZ5l0tn/4HYKmZLufTYpub0xrss5r3Z72RYz3wvAWFXzkxWa+oBiRQiF6+ix8DBPTc3tm+ORnQBYcV/VNVRziimV3MFSsD1nHgIF1zu+eXIKE7/b3lzY19KpvtiBio94dejWoA/WO7KXWv2sHH0JoZnRh6lzu0HRFgYqVm/052nCGVA6XSfrFtfIupxdBs22C9wrwC5/Rwanf1S8BQIXpm25P4dv9Y9cS6c2/DUHcle4tsUJlqC+LpRGKXRdolFkiL9r01V09Kev/K2oXaWGYmBLbRfIyvEHyHNeNXv5fnaZ3pTlIwXjJ9K9yKA/1AKAsAEuKlM3N5ep9pfyuyfOWj1I6RvBwVqKvcBZtYJ4u8n9jrxiyq3ZZ35eB62D+ceOAD2s5+LL2IylYjiJA1OO2qpu4x9rt1NHXM6LYJAruBnUrJ0Ylqz/ElcJn/lXAzY6RLqVcZ+tuV580AUkFiaXFEDcqdJbbzh0R15g9DtaeiQZd1PG0a8Xblj9aMQoRDRJeksw1GWO7TfrJX1Cu4k+sgARWRzZ0DvB0SJAxPcmhg2iBByn2ESlcxPvMOpzuJI11BUQsZZ7dcynubeMvdqBeKsC6HMcm+8DLEUPmzsC3HIfARlNbt1fOrGJNuKaLvF1AAdwllELoPf3lQ6EVZI120=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:20:58 PDT 2007',
+ updateDate: 'Wed Mar 14 16:47:01 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:06 PDT 2009',
+ currentVersion: '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28',
+ versions: {
+ '201725aba7b4dd93531e40ee08eb8156e3aecd3db4f11e54d4d88ed5508c72a2': {
+ header: '####',
+ data: '4ndloDtoW1Mhat41ZlW+nN+WkdEriCn/z/oclyBFQSljJRlMwUFvzE/OCVYc2fQx1D1GBedY/O13v+SCAiJXUrr0dgrMDOfmYy7ZtNo0hYshjaYQucJovt7UQLeFAuLO6rNK9CrsYA/AWoiT878z2iCYCqVq41sL8juCm9n+d9aR0eyjXAKj8QJzVz/uvdudoGQ5xL18x2yUZnemY5gQklYlm0u9zzCJ3rLOENnnAggFnSJ0oysNjB2UwQY6P53bqXzF8E+u6Rv3OoIbmCIZMaoK1G5ivnWHwhLzp9UVdIj8ipfLsTJnGMk+aZ3nnEJ7wQCaaLy/lY2RYmSeUTTZt2ImK4ZLrSxRC21QkD+juyIiaEBJdhP8UOfcqE8Hw+etc/Cl0QgBtv9AgXD4BiZs3HUTXsV/PhIzP+6TGyr3/A2kt8dv33V7Gh2Ba+28wtsG/+HwCMk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:45:40 PDT 2007',
+ updateDate: 'Wed Mar 14 16:45:40 PDT 2007',
+ accessDate: 'Wed Mar 14 16:45:40 PDT 2007'
+ },
+ '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28': {
+ header: '####',
+ data: 'eSAwxBi9CLckMV3o9PxBjVZZ47g2AOIsbPt8QMPta7U+6KKUm58cXHV7BDfRkbin3JYQJGYfu4HYHmayGt4IcX4RD3riftxnG3UFNqG4LQQ8+fwA3xTMBisnUSq0JYc/PKdBKzxH9x8moSqZC/cgFWe90p0PxdY13otjd1qvDL2ALAgY/uEDboTcLTbSEhpGIYQHtQ1ZjDG+KXI8J7atuMvS0KFreNUm9+uMZT0yCXwNpGy+ez2+ZDXTEjZUKaFPLI7g/vyySn6VMXmlqJftGXZ+fW5UWGaxb7WFa1hh/nI2okPuRlUQh50xXQJXVvanw1ATJbN1PRfYEfvQKLlAAwYuoB/qL0y0vU+3OktAbgBvwt9prs3IsqjwMeaejVTo3Yj9pQPJ14a+6lxQZQRFUaLePIPdYvq9NRM7chkNYminW0JN6umi6bvJ4KKTyjAglBQ6X4s=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:47:01 PDT 2007',
+ updateDate: 'Wed Mar 14 16:47:01 PDT 2007',
+ accessDate: 'Mon Jan 19 16:10:06 PDT 2009'
+ },
+ 'c7398bb27021058c9965a332d678b0070287b8ad12694bc8732346e6d84fe9a9': {
+ header: '####',
+ data: 'L+wk8k9ejeUeVz0offdItFpy8drMl1hi0FODBMKlPIAmEcNjnHU/IktOlyLrK0YHj66DaplXw2EyRkJNcMIbfACUtavxhWBH9VTftOPepsbsrU19aP6Xk7R1pr1sC76w1TgKCjE6IyBnK5qk1oHqcGv71GJLMmiqGivKyYOXQ45SH9tbHC4GUrg0YxoAYRwXqg+SlwRHpSZkX55NzPCEZn9eatGKCznTZs7pg0uBoM546fOIEBMgGndNk6gnsAH7At8yYxDMnkGHUctsSExL1O+W3bDDDx7D3uPkkjtd9se0exPru0fmsfcKPrcRkx8b8MAdgcylOtMdYvSudPdR6foSIqKMqktH35QlH6Rr5E/ire3O632QlmCieKDoPk/cB/qL3gKedxT1NxtC7SNR3aumKBAKOBDTVSjWWq3sIImQPZz+RUdRajeqkryNDVVPLFyjdC0=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:20:58 PDT 2007',
+ updateDate: 'Wed Mar 14 16:20:58 PDT 2007',
+ accessDate: 'Wed Mar 14 16:43:46 PDT 2007'
+ }
+ }
+ },
+ 'eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 13:35:58 PDT 2007',
+ updateDate: 'Thu May 10 15:01:21 PDT 2007',
+ accessDate: 'Mon Jan 19 16:09:54 PDT 2009',
+ currentVersion: 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec',
+ versions: {
+ '157b5933272bb6b8a70bbabb7fa0369eb2660f7f0848dcc653f592f5afd4f2a4': {
+ header: '####',
+ data: 'z8BUTeAbrs5GeJ+SxaV9ceaAoqxtW/touC8xhjkEqbG6+IgMrfuz6ABRn+vwiN1/Vmfw/tyad4kB2SyzKgaYPH7rXyBir1mzJi73/oHsXv5wWNhEePmjZginGGcWQ0P4AnrAoxlaI8tXo3fbsz8e40x1b56N5J6zIdvX3eewgIMU+J+iomZVPDQq5DNu0aGUL1xs797FNm4vLQbVRF+mzrZlT4XZNzOr/W/Br4vG/Ureoq1QRjAjj+8HRt7ojmzrpDX3RtmSbWqUPQqx/KpFGqVUNw0zs09MomVIYilRawe/zegW2KZKK4rmqoUm+mnWQTf/I31FYO2N8dLrI7OV71EWlVN4FSO2A7NRUd92uVxHzItMQPS3CSQ57FYAC+WhJh7k+/ikJumVSf18pZRSRaEeKPxbJZFJqrWsWk+SsqBIJ4EklAnBBU7zLmMVe3GO/ml3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 13:35:58 PDT 2007',
+ updateDate: 'Wed Mar 14 13:35:58 PDT 2007',
+ accessDate: 'Wed Mar 14 13:35:58 PDT 2007'
+ },
+ '1835468626573e6189e5302f6f354628f49900efe08adc931990d1c11fd522ef': {
+ header: '####',
+ data: 'Bv0je7USknogpb1ng86CEx6GbHlysuN3e5Iy43kg1iN83AgRm0Hp6/yMivQe/mEmQb+67cjHfKKrznAESYzY8uv3b+ystxoIaQL7tKJ5HYu2NUVvZxRC+PE7AkBhc+O28OzpZEHXXz62uZFsjRDw2hC/KP1XfYW+Deuulnpz6sgjuyWIYXF2486DzaycCqX0NmYXKE7oXAthOlbo+Zsm8Y5MWh5ploJFrzhAm0CCzjsGSa7NBOBWU2o6vN0NFMcOG2pdjZGWpWo1QQ5G9tx9UvM5pTamwcg5TOr4yOd16JmYTDjK2Fd5mdUuG3zIxFR8StIKI/Sd1ah8U+DGbNlVYAVb5OREJxQxVv6I5dxGC43CGWbpx3fB5wuFT3Jek6tv+LgBJaI9Ika79NFJQrLVMFbQgD0qU8YgCmLbxIJ4gxMBUgTN+v6PraIDHleYlpW3KVIiNxv2Ztc=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:24:49 PDT 2007',
+ updateDate: 'Wed Mar 14 19:24:49 PDT 2007',
+ accessDate: 'Wed Mar 14 19:24:49 PDT 2007'
+ },
+ '47f73115ba2079f4b3703f502e3455498900a21941625c25d52ebb7da31055f7': {
+ header: '####',
+ data: 'pK+wAHWg4IJcixnFodLQ5EH+SFQIOMOrthx52u21WZ1ziRWJLSYGwA8CNNK8/welwzPHOPWu2El+zE6cwLHrzmL8EARLvvJ2fEK11ZIvF2C3R06uNrA7QFZr7iu6t67osrpfljqbjKQrMECUCUDrBywRvlpaeIlThfA3XByezK2HtbyHD1/xnyQSenUFu/6Zq1EkVdm9iCkbej2KxZSxA6qMl1WcnplBdOqBSmeGGJ0+Ikn3LZ7t4ztqflsug7QYyQlrmI+d0UB8MFWpf6jYjZQwf1rMH5XHFvrWUCi5IbFNJBUPF3n3IfUlrnjUSBEcW3tmodJa16/biK9/iKqh5ImlnpbQgK7CStgQ8ByJqddJre1idCiK/dyR1z+IXHTu4qm24cJeGUk7la4WMG2O5U/otFbXG5wTVgbLsxfXlE6fzxHAzvEftEE1ZPNOBpRZ+LVYEHKFESIz',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:41:15 PDT 2007',
+ updateDate: 'Wed Mar 14 17:41:15 PDT 2007',
+ accessDate: 'Wed Mar 14 17:41:15 PDT 2007'
+ },
+ '6564169ac5bce1a632c602c51e9e5d637bfd4e87c1fa276e2cf65f39405fc4c9': {
+ header: '####',
+ data: 'fs5hydWDsT/FxWTb57K6zYKwVF310zjHHHtRS/AeBN8XZqTcirhV9oxJW6G6TdDkD7nQfWf53AbsivXn46Tx7oarzoU4R+1mz94TRCkEe5X2X7Wa3HbTj38+QwbkomF7np4MUkVc06aRPqkUE5hvSDbGn4SyKCjo/AnGhuW/QJIqnWVj70tf7CNTb+GR/y41JhJd7yk6U3cIP6Imik+DAvM5pE0KqxGLfLs4c1ChuTFNHfiQbYjs3tANqJCO185t4S8UIY5VxMRcnqgRoloFK3uFACIXoyDGG3FjILgxRCw2ePFsrm2Jtxv+JX4BsM+KDk67OsN91rjQnK5vBP72SzSge4EDCKJXYKdA8KJGYNwRIzk5d5ycbZgW4YCizVw8v7sLMn60v7YrDfBwXAJvvlTP1chA7HoE+WALqXkfBW29AOCNodE3eTXbI7iWz3vcWOCPvSm3hho=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:25:28 PDT 2007',
+ updateDate: 'Wed Mar 14 19:25:28 PDT 2007',
+ accessDate: 'Thu May 10 15:00:47 PDT 2007'
+ },
+ '7674ea33b650e84f9a461a91928bfc259de5549ce905339fc3b23623c6cfd09e': {
+ header: '####',
+ data: 'D7mLcDpylLnklOtIw/kvYX0M+CR6Si2t8CB9bTT3ZR+bTpXP88OtI19g1k9iPEUPdgbtFKPVw4oNmynP3x+pc8R/zzn4v697SvVtQxdF39Jmry5dnB4SMx6oRkuaISs0nxvTrHJe8U+s5ehzvQ2WWxWZ+LaoBWaYR7slgUFKLdJFyWEalPwMPVu//DoLZeWg19n2C/0Sy8u0DGdYHJVserWrQqxxg0h0m0x1wuKhF7IGvqgyJ31T5w00nMHNZbs89cUuqB/2doMgoUD9BqV7F/53AveuBDcdCc6jlEe8NOdoUyMuhwwwTyKONfjY5e5Cu5W9I36o7GpeKlckoKrTIWFO+NLG8XZvP/f2WJCsIOrCk/LI3C+bxBP+bK4tHRH13iXLeJYUlMK4ibcf8WI445qNoggJSbZzGr7Dav23KZWPcxzRxhI2u6j25/kKGnu4kcMB8ke5N+4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:46:36 PDT 2007',
+ updateDate: 'Wed Mar 14 14:46:36 PDT 2007',
+ accessDate: 'Wed Mar 14 17:40:01 PDT 2007'
+ },
+ 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec': {
+ header: '####',
+ data: 'u9HEcfobxZhG9BY3dVG68ZUYkREFcZ4q1o/xWyt3qje3icA+Nu9yCrZip/4fqe1daUX/MHyzUQdulIfjSwATjj3vvDSPjuGvrtx8oUjJ/K6GFsL366ozi45LkqkOaH02/nVrb+ik2HWIgcne/OzNrwf1mWLJoBF+8ZwQ44xqQK7ikG1mblNWWbZFFQE1B0QPmE/I/1ovm2hAr1ZsNj1l+N96hwGsdsdVFTzn+S7Sg8GTbxEFAxDQkBYEw1k/R8i9EIBndPoDZCebr8vP+c8qSEk/YmBXJ1MGVVvic0/Utn67iNLz9aBnv2z31DvvBj8bIwOxQpB+tom5Ivwe84tFkwwvpxFqYccrEg4bbMcevUo67TBVe+Lb2wzcK0zOr7iHhswbXaLzzOEQ6uF/v2ibTbATP2zNq09AIJjynoSDmrisGHsBrHgeXjiDspc9U70PVC83EsjPRwA=',
+ version: '0.2',
+ creationDate: 'Thu May 10 15:01:21 PDT 2007',
+ updateDate: 'Thu May 10 15:01:21 PDT 2007',
+ accessDate: 'Mon Jan 19 16:09:54 PDT 2009'
+ },
+ 'e699fa287c2de3d483144b48064a47cd0bc56a436431ce23b48cb8d8c42ce851': {
+ header: '####',
+ data: 'hVD8NOt8g/DIe48JbUUo77e2hMf2UBN6ah23PrIzGTpq0LifC2K/0/s0yeL/PHUOncdT56NccKpF8Fp6EWJqDKoKZPWASuB1vHCEkdbcxlqzqo98VS3A7p2JFwQzSv+5t6y909hhbxobXMCUfZ10HBqGo6TaFc6+pkYqQ/d7MEnj2NuAXC9X9TLLuZSrZ96NCKGr8YVKzxinxHdiF3TdRvIppFByXPlbZ3xiielEnYm6pu/GffW7Hkwd7Vou6jwyggxVqvoVtuAdiIy67l8GX0gQUGipFkvvrAkXfm0sgtWGQvpgDuV/bXq/L5vX/sFpWI2u066lMUOsJQmptNP/Nkp31+ZNk1nCcUIYDDa6vcOy/gRrOFcenPTUQjRkE95KPaCqYBSIWsjoFE0EIB+iBnBCTK3laBSC7pplOtuLCY1YJcJuOkzCVQCVXjhWrNJM77s7a5OyTuE=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:43:29 PDT 2007',
+ updateDate: 'Wed Mar 14 17:43:29 PDT 2007',
+ accessDate: 'Wed Mar 14 19:23:51 PDT 2007'
+ }
+ }
+ },
+ 'f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732': {
+ data: 'vxOgJv/v3pP8GFqbFLTcgtBqw8V3zhCN9rRXUuWAfatABtr3pySWvt74ITeGw+sDtApBsu+zTY/95BFVtK3y0QJkC5cjJYhLDwvMwpqa0lRfCXWSYmuEhbPETwkW1MN0kAEOMqsUD9cQCH9GDD4A17W89AoTG5Ce//X03YBG0cDjbotgENsWjQpK88LXABHBQAoTF0BPDjN+xai2QPCgN0l1IVpUzI87oZJS7x/4r6DjGTOgcc3+vtEujr+8dGNaq9xTEfAFs1kv6GMeT+R/VkIQLVO+vSxi2fd+954EAXQplt047+aZ3c0c78N6B+GhSi9DgNnbTLu6sl332Zdgo9R09uucS8nvRp3HcTzxriKpx0ZMDh9K9ig5NT9Z2H49pDjCJKTukDU7b2ktOEUNZt58s+uIlw1bMFY1TMETGAHbTq+hld8Szg8f7nJGDQF10kV2ykVEQ2oUBMC9y9VCLyYD0BWId6DUcTNXyI+MqAC4j8pp0NhURY8VSjtnV4Rlq+b48ahP/ifJdq+xrSiT9ykGqc/EyebC1uCTIZewk9MtIAndVYPckMIe0xQ2xhX6/m2bdNboVa3dnS5eKFdbd++un6FD+QAjgtcBkXQnwfptottZoghclKL5h5gPePCQL/66CLYy5+3xctfCG9u+VkH97JKL2hW+XZ/KuxLPFkIAYmbFKsNdIizfpbk5WJvoSzacpo1mwNjZ53zn9xhy/VkSIz3lGl83a6FyoHuR9VklyhTaKrj2JNWzjLaQPiR9Sv2eFNjLTivxtxLwKae5Tz14WU2QlXATC5xdcLeF9nK7yYVarcKlRsYkkvetrVpRiWUVfy9mZQIHOWJtY5AcptKso2Q0v4CuD1C/wV18DMDXzwMXeOq0cKxCsZOuWjO6RwWKzfeZnJ99S+EsFmdI/wxqiu9slJ0xXvgLvjiJhJ03qWwZV45peU1qmvKQrXS80QqLp3kUfRGLbZNOvkZbyf5OK96MA7lok8PuCZGg5jZHFX4B3vxSQ32P7VGSWO5CqHpF45YwtlONZKB0cuvKTRazZ+B2zJfwMYRQloj6sL5501oPqmjVtDg+0aoqKe5DmTf+fHV4FwAxQ8RuW7/BVL+lwf+zjtd31I/yrlDdb/Scs6yayLV026yuHxdQRl+ByogtrXbY4ViuU3NCkVrme7K7meRHnQdXyidhjzHdoJnRPa0IoI4VW3VwWNENRRNDTta2whOdIKsQYtscWBWZnQplRmDChGikERYQVCWejDNgvnbnGrlyQYPF0/vcv6PoDpIvh7Pze9y0MLBU8DnWqAhpdqHPNVdjdq51OKlSitUk5TSN9kxePe0KNFZueLjxZHUFIZ+SIkTxoCoaRWYMJIWvYkcT5S9Y/7NbdapuUaLZNGDc6tgD+LVYRRvGEdPWaOHb7G+qOmdtx8vYxZUqq5mtwnIBRzEllTJyKwwK/kOfAxiRjLxf7SOXsubPuA7bHR9fI5rROSR5rcU+nOfSV9Wf4wZkYBlSmQYqzQfmwl0UCiipJVa1DwYwLimgo2RqhI0M38gEH+mrknnevE8zlUIaEWzxoOnyWbtCecakXS2XvE9j64dswJ3bbeQ3fDQr1308x9qKSjFdDl3eNcJx2e9YwC7wZnTmHeHzRXnZwXsJXqMPDQV99wEDBr71BjlDjMx7vG9bOWrhsyJ37EOvO2X41Ij3j0X4MYpbNgxBFP6zJSu3gILrtqQRpQq6mQJ1bWHyCN1ge1zKNT9pG6rGTRPE9LqHROQuROpgFM1R+DqW4XnGOBYSOtznnsnj5fxfdpGeFq+v/ftvVuN5XsgX6dnT8R77iNUs86Iz2mkxLaQokkNzXl5o1rnQIse9+kcKVZ72mf5SG9s9DD7cZ7bOtmkuZCexJpieIosqLV8jc0IA',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 17:39:39 PDT 2007',
+ updateDate: 'Wed Feb 13 15:29:04 PDT 2008',
+ accessDate: 'Mon Jan 19 16:09:41 PDT 2009',
+ currentVersion: '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74',
+ versions: {
+ '33ce5a03b6d36f59d0fbc9445dd01a515cb56eccc6d854cffbf8aa66f3e4a45f': {
+ header: '####',
+ data: 'pwMmqFOwpW/uSys3hm/AcoERF3eDj4dO+O5SdYsR2mJtmEfXcjhS9altLhVOsck0KMQJdxE3rNDFbduF35yVetXuQrrL+bSRlXMq03EXETyrRzIVhFEM4BjoCSS9nKGgixp04Ve9WSuwD4cXRmcN/L9kCJSCqflXqhkYkjAywQoj1KxHPdAqMaGRpEWioUIfX+NiWbO/qtOu/USAhHmWFXla6/A9kKQeU2d+P3zl9KF2Zm8qm8NXjPKmh2dkd70ATbdzxt9P3BafoRf/Ud8zLIVdQYTbv0pn6UMIiUDRK1ryvgfSY180zg4qkP5pBnxhEgOxbjT8JO6hCl8n2jUCRJLdUXHwgpeuHcKYDyZizc+p9Kbc4+d8K/2UEKgSR6gza6Cpw5TQbZQq+2LxWUoVb3HM3lTqBKUPM0FdY2/3twZm/1bI1uBMPnyp9x/JsQV+xOpu0ZulTA==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:39:39 PDT 2007',
+ updateDate: 'Wed Mar 14 17:39:39 PDT 2007',
+ accessDate: 'Tue Apr 17 19:09:44 PDT 2007'
+ },
+ '686ea579db132287e8e322194652ec57cba6e60274c00f734db7a0b36702c817': {
+ header: '####',
+ data: 'ilf8U30hSq2mqje9kZkKQAMiEFV0aptXrm8fOtoOR8pp36V29kXyUX6FEOh5eXSRr/jbqGytxKENJeAGxnsv5U+8GgbvlYaR4MPM8lbKcpAoBCc0+CCOiwnp4XCoXFCNttbTzfb6qgR7wqdK7YLnrvfzJieQqJukQZvtWtsVZB/Tis+5niomz8Ca8lo/FjFOIjAq6xtwrW4CS12+yZdTKNbj8e+HwoUcesF9RbCKQlpVHuwhZ/8ghdzDgjEE8z44rDepEv3Lx/aUi+67velLH3j+1crnxBUz7wP/dWzftwWgIxDkCR/vW63yY2Xebt77swDg8g1Qj5OJdYiAq231HKaZjxr10y88JI5HC1EvbbduDN6pknKUgM+qEdojpi2BmjK+9MtV7sVhJoWqwHG8q9z03kgGoFnWEb53HyMVes1n6HYfzwnw+idPFWGZJ4IB25WfJLfQuQ==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:12:39 PDT 2007',
+ updateDate: 'Tue Apr 17 19:12:39 PDT 2007',
+ accessDate: 'Wed Feb 13 15:27:04 PDT 2008'
+ },
+ '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74': {
+ header: '####',
+ data: 'l18dnf2TRfinuu9KDraIo41yvG3mNFqiSCOkyMI6WZZD4RnF8R2Ob19fJ8zXv04eDx7TYyyGP1IlFWEdT3LBrOmmbtUmIvtYanIfKTkT6UGHNH2jh1HyHqJbpgIlr67mOm6Es/AgF44BiyJrk5R1y9tA90oeUQynMufiM2MFLpdalDYWEh+W7GV9WCmbBIU/soioTJ1ep2gvy4kJvTSrXENaxHevKfYwn8ucocvY+hjkWB4GWOR40qtaG06wWMLeRsrTBH1jBG9srzbBa4u2IQ0+NJjQrYdiu7nfu6Uyu7Ya/4bxV3Sukao91XvXSFIhcI2OuKl0njUshv6BDEfHwXIQuPtn7KaTx2uYl1pUeTv/tAFvf8Ng9OFNgK0siIMkeg1thFwRiGSmxjP0QZipDtcCekIxj2k=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 15:29:04 PDT 2008',
+ updateDate: 'Wed Feb 13 15:29:04 PDT 2008',
+ accessDate: 'Mon Jan 19 16:09:41 PDT 2009'
+ },
+ '7ee6a662d1980467eea86a58cd7299ee02000740693df2a7ab9dd64347dbbaa4': {
+ header: '####',
+ data: 'ZnwtGdkg72+TQKCJQhZQIqP9sz79FcptnmH8VJEDQY9xTburh4cyhgbgROBis+awp1C5OyiAAoWfPnuRAN8Ai3d9f8M8yjnDGJ4BAJ6OjQ5r4RDQxNycCApXWO3mJpBrx56wMsCVWT6Z8a4khzPrf5HlDtus4lRV4GRdhU9FMpwuaCfgVD38MhlYXDaPgyu/8N+6eQHuFxquXjOJmptfO6tVhP1+/tEHo6iUAX3sXMZAionssRgPllQJxfzrsu7GQk3h66PakRzgStTHUCcdyoEe9c4VnvUgaasTbhENA4x8xPrxjo24zwxfFpWNEb1+pe8N3+dOXTsIdd3CMKrxQ5KkwzyN/Bj9jXNk9YX8PC0geJiR3bCGtPsAd7aEFB7E6y0RVX/RL5f6x0utSYw8mg6lfprlr5A=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 15:28:28 PDT 2008',
+ updateDate: 'Wed Feb 13 15:28:28 PDT 2008',
+ accessDate: 'Wed Feb 13 15:28:28 PDT 2008'
+ },
+ 'c860f9bbcab5fa70854212e18c11a3e9bdc2382f91cfbd25636955c443a05f8e': {
+ header: '####',
+ data: '1rztZ6mKVFVjlL1kEoUsXEMketdElGbOpYK9iy3g1/WeMcTd4D/UjgHvmQHzzNuYJc/yx6cCMMU9dofLe3vWLKhqDAPAVCo49qiH527hP9rQE+0SNO1v2Ymk80hL/gqBfju51bIYxPKAD0uYA+GMX7OdL+S7qdealebERcnVa0K1AHiVU8lu5yIKk55U8zwitk0u86J1zwcraiM3RGXir/x3oZRIKDwT+lhUJPr8GbVjgKlPu07Ii8OdrAGdHefETDlyNnaKPJHTbGXkd3HZ2CYhJCQZGn1Hwfs46iRd5aO+3UErYtgIHl6CXuXd4E+DNW4UJZedP9YV860DBkpqMiQokEMYTh8Y2sOUyf3ZEOshfGvJUhj8O5p7rNm4+2BYO3XhREdV39tn4vUj56wYj+GL5CekEl0c4Mx7ViTQA+gLvk52V2w/5gFyFNQ9U+jUQpb2n+d9cw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:11:33 PDT 2007',
+ updateDate: 'Tue Apr 17 19:11:33 PDT 2007',
+ accessDate: 'Tue Apr 17 19:11:33 PDT 2007'
+ }
+ }
+ },
+ 'fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6': {
+ data: '4zgqvaaWm7nJO09LKN6o5hbWwGzOv7VVmXDu5T+JCHTSOXbteogax2Zrv0uKLkfooGFThJBk0rXfXxE64vMOq3AeHXGw7Chg7hz8Z2Lpjr4FfE6q7Em7UuAlAuL1PiyXXJJK5iSsRY9tkizuYl19aXW+CgpPznYD/PyXgeYxqt9WLqK8cl5iAU87R0cQDhwl16ivzVgiiFeaB6B5FQqWBAHCEgXhqTsaw2gv4snbmPOqcUZbHy/Vb9hv4lPBJwGFNxQzeZUad92VBC8YbIjmbohDsXjteqD2/k1qOgpUB/U5BpyVwsi+5ahgb8gbS+AqYoRDYzkaj83ksPI4JzWyZhpqjhDauaI6M7hGnJ4GB8UZc0M3WPgrlf1r+TXCgpcfembqL1MyteM+C+ItPRP/QdaIXxLOmvGFOBKQYEI7UceUWBCSEzORlS2S2lltlqt+K4B8QTULiKaXCfRmF/u60FpJufIkUX0pE/rQVChxswSWvh7uJFDBIDx8MplTX724A7DN5d4/Ad4Yi2cj3V8X/DEErnHTvirP3tZ2F2oAe7kIdu+JuCqKcMaGB4hVijzv+yim2TCPvrGTFaMmg9PvcWHpik9jEIabCkdqAR8EGIkD29+yvG4vD0DTRKv2vPIfr60ZQnsgs8nlPPoNa6lNHvI/EO0nBGBYBc1TW+syV5h/zOG3rHX0XCHhISZmDMjra7eUETWChncR88P7ciC4yJQtzXFGzeXp2ktzZ8m5g1EQfgtlUVZsHN8e4OQ9DjKt0unfq5RFBj2jlG8TBZn6ZpebxWR2qOxp81KQLHJND9zRTy3h65+k5wo3MnnxE3GbeXg2dFIORRvGUT6bWsqW1fqR/pg1GO8KNtrt3CryZofgE52kuk6hlcmSk9974JR5523+1/hbts8n5VrTi1C6GWhnxpiJb1XIvICdag5g7C2iYppzLKVzbJcFMegwDUrapbmGhkqnGwSY1EQSDyagPr2xlziWhdWdCOVAYcyw8dOpdD97QhVef0OWrJ8nbgFKD6wn21475OFxooheWiMCyZwXqESVG1cVCjeaCsymBtEVPpmQdSkOfMdXpKVF+3osb4K2XDpPeU1zPWVozeMp68YhLztQ/g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:43:29 PDT 2007',
+ updateDate: 'Wed Mar 14 18:43:29 PDT 2007',
+ accessDate: 'Mon Jan 19 16:09:30 PDT 2009',
+ currentVersion: '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a',
+ versions: {
+ '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a': {
+ header: '####',
+ data: 'QfC77EWgmmnxz9JqLdn9Tw7mNztfQZPdNpaML03EdFpphsjgLloqBRX0UZ21oozjQGHpcUMMOsaJgzCuDlfh7T7ePVV60Ps4AJtzv7bHSVGKsj1iALU1qjtesOYJayp8bA/3peo4HEnVgP86jc5NTwJxpsUhNG0Ae93xVu4lPF0gL0/yjgZUHqYZXkb+oXrcybL0BSOjRnB9fRpA1dEhcwJwoelLTvg7il354qp/Wo+S9Cz5E/K+xnlJAuSXCRXboWea/ZZ9TX88q5uUcY5jLF7Xi2HoFVZw2f5tbycxwGtT1CKXp+OAKn6mQaBAYM51zoMNDT7MvBDXD3v4Cidjgh24GZ2zndfkYT0kHCtY7OVIVSTsXTR+5/XMedojVvDlX9LBa9ST99NLCUy7Di94rJtX72ev3Ei3I1w3qPvCl3jgD2VbIwLogCzqLtY+2IkLAa8M2EpX/D+h',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:43:29 PDT 2007',
+ updateDate: 'Wed Mar 14 18:43:29 PDT 2007',
+ accessDate: 'Mon Jan 19 16:09:30 PDT 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'test_test_offline_copy_data': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ '9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8': {
+ s: '55a27b18e8fdf1fb5e5bcf859cfa50fcbc69c9a41f04e371606a86411a98f460',
+ v: '983a6c79e7d5d490c3f13645c49760180fca05cc677914bf60fee009ead5a65d',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13":"0"},"data":"Ki9chN/ker5c+7zB5NinstllVq1Vs+N5pezZIohKVVa15VLSIyre3DRilRoldy/94LbGaEM3SZsMlf28hYbWySln3ekNMIB+MItaYb8urw+8U6n8+QaRMAClHXukfi8te2d1OIlgjbrBQNMmzBorjIs="},"directLogins":{"index":{},"data":"54KM7x3emxWZH4CQDLBj4SkT"},"preferences":{"data":"AwOQXmReKkLpp8qZa4zjaWcY"},"oneTimePasswords":{"data":"YgSYIsDeVT87bfiASQqXA2E9"},"version":"0.1"}',
+ statistics: '6Kupec1ZD7Dw0WzK7pPesnLE',
+ userDetailsVersion: '0.3',
+ records: {
+ '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13': {
+ data: 'dXql3HZJQRpvwOe56SgzbbpMoYWRBjEp+E8uMJT7tprzYJ109H1SnxRWWiXlDOzH2XfoXahP3S59K7rHeJ+/icX+ZrsOvp3YEW7wdoEDosyvrQuxrmHdusZ3BeaFIhQMmK9wqpAzpKCRrz30l/yi81zNpLgTXLLK9fiAyksmsfQL3VHgQg==',
+// data: 'bXql3HZJQRpvwOe56SgzbbpMoYWRBjEp+E8uMJT7tprzYJ109H1SnxRWWiXlDOzH2XfoXahP3S59K7rHeJ+/icX+ZrsOvp3YEW7wdoEDosyvrQuxrmHdusZ3BeaFIhQMmK9wqpAzpKCRrz30l/yi81zNpLgTXLLK9fiAyksmsfQL3VHgQg==',
+ version: '0.3',
+ creationDate: 'Tue May 05 01:28:36 PDT 2009',
+ updateDate: 'Tue May 05 01:28:36 PDT 2009',
+ accessDate: 'Tue May 05 01:28:36 PDT 2009',
+ currentVersion: 'a22bad10653a70ec3287917bc23d642fe698042cabbcc1074b60122cf2bb9d4d',
+ versions: {
+ 'a22bad10653a70ec3287917bc23d642fe698042cabbcc1074b60122cf2bb9d4d': {
+ header: '####',
+ data: 'Pc18C1A9NwNlecbOtOOAEymNZD5oq20ZvPqMfiCyNhkcmaN9sEnifF31epZSjpDw4XM4ex3HFhhITttXlCrossDVYB8z00k6XsFruCkdwFRmBjb2PdrdZFAkGQeS/8xTarYWgiflkfGocGqVm6EUq1gh8QLE173Jzo15LOSuzuSS90BTMvcsqzzRrIEe+9jwF9/ehLyQ5yYxNImFGQQ2jkW0KiZsjyEbQAGry7B1/AiSUBaGYHYzcB3bFgXnzC3ecPwL+ENZ+azpTd143WneuVMUJrWNp3S+9ZRzboRzcYV6Ax3nOLPS7LTc+e9j9s4CrPvc1L6pG23AzNByDWst0JrqhN37yp67EVVrFQfUDWcKgZyyA/M82q1TVScx+I4A+g9ASC+PdQ3+M5+EOtEfClkgYJFqzXqwPKYwBv4CBKxikS2Vt8x40271kjmVYyGQOIRTo1UKn6u07TS5hxdEgEI+WdukG52813USiD8bQFbN0r4VhjFSqKMAJoItjqvafBNBl+OXYQ1p1zRCXP7wHS4/F7mvrK98gSuIsBgfL+/q9rExXaxIZJNSbs1HGAXR1TxYSvyKZvLa',
+ version: '0.3',
+ creationDate: 'Tue May 05 01:28:36 PDT 2009',
+ updateDate: 'Tue May 05 01:28:36 PDT 2009',
+ accessDate: 'Tue May 05 01:28:36 PDT 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'test_test_offline_copy_data_withExtraVersion': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ '9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8': {
+ s: '55a27b18e8fdf1fb5e5bcf859cfa50fcbc69c9a41f04e371606a86411a98f460',
+ v: '983a6c79e7d5d490c3f13645c49760180fca05cc677914bf60fee009ead5a65d',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"75b61c51726a35d1c12ac553947ff9e974d1a29339f87fbeee0d831b59938a53":"0"},"data":"YjlNzXUO9m0EXdi5fUguA6RjR5jc2mwuHkpMsHAheExR2zpoV6OJx8tBTdUGqDBAlbIn6xUx2TT+dzgjic/XubgKNsv6JpTvnfiW6ZMWiebKXVigoZw7L5EvmcHjVLI8aoIhVEj4ADwkh9qHm0Kt1zFGQPwwJfo="},"directLogins":{"index":{},"data":"4W5csD8DxlxeXVRROk7wVbXi"},"preferences":{"data":"/DjOoFcgquxUbW5ye2LrpsKM"},"oneTimePasswords":{"data":"DEqkd74lLAGtG4YKRPniBNBU"},"version":"0.1"}',
+ statistics: 'EkRr9wEXi/WOlZfCXphn9kfx',
+ userDetailsVersion: '0.3',
+ records: {
+ '75b61c51726a35d1c12ac553947ff9e974d1a29339f87fbeee0d831b59938a53': {
+ data: '/gtNfde5l2J9eeg+rlBHZtqO4RDaWNQwaMEluOVowKdUlGAYjo9FU0NwKsA9CM3ST4sTYl0mylP3C/AGybO8/9sTCkEn20wi0slharA61Rk8uB2lNjCICZB4l3ZGvD4AHKucu8YQzxpWop5dTN8f4us5eJ2VjvJPLqUzSKZL4g+6MiKbjQ==',
+ version: '0.3',
+ creationDate: 'Tue May 05 18:47:53 PDT 2009',
+ updateDate: 'Tue May 05 18:48:59 PDT 2009',
+ accessDate: 'Tue May 05 18:48:59 PDT 2009',
+ currentVersion: '2c913151cec0422dfa51c5bccbca6ad09d8e195bff144d2b5f7a2da3bf55c11b',
+ versions: {
+ '0311012a897262b85b60a316f086f0576caa3c11a34779c02ad9e60232c79564': {
+ header: '####',
+ data: 'MZGx+tQAecxJNl6UbWHIM8g416Qa8DfWtGo7f2vLkPBbhsr20xnZ233oPqIGceG5/6WMssQd9c8U81urISK+4Ar8zHGUxTdIYLZaDq33Q0uF5vO7OsaBcjL7m+tX7zB+e/eu0ABbqvt+saMsZKKSdIZv2KNbAg5VTiL7GjWuowM23tWgiUBgX3eO5fnUUQWVkBygk0qy2O45oNfb1XcbsGMCfS4YPF9GB/wGSQKG8keMoy1ZWZh4nG+Pdx2ymIrYKLv8T+i7jtWEbyhvEglb7TadCMBBF0pnkYvG3F29skWooZC92dy5213o+3/uSKi0od5tAbvSYZHjT5hDulUtmjRFGq4ZRERLqvrZs9Sg8G2mjtf8Ta99Hob8WLxyGF9x7s1LcLPERtdsP9qCD+I0WtwrDiodl/sPQ/5s3G2S+M/YejKXBvG3AWwoO1gkdhec3+d3meFNvCr0hKNzotrHmDLC4tGyZIaAcBmPQ8xSD5KmNJJFU+V0QIdiEYKnPjo95oSmKyK1UtIoPrWCahfYSKXh+aW53XnzY4JKHRER9vWwdJzz',
+ version: '0.3',
+ creationDate: 'Tue May 05 18:47:53 PDT 2009',
+ updateDate: 'Tue May 05 18:47:53 PDT 2009',
+ accessDate: 'Tue May 05 18:47:53 PDT 2009'
+ },
+ '214d184d75418af71d18f412bc6bb153fd6435a4a675af6bf2a744ecbd7a53b7': {
+ header: '####',
+ data: 'Y38v4jhKwcsW8LDTigIhtdLJ2zgv+1rSutqyu0AilBQeSTe4D0rnapZZTW/mNnD5IGpWKFoEl8+WGj1zvGzleNdkOa08nWJEYDNe2h0+FjBSHBUAgH5fraezomRWzJ/Z5HHFiZuFfpjt2BHd0Y3Not6AuL3aBgjjkEai90r2o59Xr70maUwo1UqmtVg3gvX067MC3hlqhNIp390J8LFiSj8Z4US9x/WzVR5Xx069+0PFMBwipq9WJPrcfTPwvP6xVa+J8BCJk3HtboRutq1ZhhHpibm+TY3Xl3gFTTCHWDZCSJ4Rm1dWkyqpx51u/AVg2TC+ljFLKv7hq3euVZNMLNMY2BqoCkcb+w6dFLDs3WfPAW0aQN2P++GFa/eVpN90YxAeXufjsXKaArTMjGWKiHqyU1iVVI8N1QEiFYjjBV1GvkJxog5PjtAzJF++qwHDIa+gJ+NnOfenVF0wIRMCEnpGyvbg3SkUoenKFoHO0IcSP2CW2RWV/GAmiEZEuVD393mKi5B6fpjdO9JVPNyz0i0kW++dtzInwPnglhOAY1ywT0ExOBLIEr8=',
+ version: '0.3',
+ previousVersion: '0311012a897262b85b60a316f086f0576caa3c11a34779c02ad9e60232c79564',
+ previousVersionKey: 'f45/Sx3jMC8CgdT8cjfcC4ApA8xMXABFO48jiTh5VjJfTlVqw3NnHRO2KDBIhy0znPvP2AKlpKQHruW8LQno7YLyhEIXh4ChjMUjJsFFwB/LUg==',
+ creationDate: 'Tue May 05 18:48:11 PDT 2009',
+ updateDate: 'Tue May 05 18:48:11 PDT 2009',
+ accessDate: 'Tue May 05 18:48:11 PDT 2009'
+ },
+ '2c913151cec0422dfa51c5bccbca6ad09d8e195bff144d2b5f7a2da3bf55c11b': {
+ header: '####',
+ data: 'tkiW41JHOfbYOt2KHx1HtDJEzxbfVS1Y2HJQqdQZ73zhvxnkWLw/X6FMiBexLeoKXO1H9NIWS884MzEO782vg8QRxTizg66Yye+q1Hox+QsaEoaD4UQ54XV1duTOB/XS5P0P9DFvtIz9msEu8GJrvizAdxu/7FG2b5XfENDkwqIzydI7JMfGC0JzDnfGvYkWqoL8jx3Joxa7TNqN4he4v771Ho1ZoUv3Pp7ZGwBU+btl6Q9mcycSf5KXdTw+6nDjfQh8qyts/u7O5xPFh2Yn8zS48x95I4SA4yFKtERU3pLAxIkcZWVb17xT8xlbPESreZ0RyYSR0CgW0wPMxkLHH1uqWycTa7yIxUhyn+JK9jCl4eDa/KUSGbN1yb6pOyjGuev1vHEZv3bOmO52RVVIdMHTe3LezCKY8xpDqtQKSfAvFg1TmabugXePXB+KvPbDDWI5otDEIwLYhDFcSn2FyqUEATSzeU2o1uXO+ffbU3QBrwr27tsreughWSP7905FQbEEshsRUc2Xt92WhTnVM6W74Y0bMLWjTrXbu+hNsjtFYYN6gtezcltnB58MVw==',
+ version: '0.3',
+ previousVersion: '214d184d75418af71d18f412bc6bb153fd6435a4a675af6bf2a744ecbd7a53b7',
+ previousVersionKey: 'XtJ8Ub99GXIkxErIPr0HaIrRqlAO0Naa/tPwUA51K2D5R6R3CR6QbHd3GpkCnu+y+bcEIRYrQqgabi3LROYT+1SZ9B9FctX6FyaTjYEazFdCvg==',
+ creationDate: 'Tue May 05 18:48:59 PDT 2009',
+ updateDate: 'Tue May 05 18:48:59 PDT 2009',
+ accessDate: 'Tue May 05 18:48:59 PDT 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': ""
+}
diff --git a/frontend/gamma/tests/tests/Components/GridLayout/index.html b/frontend/gamma/tests/tests/Components/GridLayout/index.html
new file mode 100644
index 0000000..0208a82
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/GridLayout/index.html
@@ -0,0 +1,135 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Card Dialog EDITING - test</title>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/DOM.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Style.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Visual.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Set.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Toll.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings/Strings_defaults.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
+ <!-- script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Field.js'></script -->
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.Preferences.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.OneTimePasswords.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/BaseComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ComponentSlot.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ProgressBar.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TabPanelComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/Tooltip.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TranslatorWidget.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogRecordDirectLoginComponent.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/ProgressBarController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/TabPanelController.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/ColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/FaviconColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/LinkColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/DirectLoginsColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/DateColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/DeleteObjectColumnManager.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/GridComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/BookmarkletComponent.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/FilterController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/GridController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/CardsController.js'></script>
+
+ <script type='text/javascript' src='./User.data.js'></script>
+ <script type='text/javascript' src='./TestPageComponent.js'></script>
+ <script type='text/javascript' src='./GridLayout_test.js'></script>
+<script>
+ Clipperz_IEisBroken = false;
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+</script><![endif]-->
+
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/clipperz.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/compact.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/ytheme-clipperz.css" />
+
+ <link rel="stylesheet" type="text/css" href="./test.css" />
+
+</head>
+<body>
+
+<div id="component"></div>
+
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Components/GridLayout/test.css b/frontend/gamma/tests/tests/Components/GridLayout/test.css
new file mode 100644
index 0000000..21abd07
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/GridLayout/test.css
@@ -0,0 +1,43 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+ul.testTabs {
+ list-style-type: none;
+ padding: 0px;
+ padding-bottom: 30px;
+}
+
+ul.testTabs li {
+ display: inline-table;
+ padding: 0px 10px;
+}
+
+ul.testPanels {
+ list-style-type: none;
+ padding: 0px;
+} \ No newline at end of file
diff --git a/frontend/gamma/tests/tests/Components/ProgressBar/index.html b/frontend/gamma/tests/tests/Components/ProgressBar/index.html
new file mode 100644
index 0000000..d72aae0
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/ProgressBar/index.html
@@ -0,0 +1,120 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>ProgressBar - test</title>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/DOM.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Style.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Visual.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Set.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Toll.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
+ <!-- script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Field.js'></script -->
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/BaseComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ComponentSlot.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ProgressBar.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TabPanelComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/Tooltip.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TranslatorWidget.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/ProgressBarController.js'></script>
+
+ <script type='text/javascript' src='./progressBar_test.js'></script>
+<script>
+ Clipperz_IEisBroken = false;
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+</script><![endif]-->
+
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/clipperz.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/compact.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/ytheme-clipperz.css" />
+
+</head>
+<body>
+
+<table border="0" cellpadding="50"><tr><td>
+ <div id="progressBar_5"></div><hr>
+ <div id="progressBar_10"></div><hr>
+ <div id="progressBar_15"></div><hr>
+ <div id="progressBar_20"></div><hr>
+ <div id="progressBar_50"></div><hr>
+</td><td>
+ <div id="progressBar_80"></div><hr>
+ <div id="progressBar_85"></div><hr>
+ <div id="progressBar_90"></div><hr>
+ <div id="progressBar_95"></div><hr>
+ <div id="progressBar_100"></div><hr>
+</td></tr>></table>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Components/ProgressBar/progressBar_test.js b/frontend/gamma/tests/tests/Components/ProgressBar/progressBar_test.js
new file mode 100644
index 0000000..822081a
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/ProgressBar/progressBar_test.js
@@ -0,0 +1,125 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.Tests.ProgressBar');
+
+Clipperz.PM.Strings.Languages.initSetup();
+
+Clipperz.Tests.ProgressBar.Tester = function(args) {
+ args = args || {};
+
+ Clipperz.Tests.ProgressBar.Tester.superclass.constructor.call(this, args);
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.Tests.ProgressBar.Tester, Object, {
+
+ 'toString': function() {
+ return "Clipperz.Tests.ProgressBar.Tester";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'run': function () {
+ var progressBar;
+/*
+<div id="progressBar_5"></div><hr>
+<div id="progressBar_10"></div><hr>
+<div id="progressBar_15"></div><hr>
+<div id="progressBar_20"></div><hr>
+<div id="progressBar_50"></div><hr>
+<div id="progressBar_80"></div><hr>
+<div id="progressBar_85"></div><hr>
+<div id="progressBar_90"></div><hr>
+<div id="progressBar_95"></div><hr>
+<div id="progressBar_100"></div><hr>
+*/
+
+ progressBar = new Clipperz.PM.UI.Common.Components.ProgressBar({'element':MochiKit.DOM.getElement('progressBar_5')});
+ progressBar.updateProgressHandler('5');
+
+ progressBar = new Clipperz.PM.UI.Common.Components.ProgressBar({'element':MochiKit.DOM.getElement('progressBar_10')});
+ progressBar.updateProgressHandler('10');
+
+ progressBar = new Clipperz.PM.UI.Common.Components.ProgressBar({'element':MochiKit.DOM.getElement('progressBar_15')});
+ progressBar.updateProgressHandler('15');
+
+ progressBar = new Clipperz.PM.UI.Common.Components.ProgressBar({'element':MochiKit.DOM.getElement('progressBar_20')});
+ progressBar.updateProgressHandler('20');
+
+ progressBar = new Clipperz.PM.UI.Common.Components.ProgressBar({'element':MochiKit.DOM.getElement('progressBar_50')});
+ progressBar.updateProgressHandler('50');
+
+ progressBar = new Clipperz.PM.UI.Common.Components.ProgressBar({'element':MochiKit.DOM.getElement('progressBar_80')});
+ progressBar.updateProgressHandler('80');
+
+ progressBar = new Clipperz.PM.UI.Common.Components.ProgressBar({'element':MochiKit.DOM.getElement('progressBar_85')});
+ progressBar.updateProgressHandler('85');
+
+ progressBar = new Clipperz.PM.UI.Common.Components.ProgressBar({'element':MochiKit.DOM.getElement('progressBar_90')});
+ progressBar.updateProgressHandler('90');
+
+ progressBar = new Clipperz.PM.UI.Common.Components.ProgressBar({'element':MochiKit.DOM.getElement('progressBar_95')});
+ progressBar.updateProgressHandler('95');
+
+ progressBar = new Clipperz.PM.UI.Common.Components.ProgressBar({'element':MochiKit.DOM.getElement('progressBar_100')});
+ progressBar.updateProgressHandler('100');
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+init = function () {
+ var tester;
+
+ tester = new Clipperz.Tests.ProgressBar.Tester();
+ tester.run();
+};
+
+MochiKit.DOM.addLoadEvent(init);
diff --git a/frontend/gamma/tests/tests/Components/SimpleMessagePanel/index.html b/frontend/gamma/tests/tests/Components/SimpleMessagePanel/index.html
new file mode 100644
index 0000000..ac1585f
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/SimpleMessagePanel/index.html
@@ -0,0 +1,115 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Simple Message Panel - test</title>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/DOM.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Style.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Visual.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Set.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Toll.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
+ <!-- script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Field.js'></script -->
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/BaseComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/Button.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ComponentSlot.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ProgressBar.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TabPanelComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/Tooltip.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TranslatorWidget.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/TabPanelController.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/CardDialogController.js'></script>
+
+ <script type='text/javascript' src='./simpleMessagePanel_test.js'></script>
+<script>
+ Clipperz_IEisBroken = false;
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+</script><![endif]-->
+
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/clipperz.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/compact.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/ytheme-clipperz.css" />
+
+</head>
+<body>
+
+<div id="tableWrapper"></div>
+
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Components/SimpleMessagePanel/simpleMessagePanel_test.js b/frontend/gamma/tests/tests/Components/SimpleMessagePanel/simpleMessagePanel_test.js
new file mode 100644
index 0000000..85128d6
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/SimpleMessagePanel/simpleMessagePanel_test.js
@@ -0,0 +1,95 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.Tests.SimpleMessagePanel');
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+Clipperz.PM.Strings.Languages.initSetup();
+
+Clipperz.Tests.SimpleMessagePanel.Tester = function(args) {
+ args = args || {};
+
+ Clipperz.Tests.SimpleMessagePanel.Tester.superclass.constructor.call(this, args);
+// this._user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:function () { return 'test';}});
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.Tests.SimpleMessagePanel.Tester, Object, {
+
+ 'toString': function() {
+ return "Clipperz.Tests.SimpleMessagePanel.Tester";
+ },
+
+ //-------------------------------------------------------------------------
+/*
+ 'user': function () {
+ return this._user;
+ },
+*/
+ //-------------------------------------------------------------------------
+
+ 'run': function () {
+ var deferredResult;
+ var confirmationDialog;
+
+ confirmationDialog = new Clipperz.PM.UI.Common.Components.SimpleMessagePanel({
+ title: "Alert",
+ text: "Should lost pending changes? But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness",
+ type: 'ALERT',
+ buttons: [
+ {text:"Cancel", result:'CANCEL', isDefault:true},
+ {text:"Ok", result:'OK'}
+ ]
+ });
+
+ deferredResult = new Clipperz.Async.Deferred("CardDialogComponent.askConfirmationForLoosingPendingChanges", {trace:false});
+ deferredResult.addMethod(confirmationDialog, 'deferredShow', {
+ 'openFromElement': null,
+ 'onOkCloseToElement': null, // this.getElement('cancelButton'),
+ 'onCancelCloseToElement': null
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
+
+init = function () {
+ var tester;
+
+ tester = new Clipperz.Tests.SimpleMessagePanel.Tester();
+ tester.run();
+};
+
+MochiKit.DOM.addLoadEvent(init);
diff --git a/frontend/gamma/tests/tests/Components/Tooltips/index.html b/frontend/gamma/tests/tests/Components/Tooltips/index.html
new file mode 100644
index 0000000..471eca9
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/Tooltips/index.html
@@ -0,0 +1,143 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>TOOLTIPS - test</title>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/DOM.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Style.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Visual.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Set.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Toll.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
+ <!-- script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Field.js'></script -->
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/BaseComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ComponentSlot.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ProgressBar.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TabPanelComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/Tooltip.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TranslatorWidget.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/ProgressBarController.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/TabPanelController.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/CardDialogController.js'></script>
+
+ <script type='text/javascript' src='./tooltips_test.js'></script>
+<script>
+ Clipperz_IEisBroken = false;
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+</script><![endif]-->
+
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/clipperz.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/compact.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/ytheme-clipperz.css" />
+
+<style>
+
+div.leftColumn {
+ float:left;
+}
+
+div.rightColumn {
+ float:left;
+}
+
+div.boxWrapper {
+ padding: 70px 200px;
+}
+
+div.box {
+ width: 100px;
+ height: 30px;
+ border: 1px solid red;
+}
+</style>
+
+</head>
+<body>
+
+<div class="leftColumn">
+ <div class="boxWrapper"><div id="ABOVE" class="box">above</div></div>
+ <div class="boxWrapper"><div id="BELOW" class="box">below</div></div>
+</div>
+<div class="rightColumn">
+ <div class="boxWrapper"><div id="LEFT" class="box">left</div></div>
+ <div class="boxWrapper"><div id="RIGHT" class="box">right</div></div>
+</div>
+
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Components/Tooltips/tooltips_test.js b/frontend/gamma/tests/tests/Components/Tooltips/tooltips_test.js
new file mode 100644
index 0000000..37c0e71
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/Tooltips/tooltips_test.js
@@ -0,0 +1,117 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.Tests.Tooltips');
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+Clipperz.PM.Strings.Languages.initSetup();
+
+Clipperz.Tests.Tooltips.Tester = function(args) {
+ args = args || {};
+
+ Clipperz.Tests.Tooltips.Tester.superclass.constructor.call(this, args);
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.Tests.Tooltips.Tester, Object, {
+
+ 'toString': function() {
+ return "Clipperz.Tests.Tooltips.Tester";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'run': function () {
+ var tooltip;
+
+//Clipperz.log("================== ABOVE ==================");
+ tooltip = new Clipperz.PM.UI.Common.Components.Tooltip({
+ 'element': MochiKit.DOM.getElement('ABOVE'),
+ 'text': "Tooltip displayed above the element",
+ 'position': 'ABOVE'
+ });
+ tooltip.show();
+
+//Clipperz.log("================== BELOW ==================");
+ tooltip = new Clipperz.PM.UI.Common.Components.Tooltip({
+ 'element': MochiKit.DOM.getElement('BELOW'),
+ 'text': "Tooltip displayed below the element",
+ 'position': 'BELOW'
+ });
+ tooltip.show();
+
+//Clipperz.log("================== LEFT ==================");
+ tooltip = new Clipperz.PM.UI.Common.Components.Tooltip({
+ 'element': MochiKit.DOM.getElement('LEFT'),
+ 'text': "Tooltip displayed to the left of the element",
+ 'position': 'LEFT'
+ });
+ tooltip.show();
+
+//Clipperz.log("================== RIGHT ==================");
+ tooltip = new Clipperz.PM.UI.Common.Components.Tooltip({
+ 'element': MochiKit.DOM.getElement('RIGHT'),
+ 'text': "Tooltip displayed to the right the element",
+ 'position': 'RIGHT'
+ });
+ tooltip.show();
+
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+init = function () {
+ var tester;
+
+ tester = new Clipperz.Tests.Tooltips.Tester();
+ tester.run();
+};
+
+MochiKit.DOM.addLoadEvent(init);
diff --git a/frontend/gamma/tests/tests/Components/UnlockPassword/User.data.js b/frontend/gamma/tests/tests/Components/UnlockPassword/User.data.js
new file mode 100644
index 0000000..dac8b45
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/UnlockPassword/User.data.js
@@ -0,0 +1,977 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+testData = {
+
+ //-------------------------------------------------------------------------
+
+ 'simpleLogin_001': {
+ 'users': [
+ {
+ 'username': "joe",
+ 'passphrase': "eoj",
+ 'version': "0.2",
+ 'connectionVersion': "0.2",
+ 'records': {
+ 'record 1': {
+ 'notes': "Some notes here",
+ 'fields': [
+ { 'name': "username", 'value': "joe", 'type': "text" },
+ { 'name': "password", 'value': "1234", 'type': "password" }
+ ],
+ 'directLogins': {
+ "record 1 direct login": {
+ 'configuration': "",
+ 'bindings': [
+ ],
+ 'favicon': "http://www.example.com/favicon.ico"
+ }
+ }
+ }
+ },
+ 'otp': [
+ "12345678 90abcdef 12345678 90abcdef",
+ "fedcba09 87654321 fedcba09 87654321"
+ ]
+ }
+ ]
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'joe_clipperz_offline_copy_data': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ 'f527cdd90d0d47f8524b4e165398ad1455eba515d04abd101d1e93b3c6ae0674': {
+ s: '186f0c40bf73f2af236eaa6c429df225efa933050c9aae65240e93b7b362e3ee',
+ v: 'ac61a6e325ecf329926a86084f591d8852d0ad3e4a6080f2adc901b82395ecaf',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5":"0","13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551":"1","062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80":"2","ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c":"3","507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a":"4","d5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d":"5","de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4":"6","d620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045":"7","f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732":"8","36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113":"9","fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6":"10","6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18":"11","9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291":"12","6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a":"13","6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728":"14","8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39":"15","084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d":"16","7bb69b6366a8012f181c01e368ba18d4f7a82bcabb4959189736ad124c4bbfbb":"17","5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4":"18","c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065":"19"},"data":"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"},"directLogins":{"index":{"61e87fdc4f1d9112e3b30c1f6812d095dcdb24f014c83319091eb6c9899ec348":"0","989593d4c48929f0c8f1581aa96969c622807e99619ed4732026e967530a68ad":"1","9f7979368fa29f66c44bd97ecaf6c545abc800b1c7bb21b7655a68e1514c3906":"2","dba0db679802f0e6aa6d0b7a6aaf42350aabc5f057409edd99a268a92ebb6496":"3","aa18149164302d5dbe7e2d3724565b9550e00887b49978559783b2e38c625584":"4","1f9bfd677b531a03168d3f8bd8afabb5357244a7bc355dff50bd6c0a072114a6":"5","a48e38845713462ecc9f827149eeaae87da882031f98ef8ebbf9ee9537b63468":"6","6f7bbc4e42ea462b5246e6f51c3f86056bec50601ce2de6067c8c1d26f21c07f":"7","2df54059e78f5771f23bd285cce19595b38331b73d67020424d9a1b2257db09c":"8","065cd0c270e5e8ce50e4ea8e3828dccdae18c01ab030813d756a87d03fe68784":"9","ddbc8d01300a4f10631cbde09e1246332eade3a877a2205209f9eb9e5bc9da0b":"10","9b7a30e667afc9f76ba77600658b2c13bff52432d444261d39bf3d069a160afe":"11","9fd2929cde3d32d9cbc5f1d787f2f64729a5e12a14410556b31c0c099762c46a":"12","f695fc36ac56bead80c0d20a88e01e382819c18dc268f1679551b7c83db7cb14":"13","f22dc41ffabef4b3bc8f7af804fec975bd50718098322a673cbe4aaff9464ae1":"14","03251dc1cbc5398789e4c4b45c52cfac3fcd8c1a4f19a81fa68fc6feae31d55c":"15","a7b32e72502804bf2946a2a8856139cbbb759c5777e6b3e673db1fdf7e3bd06e":"16","cb9ae0bba1957075ccdbfd3b3481704d62087687a2ac7c411a4f07d444bde0f7":"17","7e1d069b7fa57c03bd7bf48807520feb953157834503aaff8c9d493f37dea69d":"18","24404059cabc63b2dbff0f42ba57183108b8189ef53ab62fa25141a1caea824b":"19","33cf9758477460a8056deef0295a1ebe65b39b392c361ceb920a83edacfe5d78":"20","e9a16316f330e3d150f6ffd194f6fd8acd1426757b097de4b88ca0db875202e4":"21"},"data":"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"},"preferences":{"data":"EZMrwxNFFd1sMGycoYE7IrlGGrfLixLUnLZmWMkFysfISe2ay3ueO0PGCApuKqh9hA=="},"oneTimePasswords":{"data":"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"},"version":"0.1"}',
+ statistics: 'SfGy/4mpXQdDOv+Bcfie4Yt/',
+ userDetailsVersion: '0.3',
+ records: {
+ '062af892bcfba49ffcff05c56d99b7af2d508358e39c058c2e1fc83531436f80': {
+ data: '7sgxSQlqR+wh3g06M2+sWp7raQxjjQ9jLIz2OcEB7SckuQcXNrhMlDCbL6ncSljtzgqhioWrOB409kIG8lc7h6ekghOE/Mhi7rVwAiRfNGB7r3mYxpEXRe96O2RG7E+NcSp8ezl+5gJ9D0o1abXPeFQYGcr95hUioCfyY+xrxY8TJVwdb9nHkYvBdKV7rCl1dTxgsKWK3nlo1T7e5uyiz5YUAE6BrCtTFAqtprLI/xOpRti9C+llohS7D6s8hkCBPZfp3chKFDrgpsCBFLhXN8jrBKSjHi1PJdRQzpJsgrxyeBj0dZx3gTsYOXqrYgdIzFUo7K1Tqb30yNprBiDMr7j0YYXiSvEb7OuOIP+HTXGN+yt09bk9LggyY6Fh0e+tenjQQ3soySN/XznOBpEjXbzXoz6fR1MXVnE9GgaX99LVNqwWfq2rIBdSE/FfspRiWP3BY5jIrEkNeRclS05U1zw3K3wxOL+cB9r2IynSXnK8QcrDNNRZ0W3PhsSFfByUXuviLSEOPuJa1mYP29L9Lj/WyHL1Gyl8xLbt2H41S6+wvIleKMuc7teH6wPXbnYphvbwBowoI6HZTEFkz3dQKhhY6VF/81iCXsuaz6BjyrzFX6SkQ4S3lN1tv4opQMJFvnmHb6EkXqVWfeIXzJIJO+owL4vDOf4okpAD+HPjjlVXhq6fvyM5UBIK9+tzJW78X/zifrQOfWRIhwjVsfUdZWmZ/S35vnHWNuXkM8GBYrDysqxanDtah3U8XLAiIhFtBOzpzr6qGaNDOKKgG3K8QXT4bYHOq1rQVUwzQuKhlCyStrRMQrC5Ry251xmLy6dKfppRarVeGDtzB/30BbtFNdZmzMNG2g+Jj5tFCrEtCMvMiQEWZHMU3tGMFxDef/KKdv1fFTJC16jmaUiCHUZmNjB3EO9R6xPVcMlAVKf57n3efrpRk/GTmm9JhAFkuF/wsveH4JjPpDUdkHYFu5tHbb30sbga3ufBAXbQL4ck10S24akU/cKraFGLvuKGaR2U0i6ih911TBSf3pAfZ3RFbBhVIl+6rSknC5+IXoBR7MRstBPW/xC9pQVjN5Qyn0g3aUjUSI+q4jcTuvMl32NtTJbWRMGhfkrpVzypZTyPnIh6XJkyBghlUARXw23MlbjiZxmY4ScDmcWZRZJWIknHlqjDKFDKNnwrfnEI9qWyMDno+jA/DEQz0mnpdZYEsoz1/qAmAeDt89vx',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009',
+ currentVersion: '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3',
+ versions: {
+ '4a70ca20167875a936d4540f19980e972c20f329a65d85e9b0ce709f1fc7c7e3': {
+ header: '####',
+ data: 'GCNNIhDQjMJQZGVSf+95fPtU6eOnFWVhuGm86r8WZGVR2Gf2EjbG1OJ0ZIGpZ/AXgirCMpo5AFxJe0Bay8IYg+xmBqMFhwFxzAgJBYCIts+raSaNRipuY8dTEqDxAqD1cChcG8EhSoiFgQ0fG0I7nNEUDJi0pIt4/ygBcwvAhuAenEp9ZW+oQA0+YysPQRqkz3IieFaOoSEbe5/SqpUilV4q1gTVyzNXvrxzxx+rlvEyGFgFN+vgtUZ1NrwlPk4gVksTpylvv6CFaMGEWKhgMG6efo0rJckKosaJTu1pldJdnmMK4EKNMLOd+jZ6pEhEhYyadrA4+zYU5TlmZA6ASzTaps8piSwZodoi9qY0ch2StK4mAbzeEGe2HdfHuAU9Tyq3Ppk3+VfNdKgpQfYrQOiSlXbKzK636tzXTN/gyrfOTHjBrRl117ywibgSX63ayAYNfcLpKotC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:46:44 CET 2007',
+ updateDate: 'Wed Mar 14 15:46:44 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:04 CET 2009'
+ }
+ }
+ },
+ '084e23120544603f0297368fd3891a3818e0fe13488e2f2c6079913c8d1bed8d': {
+ data: 'fGzBu1On7e/6rAoSB1a4fq/CkS8Be/T8UP5cQ93asBTWndSYu2lW4DQ4SXQXSindIi3OnNx/f6SNv/extb7OrMLREF92wXI045ipPwy+DIICb+cQNMJ82Sh4cXaIcAWcyrm+MYri3qq9LBKbpwkILcebZidJ86lmKYHJozUezmfbMcwNCljHs/gYkHVzVcuw9L52Ugc6wC7sjsshh+UH6i4/2Frlrophtx+b1vervNd8eoYiKnedHVXVfW7UJcQoF27eHFgzwYnGvRW0KNXFFhqmPb61TSkIvNdCCvBKDP4SXrWvGgzU89wipvWdUPpQ+fCT6Mp3hPRrbJxwMunmjujZOzBld/HkjnXoiNfBb5akA280WvdyzWYATrjV1ZFx8yQY8G0+lRt/MxjKDc38w4y+Rf5WeRbXboJMvFatwooHUggk6qSRmZVvgOmFmNuDRnRYIFzqK3JclhJeVasnqhR6RiGSowc1Ffr1HhcZCMnXpQABGBkZcHD/zw6YjHRyh9Plw7XAm0xb16HMDtiwt7WLJpxLH/HP99j/A2hvMGWiUiFCaYv7AzyEPTmYbN32D1IsAEE/GC3FG0HypGTBolP8wpAfTRdlvWpJz8oRRdwuLV3Pgpu+kXh5sQyeZI6tnuMPQFmRDcMN1oo3E5V5V585nVMnKTFcXhBzD4UnoV+DQNkG/+iSPybQzz/EZmucEqGEYyjI3kl4MAX8UMEUxE4JO0fF8MzyBI13nxknowAceEammx1dGVaJCoIOdhadaPVPyOzXM1Vp1erVm5k4TsxSx1pll+GOm6hVoNHIuQLDueaMEpRxMhfwc8cDyXURqRGPTgTc0bint5xVjo10fnpX1gcdc/AWL6y3tXM80NW+uFJ4GI7VzyzfcMRzTiRaGi19z8MIx8PbIVGh2sw4FhgGujNsPrpuESvUVT+17M0+v8oEoABNlcizTMFs/sA1uqlPumFASltzmViAzClOsDuCh069hFLjdk/Ex5jy4vPYlwOT8Uq9DJC9ZWuZgiI1DrhWN/8QGAEGxxbvnSZPNCQ9kpD5p+iabinLLWOAirVNgKwIRJRyAu/uR9xKd7J9Wxq8q/ii+y5lGilbo2g24wbDwrkXYVhqp/4J0g+p8Wv1NBjCTSCqV39WEizUCRHo3ee9HnQnBJQDOyTBRuz2odTJtJ5tLYjWXZRdFzFSJrEq+Z1z3oq7LnhZy3YWaFXPeKmBCemMthtNt0nL',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ updateDate: 'Mon Oct 27 08:58:49 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:39 CET 2009',
+ currentVersion: '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac',
+ versions: {
+ '0ae362285f103722abbd046eee2b7d10aeae6a1d05cbaf2081392ce9df882bcf': {
+ header: '####',
+ data: 'sG6TUmPSEPFpiJ5YdtghWHmHbvUK63tZCZ+Q5iz2ALas//jN+lZCBhZcjEwPEJskBkK2R0MyAh14wWGh2bBHMjsokgTe+L+x+0c/Zi0epE/IC9gtOBhsTe/hZ2e2xOGF/SbzET3DAAYXvxduZ36f7SvvFnrkkKvpj8wGSdTFcBmzqMb9DL2bRyRCLGLMzE3F1a0q5CufCIRz2TgHm+Uw+kfvvwC7ig/F/5iLW90Ypz3vmEtMEFYFHZ9a8Oh0rsXGfevbMhFqALoywzihQEe/NiB8dwn7GEdYKSQ35rhvZh29ULWOZinqmg0ONe0HYaxx7DbKsVoue57S0CIUlgHLajzHfLfqQg2sFI0OT8TnHsGg0YZ6mM2EdKmEjJiER0cP',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:00:31 CEST 2008',
+ updateDate: 'Fri Oct 17 17:00:31 CEST 2008',
+ accessDate: 'Fri Oct 17 17:00:31 CEST 2008'
+ },
+ '10f45664bbd979a92f37886f1ecc6e52e49798b16dc997aecd37259ad9b2090e': {
+ header: '####',
+ data: 'RdKVaV/WWWchrCse3KtcXd47Bfm6IAwjqVUpaxoed3HeunI42AAm7xYYSjeK8edHpbNRJbhobBAX5OZtWIp/HmgkobKM8CIiWxrWz89FqyrbnPD7+fXdtgF2yTax/0sC1l0ibncdOuJKX6U829oPlXCpXIOjlomc4wEEAD/5V6FbORvdZ9IE/ME3LsG2y02cT2tIpx6+R6wC/PKXhZA2UDsTE6R2Op2BtIzpVORZLXsdyAp/4wvWQxq90i9cEpbsVQsMB10JVyNHNsRTFhIlHi9MVCaMxQvcrwRElMj/Y9x3RbsFzSGKqFLqdg7Fn/U+KYkpYtsgHv9hraPIb9lV5FH16+iItU/HBM6FGezIj1ZkoQ+dgjPfSjTZzgzDYwyb',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ updateDate: 'Fri Oct 17 16:49:20 CEST 2008',
+ accessDate: 'Fri Oct 17 16:54:23 CEST 2008'
+ },
+ '2fa7b67e569d5e268d2b70b3d4d3a960d7e437e1937bcb324b67d0b9441db8ba': {
+ header: '####',
+ data: 'dpnI2qKjk0+bfyKktw4ZCWf+rWZ12hO5bda39CwD29JH7KtdpLCLe2LoLd+KKF2wOdpDsoI2iTiwRgFpt77e7DoWJABxq/0aaRCVN9XpqZo08iHiYhJyNlIszO8CdEhX+M3AeZqzTnd6fs91VfIEWggvku2Z+jwr0CbclY6FnOcNnS+1fj+W79Z9XC383GOm2ujjfo3SX/fyNQSw8aX+7AgJIRGR9uHK7M1cVfsNNTbmDb/HDgLlYZ1Pqm/9poHpmS7G4HUoRM2/WjI0R6F48dy5s8vZRi11SCnlnj5oRykScJj6wh2DltbCyesiaTpAjP6MQjTXsZzKpaosaQcQClZw+w6hDD2cA54IaBIv2j5KAHyhxDh2ERdwbdnCsDKPz4+zP+fmKfW295d4OY0l1NCSdcY+75HWTmBWRAooZeDTo7AE8m5sRwxewE0Y8J2MLUYsrs7Rl4kbZCiRRHU7cs+us3fq2DVn2OLGEbkRrK3kA9swT9W8ABqINoA79+DmDaIr6TGxe5AlHkCAl5sYAN4g42UX1NKhl4fWI1Scj9O1Ixds/1UUvqzavld0mE2cR9yt6LntjE5sQSAaexvymAJbU5IIM5NTk7NlY7G3PEvAPjcUsL9SGw==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:00:13 CEST 2008',
+ updateDate: 'Fri Oct 17 17:00:13 CEST 2008',
+ accessDate: 'Fri Oct 17 17:00:13 CEST 2008'
+ },
+ '5a17723c34226d8cd663f91b11bfa14979e694e461818113ec8abf7194b46b6b': {
+ header: '####',
+ data: 'yRTvhkoY9zDRBwFYf0G5U8zhfS1XWIUfwes6ADNnFyOrHOr7JZvZZHSgkOPnsmN/f5ngcvFaIV9X3TNTmmPLzD/ewgGVMR+ofMLyOIMGhxUDzosSd1+HKqwDZWneZ6xNsci87W8UCfJgoEGrkAtAwktqyS04pcAas74XiRGBWNcv5mHZONwGPckYUnnaVG02Zf+qif6Pp7ugdvXrgncO5oi2AMSoR8GQxMP+tX53YzLwOpabA32PDT6o+aDPwMstJNQjWCXjeYLDIlb0GjL2zgjglX5CfdGw8vNT5hwGEK2D1FkvHkw79m++9sOWd5w9WdGgtS4mrTZP3JHWC1sPqvsIpq6PsrzRrbfCFH7C4X/ya5ciOIZTCNl4dEGAif94zgN74ueY5BF31PNFtaRaQ1waKkbsrU63MrbQbBar9b0hDZoser3BdgDGb1Ecc2GbJM1HbDITttmFDrzy/Ugh2kistHx7Dci8IGgfT7K94TntRFc5R6suEqYRrmOn57YJTZYrwSgbeTqAt/KOE+gL9LawiLJ0IdSC2RQnO3yu/aOEThHxpdLIKiVJoiEQXYVnq2UpnO79GNtplNnUe1hETQ/JT0o5X1bbENyInUsFjPuitAfChXofkAysIhDOHAdifc0Y+pxOHbQLkL65ZOsEDXWSlwMcduMNdQm4LVx26GLIV6yVsaDN+hGta2CxUuSvEIMM6T5xhaPfJ4K57LVw9MbOjRXpmFQz3QgEr8ZZdUxgE+Kj6CtmsjvzXtCQ3Bv/SccTLJSR/LQ8XRdIcPoOlDDy5jSQDF/8lxkgV1V7M3+SI1iWESPT8My5C+RH32F2MNZzthYq5hIFUB3wsM/AaQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:59:31 CEST 2008',
+ updateDate: 'Fri Oct 17 16:59:31 CEST 2008',
+ accessDate: 'Fri Oct 17 16:59:31 CEST 2008'
+ },
+ '6fd60c5709a4808444f43f7bbd872363d76703957f613076538ba2f9161206ac': {
+ header: '####',
+ data: 'RgIWPbNN3sPkIPBE6lfvf9/EoDFLemTZe0Qh/1wZLrKxLRNzFpUk9+NmeGUp5f1hM3XjXw4cXRvP6GrWq69mz9zGja+1TA6RoW3dFMpSQkbONcrSD1mIjxV2zIvzA/Pangz0ZixbEeHCfwXLvgnevbTXXFjkti3kLHQlk2pJpM3zMl+rMJtcsefszuJ/0tE/bO7sBcFqcYgKAht2OyDQORBAGiW1kI9USKM5OOfJJIZDQ0gDhRgl2U92l3kIOO8hdnj32oRedwfKFmdSRkuMY7ykU0bMuVEVkLi/FWmhHxi66C2ovAztVtMd1IiyoNcHc4UH942GC4pT1A8YQpIHxBAJbrQVhpl9LfFkmJ7xUc6Xs5j0Nv8+z2JGCnJI/D4nDJqYW+iCYtRWu6vUmbg0vGfaYWQFGRZRk8zWfHzHXBvHU8p0QsIjYgCLKiUaU2SRRD2P7JCjeTUrm3I1OI593iPsEH9J2PHCM9OMQ8/Fsdgd7lWgH6P9jLdGUwtb1hGaq8mg3JGrHFXcrVkUEBfeR7xljeSHD7j4YahYrua9EeR8nvq6CNaOr406AWyHse9SXhaOxt8qXRLoELpyQPsaLgafUpsdLjJqHz7J76Rp77NSOtXGplKjAtU1xj+d/agaAKYCjvUJC8/APJI2890Pn7VSXr/TPc5biPEIopyVYEHFqaT4e5nZW1Ku1HXC9gwUwUI9rITG4GzIH1WMEm7oFLNUaSMrdK/UTdTJZ66ENE3B9v9cTUpR0NTkbI+iGKDnc8GHPRlr2ZJwN4KFTxi+o/kkEOBjvRHR55nRh2+dke75LS/fzHQZw5wlyqBv5ZeUZfRA7QHfkj9acR0fJSqqNX25AUzZQnRL3oVpOxFWCMU7QVf5VpnRm9OIOd/5F5EoY7Be4doM/UV9U40F3E6XPZQ8S0GKQzrDjc7jKyGPLNPLUWTmGB39mTNDHZQHh5Xv5Q==',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 08:58:49 CET 2008',
+ updateDate: 'Mon Oct 27 08:58:49 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:39 CET 2009'
+ },
+ 'b57a2d2ffafa8029123362071c09709bb9192f06a17140440f0e41d22143148f': {
+ header: '####',
+ data: 'PQ53T2Vo2D8PoLI1qNX//jLaVZFTDTYk6geT9+4RoThTxvlJ+beDPnQzgYhd9iASaF9GQEEL8JxsBnNpEPa6JPOY4ndFLmDLyFDKXMprxq1UIbzFV6kFoYAk3uCCCa3UCDzdr1KXB2CiiF9HrilaA+xkm8krAvH8I5kZD+j23gByz5cAFvXg7A77KEURpjujURL65DW5M+ceIjo6OXaPW9VO03xhqGt/M47ayObpoEGJZn+X9C8s0SE5wOXHbn38YZlRI480OMvtDAxbEYUeQKMmzu6lO4Nw5hhOUjoPSLr/i3tmDx3nPcDwnSafx6jyA4y31eW6yazqTEOP5I5ArC5mUrF7mAAiFvbHIsMoF8PLj6MONlRIOZgbf9HzCpFdt8xBrX/TXp3LaSAj2XTWgSTFI2cgmU3qqPyibvIfUsB5cVHQCXi692JpC+B85axJ0FLyMl5w3vq0txlPkf6q+dadPYDaLHGZEmDjkWScA1GM5xPJHWFwqGE7ejgXKG0sMYsMKWYk+F2LEUmMHtEvSlpgJBntvcQ1ZjYQxeu4hg5txu1ykkif6fXgkXF6wn6qu+5caeJeNhWtAB4q7WVD47111woYMdkmX7AnDTXSAQ==',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:57:17 CEST 2008',
+ updateDate: 'Fri Oct 17 16:57:17 CEST 2008',
+ accessDate: 'Fri Oct 17 16:57:17 CEST 2008'
+ },
+ 'b713e0a1e2664ac7bfa7ba887329ea023204d10298973e322983b82b222debf6': {
+ header: '####',
+ data: 'H3gIieYrH7Oy8LEWCZpl9vGp9qYdHNCoBNGijYqlcfXt+1JYvPj1abPp12xLNrDUHfaOZklU2Ip4tOf0CDNhgAan7LYyPqFoy9ss2f9/5RLcbjwiIwSduySIL322HTAwqlzlBt/qaJdHHPUrczmu0fb7fT+0dO4gCL/e/IjcHLefUUgNPAbpHG0Nv0+4lNwKZkIQM3tLRtfJyFBIgWKcMcP1XMic33kr24rwybR8Pb0CHZrOOvvUiGqyoED3ZTZf1twUDVNXO7MWCAC5dBc6/Mk/vSmbbGhppXAH02N0g8G5qzZfp3UVikls55VNhRYLHByVsgpkbIrKXyZnBPTwzm7qefpYAXDOgO+164L66/Art2FYGqZQRZLuh5r8oF38',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 16:58:00 CEST 2008',
+ updateDate: 'Fri Oct 17 16:58:00 CEST 2008',
+ accessDate: 'Fri Oct 17 16:58:00 CEST 2008'
+ },
+ 'c4cea1cd88a86b05f48a99896a37967c3456228283a0406331ca9f67c6f29f97': {
+ header: '####',
+ data: '1znWPwc9JwCe7iOFiUd2iGm4xJd+824B4VRqEtzCQkW46tg25RWfo7XagvK46USB7t6pC8WMLU0M/EC47KucsfpWUqHGbseoXT/8g8E8GoLnIsk9qFyJG7LGd1sUvqBgszLZwjWWG3t9zifmpW5nY9GialBYNmeSLS3bg5xDH+eCEilUUfDe7zGuVSuu/XkHacv/DYUst97e+6u44F7H8Kv8dTywJZpqbmveNPeWfCej2aBXdVV616J5lIRaj2uIYuQYG7blYJh9KZ7yLStdPndl6h65hIJpfWo0PM8nLJuo0lWNHz7misrutnmxJEjkwVIZ5YAmqp1Zz3VC8zw4IxkXrC/sPmp4PaNXgKz9ZJRaY2KV69WmHf7BUQ3QneGngbT0tN526SS5qDFwTGiuIlnYGWvTB2jVrbns68n/d8Fps8sSWfJBvvXJUEkaZB+1WqNilOPGXvyJ5k2O/iucFbRlxwlEHDny+AgsbtXZdp8cHQ4C/O4G0mnUMZuS38gn6e2kQ55mUhxKeORM+J6Rx1y4Iiu9KKNbxyS5eBpAlFB4xS/o35CS4g309vyOEhi37F24bpp4pM0xEPG4mcc/IyChHzaHUGEp1IX1ZO/r3ut9RIN2QWrGLUlZV/9rFKpLLAy6BkY/g8VYNrV8PztOL3rqy/qwqNZouONwPw8w8SA=',
+ version: '0.3',
+ creationDate: 'Fri Oct 17 17:01:59 CEST 2008',
+ updateDate: 'Fri Oct 17 17:01:59 CEST 2008',
+ accessDate: 'Mon Oct 27 08:57:58 CET 2008'
+ }
+ }
+ },
+ '13a5e52976337ab210903cd04872588e1b21fb72bc183e91aa25c494b8138551': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:53:11 CET 2007',
+ updateDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:25 CET 2009',
+ currentVersion: '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854',
+ versions: {
+ '106a1116d22c2395906a346da4d830c7afbd2da9a46210d0b7a11de238016783': {
+ header: '####',
+ data: 'jgDUvByveAFnchBQKhiHGYDNDtj/7Aja2RePMer0FCOkkEu5GRAiLkxA3/DD3eiU+g+mCxnjnOaEIYL1O5o0+JP08XapsblZHTRKfveeFfs6sWwuqEHGYULBaXx4XSfK2B12HgpBwa5aD49489AkuyXi7t/aAXcKKJcLB1sC61DI3NsmajUaXHBi31Sp7nKAUpMuiWyguW0JVfH6KUPqyldVDBTBqHAis37c1qoR6aFHFfGgAfb35+syfmPRgemujMRkj2XO6dbt9zAYlHVSYFp9393rwPZoyBfXMMdDtSTmq7H9qbmx31GecHZlFN3NymtPPDYUbQ9mpPVRbxE9NjtiPrI5eGFvb++OdOx75PKjYjCAPWWFZ+4aryNn+h+yqab7pAuoG03ACVVrAFIOn09g1ssol/vqvalulEf3hAIviedyiNAC9D0UDHtzUwyIiELvR9qouXLZ',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:13:41 CEST 2007',
+ updateDate: 'Tue Apr 17 19:13:41 CEST 2007',
+ accessDate: 'Tue Apr 17 19:13:41 CEST 2007'
+ },
+ '111a8a4b6b912b808a93cf5e8785ca223112628d05f0bfc5dfe1eb40cb72ed8a': {
+ header: '####',
+ data: 't524etHmXljCnLC+IM+WPD8Q5VE7wDsSHVNZzFU4hQzk119t/N/vhtfHYz5HgNstU5T8c7h7RHKvFk5f+4ZwgNgDqSH7H2PrH+7/bV8+uuqbe+/3GYOvELjTF7v3xMyYs1B7ruHpT+291HVNZqxajqCl/+9nbG0e5feqNsTXWUTdLzF0szJuCTNr2I+fhxAO0LRVaf8h+MBPYyuBDnfFDuKm899IsgF9YoYRvjaYO69DkElvf4VP2jrXIJsRnGIUfUaIS/wQ54+X4JBZM/9M09MVOw1SVe+cwG+P3xyPUkqnSb77ECo86C0MktzeYFmPnPv2SM2KFA6slctXsyudoaNlReh1k+6no5J5BjaawTfqYjYrAtWSPsuhxYVsZym/X2CVbkz4rMSn+J5Uio9N5uZ6AqgCKdhAJlwzVb3fIIJwvFpVpy/0LMskb7aG2i4eAxwzx1H6rD3Y',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:53:11 CET 2007',
+ updateDate: 'Wed Mar 14 14:53:11 CET 2007',
+ accessDate: 'Wed Mar 14 15:24:35 CET 2007'
+ },
+ '144d6eff3eb5f1cb70c8906741d88018cdeeae3a618ac4066598ad6b04242364': {
+ header: '####',
+ data: 'NPgSZF0eSOzy0/Ns+15Nz4bjSwh4o7fWYgKgwXLRFrF8y3EdbiOH7AiEmmPrCpT1raeYLWCcDIrRTz+/9uvIrz6kK6BjU2emr8YdyLai+PTCRY0SafWS3QiYixX6DJiKIt0SC2F6dfmSHwNsbfTHilFhVXn6wXTJpWvC+sRzw+h42cYpQp0BoLSuFV7vPz/+wtuQdl28BiBgLzGsrtPud0tPcfldGox6Ia/1SrOPcqUr0tnFlNQiUvPU7N0JZgRNyr1PfpAEhmYRI7aEJidsZ36vGQpE0ZQMmQE/9tLS/InALRZT1YXfMsytf0o3y4QlgJrvRgBL7fGiQOZJpU7igLk15xAwU+OLIaYIbr2xlKDJvndHOcrFoYKry9/A/aZSnEYv79wsaf64bBgIVD2WJGLuSFFmzlFnbg/O4kGTin3A8XBpvFA9V6iCMvnEMkrqxD3Qgf7WhxFE1A==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:33:00 CET 2007',
+ updateDate: 'Wed Mar 14 15:33:00 CET 2007',
+ accessDate: 'Tue Apr 17 19:12:56 CEST 2007'
+ },
+ '1f1bdb7a21440ac20c6d913d676aa30dc360252d27059e77df51a1be36b2e263': {
+ header: '####',
+ data: 'TaOHH6IoHPKLLoyLyvsBszgsPPcDs6CiLVXzXuXjFSTrhPxzUw9suSsisgDRRs0ncjZ6BCyqoCxMnw6QVvGN4viUwYVR8AWdCg0NMQZ+LkNfq/2WN0M3KyASI8sIdMCwTb57NzOn9soB1HmmmETZfjr7HpY2cc+lS5/4f5rxI8XTEK60lLed+aEuJamAjeZUdgIyu30mMKKjxPfY3Y9iWMwn1OD0zF0mAW+hyEoMhhK7EYlWKCy+4qN0QM+yNFXQyERb04o2n4XrM+qr9df1GtbQMH8igK5VzXIrKjdHjKoLo9G7D7mfx6mRLsmoAJuE0R8gyzotgdBpOgWasHJ82iWEa1dLRKBHJ1d0Lnumv22tvYfasx2DIR5Tmx3kIQ3hFieLSXq48cYMiaZH/IbLiapIOlMgtWDow8JuySBLei/8FAV8jCxSc1Ui/SjbuK/kCvywaSOhDVIxGw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:26:35 CET 2007',
+ updateDate: 'Wed Mar 14 15:26:35 CET 2007',
+ accessDate: 'Wed Mar 14 15:26:35 CET 2007'
+ },
+ '70720f026f37b571e9765d27c51d3d60c7be0293c3266f1f987c8de9c6b5c416': {
+ header: '####',
+ data: 'NYaYljcgfzrlN1DVgrbyj4AeVhXGjXPho3IQwEKD3ZOx/yEZxldCNSyFsrk7PoRB8Q1T/6VV4CGa4HLRSB7QVCrtVqWyu4KbbmFoX8NIQ0H3xv+TSo3S/b3dldUeyW32ScaGbspaf8nFf0CffsgpGusd+kHdiE3gSLJvH9y5j47KgpyyX4TteVzqgez4dcXIs5tdzJq2eUlknwU4651QeKIuRSmRaDRhhOP4yRgUo/qXMlTJFmHviCh+IumvBdmDoPe3Vc1vZ1r8PxpDJLvDoB8GTDE42NhqHfVrew9ym1xlTD9wswwIEikfOyTq3JM857qPOHRqSqthEvr4WHbm1VW5PReIyse0lugGyOzqtCnADp9NvNI440VjaTd4NBQqF7XrRm56+1u1uTdfYGFV5BRiH1KmrM1sxXQ6PlOF9Lou45ALo20xxvJOLKG0RKLMr8gmVT2bNtOSJw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:30:09 CET 2007',
+ updateDate: 'Wed Mar 14 15:30:09 CET 2007',
+ accessDate: 'Wed Mar 14 15:30:09 CET 2007'
+ },
+ '88943d709c3ea2442d4f58eaaec6409276037e5a37e0a6d167b9dad9e947e854': {
+ header: '####',
+ data: 'xI3WXddQLFtLVzxJaZWQaw8wAgSuXLjLnyoNXnFuLecTH0BzU36PatglVh2HK3LM8aDLzzbHILdlLNnJ9CY+YnhmGh8hswF9oKTgq0Wsesgdc20QhSMNFFjmMljY1LSXmcAYK04Q5mIzi6Pe/04DRdj+e4zbe5QI4vEBhp/ohEpxZnNqc4BoX6J0eVf6LA1pwrKWvxzMxorWsJrrr+mn3svdlF437n+MMr89k5sQJogufes2GZ9tTvVZ4247ITxXqxgAhwXtbuIs/A5UqqnNdsxlHfpLKG5KjxB6F0h7TtFA3gkZCve5UmAibBnoBCFaIVWQyVq+VO9iqDm3DeXsK2pepvgIvpSID8Poy+uwN7T95mivAsHG5p7MtgN9KwQzNW3Iu+BfO9FlPBMngSk8L29So2CIXe6lEsXSGEi5Yrgyo6hZi6IkGCXwIQ7TCEMnlQEGyKnnAVik',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ updateDate: 'Tue Apr 17 19:17:52 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:25 CET 2009'
+ },
+ '9588b523f39cdfc14efa1e15ea7716c2d8eac45d8efd7bfeb19d716f9df72d66': {
+ header: '####',
+ data: 'q6DKkxhgDFs1XkqOYf6dvojPF+yhJbniTLFpSOS+I1sum3EZIJfYxJXyi2Jx3KOVNBMILw1+vrSLe/fh5SSWj8ZBoeppkPPLjyRNdiUyd4IfcRM5OSv2YcTxCubKCH2kIMFAzY/29A6ZGPG+AN8/kxkEHc1fxKaNcj2Cs8qejNR8yK1iKT1Ut9VfEee+Eqy2Ohgdq8wL/xAD5mUzdqHeQl8BY16pXGIYncLxMzR+EJ8E5jJTuGv3O41UbO31lvBSfCt2pfz2MrtsuqNoI8LBHJkcR6t17Bj+rHZUniHlyxSW/1rQJ1NnwpPgUJ1fhfQJZM8Faoif+0bvWFY4xWs/tCCD7oEvf0xM0I3FfcJLbYX8M+wyO08t9BmGdEjnr3VUcuS9qKaJRpdpMP7aQf+vJvioeQDXdOJ6Ceo3BDFc6JdNta1Qc+agGzN2KPbIPrLDL+08hWl61yu3GQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:27:35 CET 2007',
+ updateDate: 'Wed Mar 14 15:27:35 CET 2007',
+ accessDate: 'Wed Mar 14 15:27:35 CET 2007'
+ },
+ 'e5b71df0d4d79a195c7ec3288dd7738069837a7c4da3bccc1ebc05d8e4f19d79': {
+ header: '####',
+ data: '1NvK9Y5r0Q880BfB1W5IqdOR77mmqQU0d1GL1XUeQT75R2EgYE9rK1X1jLygCXboPhxzegEe7TDhUsn5XcHN0LkXcLYz8gD/7+He2HiTFxoHd2oQbI3ceBxDJ7+5kWA6Aiqy42QSCuA+TWIQcDVthSyFU7nNdqNxeBYeXiI4jgwcH3xvm0+pBf1OYLtywjUK1JwntP6o68b1LMQJFinDG+sqRcm25ggaZyxDtoLh1IBdSpmXk0papRnyyTGNgsws78dLxnH0Iqxb7FhqYfgLDIvN3i7+IALI0lF0EuTS0hSPlr/1fTz1/6bVt++wI9GpUsrdafUJJMPerXoCK+gAP8EMneLq4f5487HIkwWh1qON6Hvpg+tB95NOSJpqE72VpVxN4+wTQWyDMhfjqXBuQ1wKvTsD/mUsdinU0Wb/YT/zIWBNZPdqur0rjOC+mrOtSdlYSCH89Jj2',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:15:09 CEST 2007',
+ updateDate: 'Tue Apr 17 19:15:09 CEST 2007',
+ accessDate: 'Tue Apr 17 19:17:01 CEST 2007'
+ }
+ }
+ },
+ '36ec1a41118813ced3553534fa2607d781cba687768db305beed368a8e06e113': {
+ data: '6fhueIibbxKRA7Mtb9TPcWiUKajnikM3D7PbOROBkE39Vw9E/nG8KrtJlwwPQeOGCFhssO/KX3ymYehCR8rfaEL1f9pfdh5x69mSxKRlOmtEknWqUgPzcb1yPenRbQagERadh0LF4zu91M4WjXK9qynEHoxI/pBhwQb1IsnhwtXl4ELtajudv+2Hv3p75v4XOXFsGQMsHPY+Zw7dkFFA8EXhvuxjiGvnxCUkFwNICFRdHTEovkW3VSerLdrYo5lDgjY6ebr/g7wDGuu4RLfUK4+HpzFwZ0+aOrjpFq2ePg2xObvkkMNNjZ2PcR6Cue0sf+aNqzIHIlFPpY2Hmrob8+bwxocKA6aagBu7z5GiUmZNXGE/Vtr/WWBV2+xIJyzXZPet0MLmSnGiALjPJveeKnnFdDtA929ydcAb8efc0/snfU/uDoXDiO5SWEQ8DDNjj1bSo7VPTtvZyFormE1KjqimqSwaUJzbIS4CxPnoDezaBtQmlG4z8mc8jXq1HfPu7s9PUzcbG30gbF0ch2pDj4h47AhE0ZoeiV+VYZTaYateSifQXKBQKjPcuh9PQyDI0HVua3itbbwxXpRubEM4fbvlcd+7gu+Zq03slYICD07fP0I6XGrRHVTfYpDbEb4GJBvRIeZLwRTQzOeFbPLpBU9Lv3zXxfHfcHy9oK+giIxefPdY1ZR2ZFPKOO0xYJsTr0vmTuXeXzy56bKl+yP2lFst5l9QG8j2JcQEotDV1KQS6mbcLjfIpEnltu5fc2t10Q25Noh+F3kF+LcMIYsDjwanojYlOC93mZl01hmSJdimRTk9otjlRTyC7NWwiyy7fe5IyVi7ACNPZyeUYJUPtKWcPbT73Vtf8W3/+HdhmyYNyMQ9PDCBb9WKMon+qW2+ZVH5yv/KqMHRY1fflAfxpHNhrCkwqcAAGw+G/cetbvQjpkfVT2/u/uLupMsITN2Tgvr/8D2IMm3cyDBUCshrp0AfzARRygHFK4x/0uLfCtQSNjw6zMK8mn80R5aS5bZi5gRS8JBMZ4Q0iG4kBlLpIYtsXSBwl8faljjdl/4XvNNWWrdGJn2k0eM4cESlOFFk4s3Yu0Zspo17nKAHINjHAiP3VlhuKSnk5C9hMU5i3vZO8anQmx9UEwUgQVm22azCjyNtUl6jVPYSNsal7A==',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 18:39:35 CET 2007',
+ updateDate: 'Mon Oct 27 09:16:14 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:35 CET 2009',
+ currentVersion: 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463',
+ versions: {
+ '381201fd3b67549bd6630841e8902be1499f3ff0c3514dd464ad9679f22f3561': {
+ header: '####',
+ data: 'DgjIW4YcJAYnckuEUzBFkfEC841LuanGopPgp+YkyMn3xuzdpGq/ObLFMVQaeAuyErh1B0REHPbq0E/SRUZbeXLXWN720GU4GXvY5bnen2h7pHvl/H4yz+kvyKh3EHJmmBjuz8s0kclFJQB48lter+G93TEmUaFke9c9m0IkKlgzwZ/PQKZyIyfZA09KFaozdSxdFRbswZj2Vq8Df2PQsKLapZWX1wYQ3lXOcyvNdTULy9MCXwPwX6te6hTLWxQOiSPsvB8LItlhQUsSbrJcJEvWPlBupPu5SeI25zDnqKDETPep63Ks2GWf45nXZzYYmQMzL0l2cenYFxlE18TcOd1Ms24TQ/iDKMhi60zZoo13qjVT5AKZ80KNu46t08qbACxjv/LeK2aM5TNycTFixGskPywpnb6MCo8ibRe5rs1WcTJRMD04sNoiuriivO2fiyo4rxjfdyfueMlOz+Zeztk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:39:55 CET 2007',
+ updateDate: 'Wed Mar 14 18:39:55 CET 2007',
+ accessDate: 'Mon Oct 27 09:07:56 CET 2008'
+ },
+ '99dc86ebeb20a3db0c5393d6d94bc1150187b04316a876970dbbcf517b55d6f2': {
+ header: '####',
+ data: 'AJwqCWNKC9z8DC4TUI0hWnqHvQ40Y/x+jXylnVAkyO2QYQcqg51odLFSfgP0GiGEGPYwDc+kUxRrfO+ITgTNm+hHi2iIWkP/ljAC+AQ56MAEKsU/USTbvl6ShZ0XTAdRpwI/oqqOhYThVs6jTm/J8+lx4tWoMtNj835py88c/9eW26pLQubr7VysLSWuIMi+iDp7zXZZz/0gxGKDe5xNq4MGIYw8/OK1iJCOsjBdrRygLlS/Mz9sRlKkwdrDsohtRG0F/NdsIoaU4FttGs/rY91SCedvHy6ovh0zXhxOO44O6MiMbP085D1jCjWJn9S1RBxjxc368MGfMJeZja87nuvgSnLS2tGDL6zFtVJMNcH/7GqQPXZv/sNEykDNWpypchCnwYUJxvBVb45FcUzagPm+SSiekWK1hrEntZkZuEhQZp7Ud9RcENpa5h7wXUJSV1vPl8xBylx9HWmxez7D9OYRqbOlCRAEDqup4ahNhYB9',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 09:09:11 CET 2008',
+ updateDate: 'Mon Oct 27 09:09:11 CET 2008',
+ accessDate: 'Mon Oct 27 09:15:58 CET 2008'
+ },
+ '9fbfcd3e7fe30d549a813f0e6c1be58ed45c3ae7305d7367bffefa097b424ee6': {
+ header: '####',
+ data: 'nZ+Lc5LWWLxnPvUrRrHhxG35PHq7GMbVENHfV1oS0Qw7/63NecssNoEbiOwFVMjAshvfUK7IjnzyvfQhNtFRbj2yzHOTWCd0eJ0O0MmvGzjpUntSDu9/G8RFeEu9jDKugwi/NhOa5legjT9pcsEAqR4s4NN/Ac6juQb6D/Z6Wd6wO0JQhT5/QPk1KllDpDeo2i/GPUKvEi/dXpik0KQcVLVylU82rf6hwEgvRQi+j0O5hnFW1E4ttxClrnPBEBv60jkNwcIpD0r+rvomDe8+398xUuB4DVDJoM+WUYfu6Sm3qI0yBfET+tJvjn8WsHhKTgZpOc2BXC7EdF99nNEg6kV5pSxV6AUA1XUz5kW+YfcSzAXzUH74OqroC0SucHe4+BtRKnbJy4h5vRfjTD+FJaj1Va02cxSR55tQhxm/k67z0QeyB98dnU1l/pPHwBlIWa1eR74gswNSeQ2jrzu5JeQ=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:39:35 CET 2007',
+ updateDate: 'Wed Mar 14 18:39:35 CET 2007',
+ accessDate: 'Wed Mar 14 18:39:35 CET 2007'
+ },
+ 'a96a6d8b9ac73fcdf874d8a8534ffb2d43da8f5222e96a4a29bd2ae437619463': {
+ header: '####',
+ data: 'm3yhZu81UAjCY6U2Knrgg8mK+LX35Y/iZgIEm8MuRDAlg6UUz9Z1Anu63COFV08YyYQRuBzTgR9YQ8wrUD1S9FG2ZmtCDemqvd+5OUMgdn4sK7G3CuzAc5osOa5neU2m4y19WuobkGnhO78ko7pVVjO42q0DeMT92uFL6KE/2UCkWlq5SdFyS5qXEJEWs2IO5C8nVpdlO/eZ36Pl2+v+afl3QQMTthCVIUR4/zVP2ajbO48yjDXhYxzskFjtXMYLApEn0wO0dcifcsYhPkozz6Locrt/R6IZXnfZfuW5XXHbqhutoJFPK6L6t0Ib3B2r1TNkPaMsVs2g5V1g3ENRd0IlbG/uBk2o5tgeu6gOYlA1scEiL+/ad9ZxiqYB2ENCGZ8DXA4VNMnzxVPbO96OIUCb9suV0fldGOg=',
+ version: '0.3',
+ creationDate: 'Mon Oct 27 09:16:14 CET 2008',
+ updateDate: 'Mon Oct 27 09:16:14 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:35 CET 2009'
+ }
+ }
+ },
+ '507f38b06d587d8889698ae1ebbba7ef8f0539b82550dd25779fd9ee88fc0c7a': {
+ data: 'ncSFmp/+n1pYUKi2fwhMCevSwFYO5irdcpOlSxC6YPOKYavK4iUbtBsilYWd0hpvUHW2ItaDwiyNFxs2Lwegex6dawKrpMYkPBcaZQDa746yACGgCkhz4MAGnUn5HCmz6xhpCVXMMKe3w2nEOjRB+pOMOeJt2n7aw0hCJ9tQ9JTFNrZOxeXrqoexrd210Rmr9FnKhLIvhNTN1/vXRqP0ys10omJ2mowzF4KoEVmz3ET6pS2d7tGjt9M/OYsH/ETWWc92doF5PO84g5/3HePaCo8NCqq4ul7AWJEbdnkxxmd7urJzIscPQPcoLxL7GfG5LhHTFyHlfFz9dNlccfA+OPftjyfjXTjLYZzbxxbi/nAB9Esqj5AoHfqaJM1ZOrZ+qAvm8Am3+HAXrqtiybDITrCLmGH9ukWDsx7R3lYTlvjArwORBUH+4w4/uYGscVm9kOYj/Rmz/ZMH9JibYFcPcOnr3rWXPFUL/XsXTrm9lzOvPyEYJmkENzd54AHC4Lr5vHpeuipWFLiJOrtn2WcgDG/DdLaYGKsmISXj74XDtP6Ee5lKOtbwwcmVNrl11UCQBEFHNybhXvpil5laKddOauLJDKtaDL/mKYPbr5YSk7HPCzRyE7HM2dC1MpBHuJ8g+hDkgU3wQcxYduKLRpuC0uOqrODigGWhVrdiKdZanlWUq9EkE3eH+E2A/CA8mHl7UNaH89XSvgV7uZyOmK7iZ+1kd9OzhBLQdJnK9qqP467Y14KsTt1E1+tqlqVAuK79QMnllaR0e3ztBRAQsyf5SD0KuSGXWz+z9/RjbhamW1s0UFRGh3voQMypU5RcYfYUA5KVg0BiVKFaiZBZKLo213hKbrgE2KoqVDEmIBFmwsu/S3EDzUY22tTB+o8ZKQiYesAUafGtnvsOLa+h6weF1ZvQVBerbD3fhb2o+d4ZyPkoRAsop+5it0QxsWuZL+J2oWybaikxIP/1ZM2ow4QZLaAVqihyHxqhF5UxZ9zrWxfp34BIPzzU9esSifrD0gXZ3mwutaCukZoijnGODJZtFOy9Rl1gyS1IbpyRbwz5O/YRl4BsD2aOk4InajT13Sa1BLPblQcrau13aeg/IzQhcUJ6n7enkrqiJFTP8N1aFAuYv8ilu0V2ymIuCLUtc4cbo7KyA+gnHhZA+DjjrhG/izOyWtQY/WtDsqvo/6ILwFk37JDjHfkchPEVcdl9qT7goG/4zTGX+lx8UTKKZJjJhLjA',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:01:24 CET 2007',
+ updateDate: 'Wed Mar 14 16:01:24 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:11 CET 2009',
+ currentVersion: '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b',
+ versions: {
+ '395eb58606138588dcd7e659065db48775610cc1e90cbd03368c063e02e55c8b': {
+ header: '####',
+ data: 'sgq3FGcsnlbhTLetMa3TQQE6uFZv/JL6Awha1066IimKoAtQGbAr6E1+mxRmvJle91sL7oRfi6suvDanYHfAI+rrG6qCOtESn70ssS+aGFyO3XwFgypzG/Qa34bjxJ16Aqd93H8IdhzdtOxs2Qmou3CjyxbT7Cq+YW/fAo1WfctL4yE4GBNPWC5lfebxSmINlBY+zTjhv9Pf2aK6vL4p3obHl+zhz0YdKAMBwbDyCLa9tYvhGBnq/W6lFUsyZCPVJJP3bQCQww0TNCcLJLm+SYVSiC0NwCQJq+yNqDkWTvv41p5EDB06eOQ2VqC7l4i/JLE/ql9h9Z++gck74/Qs3ppdVdG7sTzWyPya4v3RW2OTc1awFRZipAX5Zd7I97dyw6Yym4y+/9UT8z8iMDYykQ4+QnOhksDIE9a8q6agDF/rbZ/BCRcMWbFylGTdudk26mu0GdPiuLDu',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:01:24 CET 2007',
+ updateDate: 'Wed Mar 14 16:01:24 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:11 CET 2009'
+ }
+ }
+ },
+ '5cdac63b317f3942da38f3a3de3b7f0e5d6678200951c6216230295550f63fb4': {
+ data: 'Xs+z3VzIqsWa7dGBqepwq75lTsx3yemNhTdRYYDDc3Kzpycyp961SgnKXHjE51266mfmj85ASFi/FKCOwk17lbD5UT3iawtc3TdgrQ18vBhBsmOA2F4JAa4yC58bTaXbyld3c4izDp7i9+iyRaFN52NWJznN82SXuRtPdWRtAxXB1V5Tyg==',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:45:25 CET 2009',
+ updateDate: 'Mon Jan 05 17:45:25 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:21 CET 2009',
+ currentVersion: '00b3a4cd7400cfc1e7f7b369bdc3dcdaa50d6020233e131b30d755c89249ea9d',
+ versions: {
+ '00b3a4cd7400cfc1e7f7b369bdc3dcdaa50d6020233e131b30d755c89249ea9d': {
+ header: '####',
+ data: 'uGAV9pZTjrTwBy24TX/OUQwGmgzTnXv1JBIxdGkeoLCUhP9tAjbpUVylrUI5+VRrFYkXYyZ0o2HEgKrun2f3PODTxlmAbfkUldOV5tyV/EUxN0vYSBtgsMpqQm3bOKRIAo/uzrhSE3iwMjvKOTH2jUrkmX6hmqhXWZfa4X231GovrnOjek8c7t+LUBmmIjXEr2GSc/UbBoFnni+Q7ZArwtU68xoeCjLame1e8Y9wvCO8gIfAzXQAHsDgzn1MVeiWIqiCBTs8YKCO1yaxZpkzXV0yWzX+bHyXlKWwAk7Fu9w0CuaRULZmRCQhv+MMDw8DEXciTm0R5dRiVmSCFBy8cL9qlSeSX0GlnKl8E4/TSqvhMJblwJJsgmGSZ9cEt2u0E08tHxKuoeaaT1rpAOoiqx+z7BdhqjWOQZOGM4gR3EwqvOQoNYFUaXjAdmiUzW+e+TgE1IBQ8udRFl/D2zCcqFO90Hgc7hHsTDI3aGYvi6bHADu8hFpmZtJAjOMv1JgCX4Hm4n+SsbHd0DIfkEUMeGlVO47lcGWBZNRRm7xl8luZ4sZn',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:45:25 CET 2009',
+ updateDate: 'Mon Jan 05 17:45:25 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:21 CET 2009'
+ }
+ }
+ },
+ '6026370f3db3860d2c46a08e389a7e906dc14f98c8444b21be9a7e9f405a2728': {
+ data: '3oUg1TD+Lu4ou06j/MddOTXDqRM+qSKD+6Iuzia1Hop1w7v/BXidqeoKJZQI2VY9oO9B70Nr3B3wDROF+ycy6Rq+FM/xqUGHKXn1lAaSc6Wgj6TLQ6eRF6YZKSPqTj7TDWyw/2pEWk4HjcT8drTrCaC02tzAXMhYWlYPQPW4fUdq4hawoHIdopUN3vafQuFjY47OhqXKav3bNao=',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ updateDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:33 CET 2009',
+ currentVersion: 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc',
+ versions: {
+ 'bf8d46022179715d9d27e0a256b56b50828a771c3c6b46fe36fb2982dcb3b4cc': {
+ header: '####',
+ data: 'fehYRMkg/wFj2t/aWu7szbXwrCyCDpjQN4UNck4/OiDlth70a2ve6ow5lAi2jgdlV9WiFrPejfa8dD0Z1g19jx+BBsuUYnBEKD0K+NapdJBBeI0We2nj9nYIij2dfZVx7cuvhy8sN6+DdylUQLsFHbga+Gi5hWcMuULT4GOAIy2WanSQL1RSR4ruA6zm/t+VVboEkkm7PPT+w3LuRl3wRaD4a8ZwYiSV/SzgWooFrh2S3YOUeshdaGCiYpTbXscsOxsCxc11i6wQGBqYSjksmtZDvEegdQdzCmxvq4jaVWJElYYS3av612nD5K/w7Zei6RccBiODBPATjrIczYg7HwmQxIM/6QI9/LQn0LP0yqRVUUtfzaODf0uWNpFzml9l/1lwXuBJyQFBp7H7Th46ekw9yEuPD00oZ+eXvKwbwfUU0JshT4hnEBtIjM8fH974PU0y95f0yLAJ1+M6DVXCxGsBix2aKJx9fuZP4KGpaXg6qCb/6327rph7MGomcrGPIiDjYwD/NTMdGluc55OZfGXtOZUaJCUM6nihqDwU7Ly1ZzYorgcvkX/t/0RNcOkFzGYNByp7mdcotyiHqCDKspqz9mEXAd7Noz3HO5GFpPqbRo7htDigGU1f7dvgbbfRoTz17Bt9Mw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ updateDate: 'Tue Apr 17 16:36:08 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:33 CET 2009'
+ }
+ }
+ },
+ '6c25be8e145efb26a1abd59590522f73fb2e3dbc139af2217074d9e2ba92c16a': {
+ data: 'b2mcYUi59l434kGl7ij6dBu3063UL1dToMIu3Zsa9RV9RzeLKnezJhLKunqoAm7KwiJeqDo/REexHI1cshGYtHasVXXuyJfMx1grH7yhoWnkSRF4Sax6w5E5wnGkEpGJHOxXJ9rOjWHZ7yqCUUCB/dqLw4FwPOtRb/ynkBEYztEJA6EKGJuz0vrrTOsT8HMXtj/w6MEZ7qI3fPs=',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ updateDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:08 CET 2009',
+ currentVersion: '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3',
+ versions: {
+ '2f60193c0fc0e3f2f178955e1c68759675acdf691bcb918cfad329a5a97cfaf3': {
+ header: '####',
+ data: 'pZEWSdYIkrX8/r6OYmO0GEuKG9baUgn40Bmw7hXZBd/kfWuRjWsL4/pc5F5Ojrx+N0dxmQn5ZqKAzOOri29Rm4ruxnCbyK+oDsCDyMSnWy/VJcvystnDKzKmBRQVAOSEJtzEb3OtGzvqm0PQ1Dhx1YUAx7L6KlXysmG9h9+MjOcErRL9/1x1LZ33ytR+zK4LvTAb7gN5/9QgwysFyCkNP8bG4nyCzPMiUrBnP0odMTUvDkJDlY0Oia6VjGW6oNxnGIgA5fDraRrW4JH2oejQcrL7+X+jpCp05g==',
+ version: '0.2',
+ creationDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ updateDate: 'Mon Apr 02 19:12:44 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:08 CET 2009'
+ }
+ }
+ },
+ '6d45c2fec275b7482d41c76b20507100cfb6ab49922b876f9dd3040d361f4a18': {
+ data: 'jzjPgxRHApIJA/6hiY4XCtb5+eKzHlOeoiGwfVDvip95zU7ThHbdmxOUomeyCOZ3S1SGPT4lHvqZgfVG5m5RvH3JaAIa8EY1ZElRohoX3rETVPJzI/Ov5Rp3lZjtWlu5meNrcJz811HBHrtBuJxAmSjYcY3CCal+oC2zcK2fLZR/iOQ+69ONVFhdV9KiOqzNf8IisIa1sIgFopqsdHXiZ9oLe0a7Y56q+OplyU3A+TmxKLI+Qq+WkjvdMzZDDqzYH47me5niugYPdkQwN6WQUE0sK9QPs0uU4TOwqCwN9nPH/DoQ6oXWAu2+R4iCyt6ZjLNkClbps4s8Cwz6wfFQ+4T8bcldjveJenmrYwiUzxSd/4xa34yFVXVw2OD0n8yZhtvNFvfoPy+X9z+Y4f5HlM0qzL9zYya4KwWjFQzhOxFjni9JyGM2PJ1BctB+q1J+CHuhlVjUF0Y5zIS3zFTET8jjDGBZDWB+Ao9E8fUD+0OJJUdKJ4kUfn4ZUZUG20eLBjmJqWBGYZX7UFaPv8ksahoK26Ol6FnBE4KpPStQeDgXZDzGsiLlEsxHJLUFkNtAUXozw38bWWQvi2VIFtkw/ZViPIenmSNT14kUVWdrlKQC8x0+wECeh5ffv0i8UUw3v8QC2ZE7GV0OMl4ySlRCuDCfZ53YFoB3HIR1hSZMhHlHJDPUz8JOuXdHcUQaJeNrfWoC2KkKb0ZecBj9iXooDh9yGi0g7TS7eyhlz1LHpzEWB0CPsZqhNGMxmfFWur7v2hrYzoHQOeB19ZSmWzfUwd4dRpqMp0x1lZaF97jr+yyYhnuQvuO6lru15Pg6FqjzhsNiLtaqtyoaMiHZ9veZs04qZZ9Fn3U7HeJzjZSAssdLnvopXi363cXm9JqoClyV2OemnVoRwOZN2gdSZxGeOefKR7U+lrBAbJwViMnmT0Nd7AC8C1k34iEt8HJmpztXeOgX5CQpwUPENMCUPsookFbIh7e4aByllEQy0gBbxUz8JMIWYyw98hdASnZ4s8bQfSmiMM8Iw3YxCexKB62LYYJn1UY51NSnwCtwRep+NhaKDk2d6SLh9owxnFbjhw22RriPd5f1InJycjtpvMzWLavl/hDsjjj1kWpnCUBTM46LbERmjz+s4x7fSf2FhhguBT36elz69ivXoiXI+7p0E8f8HsSwm8sgN/AA5m1svsXsdWeZFUiWtAwLg0tI8YNHlazbvFCXfIC6Uhq9eDv04iqdZ3rn2c1rwSx336A7ySTBFdxOCJ46F7ShIhNKm2N+5Qf0K5B2L882fbwqiLsa64+X9aKvufKTsd11vyf19Zivg/Ze0FWoGC8D63Nh91k6Hu32RT+uAtJIjQIZxu9yXJM9lMaRA8ieER+ghrLHaGQqF9J3WmueER3UzU1midvTynOV6g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:09:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:09:05 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:15 CET 2009',
+ currentVersion: 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5',
+ versions: {
+ 'e85f085a8ed42d2def7adc796b66a2e0a4c3c88d9f3e785eb12a6f5619d945c5': {
+ header: '####',
+ data: 'BbXNAy0GcKKyDPiwhP1Jk9mIi3uXMHQdhuxpDvoR2C3YITOUBpurxGhhvmCg+a9pS+fKJdZPxL2mPbJj6GfWTEsm7K/ECEjrVkSTHi6PTUUgYVbCumq9EHjUspos+7VrifZry3c73+qAvIKamvUlNB86TchMpOXVJIyx8UgRX+bdhrxk9ZCEVOiLCG1zGPX8IzmcxPmBRZFlHYqE4ibhl/CLEzWXZBYCofTusClhOh7YM/jBgvDt64W7aIN2y2KiKwmFySkFZdnOvbAb34tXVimwqjqWPvPwd6MujQeX1bmaDD7Y0kXac8CJxqasIezLo2WqzLUbEXdIHGilkaPT2ZKpKhKkpHJHFrV2lVuQJVqwPUr0Gf9qMKgVnsyU8kUfq9ox+fhH70+v7BQSjT7bxxDLs0UesQeL7G4SqvNet5hPI4GQEpOY8p5MUFReIBTRm72NQEU=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:09:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:09:05 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:15 CET 2009'
+ }
+ }
+ },
+ '7bb69b6366a8012f181c01e368ba18d4f7a82bcabb4959189736ad124c4bbfbb': {
+ data: 'wYPZIt0UHiNVefNwtGc7z7Lu3YoQrXdfKmWqilZp8yeIrNfSLB9p60DLMrL3GDq/CsvDYkGAZgj1C/6NVnzVsXsJKq7NDZn1UPOGt+hCnw3lEVbD7zHkoMM4VgFDn1sZdjLe8wdpIFfdlQESTipT3GVXv3swG2qX2O2yuwtlopR8yZQTLg==',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:44:30 CET 2009',
+ updateDate: 'Mon Jan 05 17:44:30 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:18 CET 2009',
+ currentVersion: '23f5fb503e54c0cafe3d4944ddaf40bc74fab8b5d96e2bbddf693b1afb225e5b',
+ versions: {
+ '23f5fb503e54c0cafe3d4944ddaf40bc74fab8b5d96e2bbddf693b1afb225e5b': {
+ header: '####',
+ data: 'IpYj+7t3DhSVD8r9PkLbF5xpGrHhg8omY014P1vkT2KkGDEUj+ekQAbQ1g66Z7oNhRDpjS1/dcDjzH0IIQLjGuQ0oRfL0xZefVTx3N88ZLE39m3cJz10K2xyg3xp06jFBmdNJuCkgRhMzeUXeEJujw4lS2kv7cO04Uh2Maui6jDR7E498rgePY3L32vG1S66li/xU1vPjNn06aFTqSYxUL17/mlJNbgp3XWjGC+l0dXLLfXy1wOm+/I3zp2caTs+a2zDUZ15s+3XeaAWpBH7QCaQsvsQmoBqPbMvkjOQwW3taDvV7Hvkh+qTjCEcLjRFwhZkMNn3N2ewcLWQa2aVIjxt6Z0F4s/1URztWlKVzCfto8RmrLajYRn3ggG12kX2xDJFjNPNfs/7A3tMn+FqXQCCNG5GI06JZ32aQfpnjtmXScUuEs8UeFgsNeYclQhcm5R0sUwISK+D345B8859w+4+9OTY38NgYQQ9o/tmpCjWj1tLYLx/m/GcR2em7iyDpBdcnWUb+tK6Ah89qvXriHwPLSNzhOH2wxmi7nXTRQWMv7g2',
+ version: '0.3',
+ creationDate: 'Mon Jan 05 17:44:30 CET 2009',
+ updateDate: 'Mon Jan 05 17:44:30 CET 2009',
+ accessDate: 'Mon Jan 19 16:10:18 CET 2009'
+ }
+ }
+ },
+ '8b18e8593b5bc2f7ea39a5fab222047034ef2f380fee05be0fa6e1c0972fea39': {
+ data: 'pOMTY3PnUAbwMLDEYNJCMzp4iIA42YWr6gqoomg+P40e7LFUtbt/RQRelQwNIztyUSVLl0rilkZZkBUVvxrtTqvibKITCjJQGQIzvcb+Yl4mNosl2Rpp0xxMU03f1+G7eGbuCc5hJXYVAglhEYplaAPzHbRWXMY8iZXZPBuLVf5PN+rdpgAfkGeZ7Uf9RsQ9p/EglrWXYnTwXi3saUfzIjfvSHm5C+dXTY3FHpIc1YkjFrdVgMkhYQGV60JtZcwFtCEL2NpVljAbRgHoIXTOkzUvep4vxrtfBBWWMuAWEI06432gtnH6IQbrR6jOpwuMt7k/09qy/fARPHs3r4qTJ9r2uqWHJ7tjJw+IChQPC+3l5HcPpFURiw8LGAN1NyY1hUrF6N84RSn7AKS0bLa5qN++5lcjjxn/k8+JqmeUqN1/SYIbGwNnJeZ0vA8yvOxnD20iVADX5kOVqJDwXRPLaF6Oz9KkbOrmANCh+PmGw1i6PduB+FgAU4HViYCw5IGOUZ30Pm1NJofqfbhXvgzn7ey2+kUIAwDyOUpJ9fW+9jW/JU4rcawmzwBYN2V8apOoyc3wQJICm2984wIfVBpygCOZM0QDyVgNo57qKtYH3yMDQSkKvpEUmuhklMYhcV+4X5ggdqx7lYXO9IMDnFf2ZDiZyieTlOlRv/nNVecUB177Xpnq2e+X/ik2rCQWVrIymiV6ltr1DEv0krXKfvXGG/FMZHUmo3m+B5bG4xVhmt0GnHseqvY2Vrl9NksLgq3hTDOGSGIy5Nv8kfrd8B4/6Tavh0SumiyXnrTXyYXzCK9E7IqO/0KAln63VkcHsbOtS8mj1drN0YQ2KKaeIW+Yr3Gm0pbcODsgA6aFfz1itZVeovBqUklhXS+/Es8J8xOSvvSyD/TmlFjuErHa+wwNQvftosfwk9ZTt0eIJS5aLHdU2QsCjdfSy0DEPkk2siGhBX5ZhRzqyIAyXApSmy+e7PIqn/dDR51+D1ZHwoTQyTrd+F08jBWZgU/OvS8MRxNZSxQwsi7bcWZG+w0utrIDB8eSOMVBXI5XBeJb4h5Bzut18C1shGHeGkSJp04=',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:10:17 CEST 2007',
+ updateDate: 'Tue May 01 01:13:27 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:02 CET 2009',
+ currentVersion: 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8',
+ versions: {
+ '8a032b53f7356e2d8b28665211abbe2cf1c79fd8eee4752e83cebdced1c19911': {
+ header: '####',
+ data: 'OXpNHHSkdsaD91hw2LER+9XKpf8+bh/O+OcLSgG/gAx228UpifOCD4HTAOs0C7IJ5zhAq1L9NjCGb1QWWTFErYEtDEBRBV4kogscP9HWPxYyZHxjwPI0wE7Ri2eD4Rma76Utb+xVnXWuT+vNb8eRUCK8Ur1rlhYafS0uzAYvVqHDNfZaICksxeVQojil/kSPZDMu8ASz5pMNFNCF4SlwDKPRrJJDbNZ62A3px59YJtsla91DGVyOLhb7VNRxEwnXyxENfP78yA6OjvQDc2KhKFUpHbZws54IolLK1I1mY/Z8BiDXPSnOa694Q1eZxy1Kx/jLINZUIPgGg1++YWITx213awOISdf7Oy0/dUpu10Vr1hgAqCVlDp0IuGK01CswRzEdLVpUk1DaGHuin1rryZx9vThUkEJgQQc3ivr8',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:10:17 CEST 2007',
+ updateDate: 'Tue May 01 01:10:17 CEST 2007',
+ accessDate: 'Tue May 01 01:10:17 CEST 2007'
+ },
+ 'd175358ea0b9d32c23e4bceff2020eae9a8459466abc18d4399d988e733fc0f8': {
+ header: '####',
+ data: 'tvSUu+NPKHkwt/ZLXdLGdDm4jSxTEtJfsecdpjJ9UGN3Y2EBCmijU5i7q+hMfNDqBJ4/m5Ayju4zYDAKGp2pt8l1TFoDurITdFcV12jL8j3dc4TTD//uC6OtowRN+altgC1Xc0LsSvEPabjAlwfVC5xqirfm5t2mVmnFZ/GALkGLGxRJRduylT6goPwfunkVGwUdqMa3md+9mwYn2gm7CyC0lpcKX8AZ3B4Oa656yRa9m3Wjgb007TtorLIpZO2MzVwxcHBqqy7YpN+zpmZz6Md9VK3L4F724tuXXWnDeVzGxBO7aZVr62hwPMXM6ibCjUScsaS4f0chivA/tBJoyx7OqKhBxREGeGjpHTeLxyHcekbwXhXyeqxBuwG93yGKutUhGLVYcXwe8/+xSeaBGj/j2RWutKbNKG2yQyNPGj2cxJWsR4YfOQJTSOSWT3K6Mmf+r6hLhIo=',
+ version: '0.2',
+ creationDate: 'Tue May 01 01:13:27 CEST 2007',
+ updateDate: 'Tue May 01 01:13:27 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:02 CET 2009'
+ }
+ }
+ },
+ '9dcd2a8a0fcb7e57d234dc4fea347f020a6a01793e40cf56a0d22379e590e291': {
+ data: 'xXZUJjgxn62OqnzAvScHJNo4WjYEFp1vQ4ueBe1sk8dH4pXZUKV6m9c1d2cLUgBj4rUNP5cC66GiFHV7G5BDZGLrfrxUlYU6BWvzAz4eG463pRDhHXQgPrhlIGDlK6ovaIsjwaifvHaEfLREoXvLFluqu406KG58guhtWdIFK0rLypyRo8uyltGbTz8wZdu8atY/JYQnb8NaAf4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 16:29:06 CET 2007',
+ updateDate: 'Wed Mar 21 16:29:06 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:01 CET 2009',
+ currentVersion: '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7',
+ versions: {
+ '5da9ecc65677d03f4f31c0f12f000caa4930394a99af8187c05e74b99c851aa7': {
+ header: '####',
+ data: '7wg/yWfSasUjJKV/5ygFfteazVSdqEJ8xGAqtS7m/W2q3rOR+2fr99Il2TzxXCnOe5zV+iir2tOqPQt6BCGbVf0NVwZtvfO/lvfMc7DIwyWuhZ0sS44LBTD9VY9fruuIegktVHSNBoJTCIfAHN/ut1iB80+51An+TdpYT3SGAVM4RdenQ9IdvDOnQo2KE0E7BzHekga800VJrbqI8aJEtmm5mOjte2xHYSPFDCtwURQclwxbNv32hAY/IUkaejqg93WGIzHIIK0+SSDzQwHYQo4yzVGCKKy75eghpvGyg1zbzlv372bND+OuA3laocARFfe4rRd5I5nh8vmSJ+vybh3EIJJzloD+qWk6hsEagkYI0RYu9I2uOfA8drmZ02GV5/ySDsBHX7uhaTPGx4J22rNJoj8s1L7UoaohUHFvUerBvQTir2LPbzqT+B07wZOU0ibtHlaN5C2XMKRxfvGATeR+2J3l7WisCIoRdpQcPFHA7nlTTShBiCVstLxolvd7MMzPOilsi3ecxXLQSeWara4JILqXQCJ4yLbQCMnSpIrZ3TXbwbPZ8fjKjogHNUaBPnmd1hWoc7IVvK9RSFBEdCh9U/hbyPMCiSjdsUCTclmhFmhiVIlB73IyWixmLwHSWSl/ckMxcUK6rB0IPuWcT8iJkxfqOziFhMvC/cNydpN5Nj4WX21c/1M7lVlX10FRx6NIYH5szEXULmLnkfEwr35G9mKJwR2pgZ272UiW2cH64/+M+Kh7XnPbQKxTwVR3FOhR/qdSHeA8MTc9FDslFaTT6YSeJEPoQiLg4c4UdbB7w5nA0o4qg82hiiJbTfT2zFHZeeWOpVO1z4V8SidJrQkh8aL1/Is7KaDVNfL+Lx73gfO6tdSviCJJhD29iTgn+MW4MlGwpeLKpvq+LkXNXi/CVjIa1VqtR/Flk2BqwT2hccgw6E1ML+QdW1n3TvTtdLIvSGheOM5kLdnF76e8Nj0kHDFbnxQMlO7lutngaNBRAvhvSLccT76TMG4OTxNZk5aOre6AIOuUfrFD3KDeOqWie5zpkvTOd/JK/JDFYgbYQh8AqhwJ7VWUH49vfd6AqfwHwdNWymI05F6/0Co4xoQ6qN+iYNConUXz78Uo7AraJuBDQ3a24+wL2mLjnc8jUDFUaAKM6gZUv9+bx1vk6zVdaZcuqgZc6dcyo5Oy8lmbJ/SmRb8BF/Q2nW3SDv77R+p0bKPLmjcytczlMNct58Q1LoiLnGck5v0wByQ0XIMd',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 16:29:06 CET 2007',
+ updateDate: 'Wed Mar 21 16:29:06 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:01 CET 2009'
+ }
+ }
+ },
+ 'c0ce9130ca365bb02418d4305ea1d29e49c3f0e96d44b9d3cb6b4b6843d25065': {
+ data: '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',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:45:43 CET 2009',
+ updateDate: 'Thu Feb 12 12:54:37 CET 2009',
+ accessDate: 'Thu Feb 12 12:54:37 CET 2009',
+ currentVersion: '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a',
+ versions: {
+ '36a2e190796c4c8bf2340fe6d7f1d032b4ca40eaf42b9ba537e1dd06a638b26a': {
+ header: '####',
+ data: '/mnLRePyLGwPaZ+EkbTRHdE4jz4gY99jnHcIp7AeMfcktEpPmUVNWLwGSJUH3ANP/cO1znxACVQPzC+g8IVIK0muJ/lZ4Iw+HkpsfPtBjPZc+bfhsY5Mud00YBsImleIMlbbJGv3l79eSPcea49OwG30xro6b6I0KK3BmSgr+BG2AmBrKVlFRTPFCHRbO+hG/LgW/xqYgwd9f1dnbeVYCm5lA2zdAnwmMwlUIi/J73MbnsSO0Qg858iF1SPQ2Ne9Q8SCyKKEZwBY/YeSgDzoO76Wvqbzk8uPdmZldaF4zql3ffBeb9ZS9KIyyk2vJcLk7c3DUc65vaT+w25+2GSpEXD4YIV6VSr6Brz4w4gzcDMeLve0U6oruqWijz3CDe40yhd4mMt6wTVs4xo0KHc6yKjTuC1ZUQwZvuCiS8T5czaGpc0+fLyfuE+pVBxTlpOjkoZqzk6NsH5lcKMzB1TCscJ8fbOdtJso7DRUvijIE5+ayY9IktZhMeHsk2zurKV95A==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:54:37 CET 2009',
+ updateDate: 'Thu Feb 12 12:54:37 CET 2009',
+ accessDate: 'Thu Feb 12 12:54:37 CET 2009'
+ },
+ '4ebfe3bec6d419d61eb68a1f25407824e404e3439c23fccde1ac19225b40cb06': {
+ header: '####',
+ data: '6VvjRN9LKi7tt/HsgqmU0bUdZQNVjVAYNLdCrfKdRJCx3W/GZHHR/AQF0FcvuXIn0MWMUypHpTZW86V459OEoV4W18HXEisQKEiqBnUCBaxBd1NKZDpYsThISXXOhZSbXylbLoB+kBaYzT+Fc7utDheVvVPeMo+iEb3ih42B3En3ZXcgUAdEjfbRUm6st9Jiaz4onwXWknVhkF5QewA0GXDhT2JdakFxfUDay75wKvspq5IszbEYwsu+TEgsbuO4/R/bktgsQUrbhtKIEIiNSccDNx1JkUKvIxrRfp1m0Ar3XJsDfv7YSJSLdyVheOEdIpBkeZ40LN83uzGRMZw1bQsKf+XOFTfacYZBBzwVj8e1rJC6AWlH6Fbn0jXw3JcEljA4zUh5IrYhWtyIZW338UVsMSIp91USeM4uCvPsOLAdyCXiWu5H8MMYGz1rJxVlTbMiq0tn1w1f+CL14v8EiUft7l8kfZzBZzdLvzdedD/wHQ==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:45:43 CET 2009',
+ updateDate: 'Thu Feb 12 12:45:43 CET 2009',
+ accessDate: 'Thu Feb 12 12:45:43 CET 2009'
+ },
+ '7ef137cf242e00136e57ddd262edfe6b418b6f57f3b5e5e15f3ec1232867f6c8': {
+ header: '####',
+ data: 'N5eWFfsQGHR1WytyXuVySzJ3zenJEB6IaKr2vgWRHTlJFzexXzJmSLoozTP9Z4TumDOLsNrp+EUeIa3Yo+RqSyQKQRFDHXlUYa6c9PPLPXdexSA9JO3AHzMSpL6K0E4gN3BybjL2rbcQwUqJLvCKy44OdiJvORGfIIpTPx2LQ1o4P+chcpOwwe/ZhgLWmNC6FmkTvsU/xJlNuApyD7tPX7Cj3lP8WBfYEPr68BqTKAa9cxai6ZF4BRC//rFob/4pQNHE+7qjOSY9HOnV5uCtZehPYBwfpBiDYhaxWJxXN6sxtpe7GC5CM7gAAHs5lgVaFSWffOAL3zeX7I4vh3j1nYdXoh5KowZJVVUUfhwqJo2T3YDVsaXNibZIaPd9GlbeBBk2HL6c/ao6B8QNwRU7GvMHAdJKta2I9mtU2NCnr0Uwi4rZRR05V4k0HIMLEJxRo/IYAysAYETNIAXzk0twIokOF5JPjP4uTXRZ8LdiS6JqfoUu3Jv/7yq8wrKZM7DaQA==',
+ version: '0.3',
+ creationDate: 'Thu Feb 12 12:47:39 CET 2009',
+ updateDate: 'Thu Feb 12 12:47:39 CET 2009',
+ accessDate: 'Thu Feb 12 12:47:39 CET 2009'
+ }
+ }
+ },
+ 'ca01bcb7691f70818feed46c9a2a91883ac543997a395535aedbb49de166690c': {
+ data: 'zbQlGR1fT8HoH6KvOPBoaIjMUsVMh8MSNIzPO2muIMJDVfXB2rEcPnIFl8fNv9BtE9OLecuex3BQVJKGXdVGFYVNiSS0SgPoEpyD6GJntEIOaB7GnhVflTm8fT7Ba8ArS4r+fIL32Jx9F8sYrL6jKPWeuImGHK+x3X32uORI6znkRac7J727TiTPlbj03X/Fj3Of6Bp9Wa4xbVMwzi+R6NRKD4A6Za3mqhoSpYFeHWld8+ChJU/w2wFkj292OjPBzvvz/SR2Zth+AXTChreQ3Zl1hWNGmU2Ep8ijFCYwcamgPkQwh4vBk9NJlzIgadORcb/0EPDxn638VNA0dbpW8MZUCIMWVe3A8VgdllWxei7dDy1ri6xsKlFovLYjRRPXgAqRSqVATqwyXqhBWhoV6VZ5NaSUGvM8okC2GQSweLuz29py0F987MISmLjav4gdvcMA1wn7FOIaFTNg7oy2CxZefGhHT3sHfX/PIvs/ovfj+7TewI0k+HR414az2D5reo7S5I4+roCm1QLVpPNcXUxbAmEbjF8JCsTtECZ4kdpG39dN6BaMlHoHSN3wu05uTSn+sL7g3Cg0pVLlnHo9baw3fUnVJp3MCEgZJELaiI/WF1Om2y2S9UeLur18z5T7hHFv3Px28D7c22HEDdF2CObeh2uOlZGAa06lp7YlYeoNtb4CqLlZAMK0xIHfNUceC4OMNvqyGswd5WJsYQEnMry20OkxY6YinnQfjAml54B6WlvNVlg/YaKjw5AVinUHjzEFfQbcBFnFGpqg5qJk9hZmb1VI6Ujhq73fPydSfkvfScTImqxCNPD/BR8ovoaJtNpE2gmcoX9A5zhZgu5xUnUnXoaQu0l7K9kWof/UmCCl0O1A6j41aebWr+aoFMalaOPzNJ02vfLuW155IwjFQvRuAp6EuktZ2dFKyFl3QnLbwsMnitReXMoW30cqTYg7ODQnopE73RIb41Nj07qdx6FQMzw4gAIEFBe1iRvlMHQazZCb2ndVvgtK3ZcPNtDoahuPRxMLaKZlRnpa8E5F4o8NHYNivshawZi36Hk6w0dOimCiuk/zvJ1mtx8hhX7B5dsXlNcKxLSvI1onEm2x9HL318xJeT0y29alzPYVFuQs5kq1+UV3h2hL4E/H8h+5mWtTLf/MjaTZ09okW/etuHFFjCmLoKwugk70z2yLWEJGmbjw',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:51:17 CET 2007',
+ updateDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:12 CET 2009',
+ currentVersion: '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926',
+ versions: {
+ '3895963f82854530ff754c8e2d1eaef8d884a8cba7cd058b8b7adcdc12be3da8': {
+ header: '####',
+ data: 'rXmjQYZgxv9jpFus3T/qa9Qc1lxt+mDF+dmZeDmDG3IiE/LnonGt2MqL+YlbFzisF99Uv0IQGOZCPigtBwOXB9m6R6R3lEy/YhD/C6b10s80OBj3yr3PoTsoTmbnmZMYd4r+qx8SaoLLkR0aK6NADYZXebR5QgVtwF/a01EifI6YxH1wm1RX3kyRhIrMzOtL8zHbstPvW4sRtv2YpZqlZqBTdoiqztDUZTKEcCcU5QLnHYMNAVpDHE7D9WvQy8Il1taAbxg97Ir+2ktZLjqfJdKhU7ZLv8fcJiRgnQKPqDWcqpjA+CXM6Ak1HCf9SRJh6Hl64+fk3jEVAPmHvry/xq2RPCG2YnVNWZ+uL3QNuH4zt+IbP4FnrxkCAprmEiNwvuEefMgliGRd+FowIaiFWXcEtYxxQvRDujZN6eoTUU0KVnuy85PKi3ih0ZECoDM88MFhztwCG9/nJQ==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 15:51:17 CET 2007',
+ updateDate: 'Wed Mar 14 15:51:17 CET 2007',
+ accessDate: 'Wed Apr 25 10:37:27 CEST 2007'
+ },
+ '5311936f6a95cf123007ef867388adb5c1ec5b2cf1173d66e501daa16488e42e': {
+ header: '####',
+ data: '+VirbcZ59SiN9UJKrQkjQx0Z4avHIhvw12Hq7fs+Qnoz4RgCS17fqzYyJe+jYorjlMPjzUcALYOTobqJJp4Sp8v5nOilHW64Gny2XRp59PQPg0zE4TP22l1PzK04+qJusR5NLPU39hYbW+InkDapdIhdf+nIruqeA311bRLg90A8xmpzio6PkZxXmhZMabbEVfXsYFBQKVBFloTMusBG2eaxTjeK0hOAk0uEc9RGOEwCOvZvjRFCP8DyZ5T6QV1pYYgBFBwSFrB/koXmBmObj8zscJXQ4H4UWC0yw1B3ABbhNX7vC9q+vgZTxnGqI6GvzLcrzaXKTEyfa9twq+vKFX1hqDmM0UVLw0dPOy0/3tabJjFrYbz5EEKVin9UqWhuy5YIvHEJlMkH190Zo+lPMuHvD8TiAU1M/n1bTQSBQb/8STD6uqefbKS/s/bXcS+bdVKBmSgCuutBznYO',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:39:26 CEST 2007',
+ updateDate: 'Wed Apr 25 10:39:26 CEST 2007',
+ accessDate: 'Wed Apr 25 10:39:26 CEST 2007'
+ },
+ '55ab21a3c8f10df776aaaf923f439b7080d9fcc71b192a51cd0f1e17139a1926': {
+ header: '####',
+ data: 'P1LfM+8PA/kyelFsojabLfBW9D0Aey5qDClz0OTdSamMT2Mv1U35eKcr6ilUrbtW+dKJotAzs3B1dYGzaEQ1j9HnhiL2pk4wgT1JWGe5c9frmFX/3YGO63c2ngnaC/Rrv3LC251cLVS1aoWNPskWkjZLzF7EiWbAeNYTplSa6MWm2LdHAm6xq2dcgYx53RJVvjnsCzpghQdzL96G8ScJjnUx8FC8mHW4Ds0rkHTeoM344Ao8J3o1XwoFqFFJ2X8+lSkj8LVVdjff1EHIicjrMM0oJG8VyxK2TxMvg4mnLWP4ALfh24Wrb9XmrM0NjhQXBo07tL9dwa7sHHKiBrM74644vBR7NB0+Laedg8D+6FmgNoR6icB+qvxCIIvAhOpJ0er9f0CGDDS06knx/lDtVVNewzxx4ATuG0HQn8M61eU83EfbKWG4Mg+9jtRcW0/bdFW/FQr/OeKg',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ updateDate: 'Wed Apr 25 11:14:05 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:12 CET 2009'
+ },
+ '5c622bec0fb939da012beb98a858a4e16bd670b3e6fe1f7c92a247f88a65c747': {
+ header: '####',
+ data: 'XGlplDTD1xamZO04H6RiqcLd7XaPwxI3MqpKTCVHPBoMEkwE4A1izGjFKdPqHbQIuYYcT9xDgPOknlkP89jDTfcR4UfENtKHFgFaMee4orSER+MhldJRxMwPLorZmMNNZzVmTmwJS7FI9jYiXEvDbcyw41kN+SA0mxzWpc9emaX4TmZHzlBpY2zXKJLyN3otYYzcTWzuu7DJejWrB+CnNp925X9vVomBPfp/Gt4tiOFsE2ZyEf1B/7cDmMszlQgEgGJONS+C8Qyr+X3GEh5iPoYsGpMNmF7aYnZNciE/B5lP/ABVbZIi2KfmRlSf7Cc+kMkUXyHxOeZHuVv1ZlzfIe3gXlD0/yUJFHNju8ai+F3hpSkhMatf71mLQzD5oFrTmKatH+zQZhGPP9dQxG1cgZRcjbyUQJMazo+0TJuNXNndi/oiRzRJjYRUbZKsfRzIAEU=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:51:49 CEST 2007',
+ updateDate: 'Wed Apr 25 10:51:49 CEST 2007',
+ accessDate: 'Wed Apr 25 10:51:49 CEST 2007'
+ },
+ 'bad48f8ab053804a02bec678db01baf24de35ef04a17b90e1362e67fa352e4a4': {
+ header: '####',
+ data: 'SXl3D4C5Yt81L/117xsHYjZxT/fANq09VZsMNAz3Gcn2+2gopG+1K0JFg/1Mbjt4EMbe5Or42zBlJPo5EAldAfWu4MoTkQzo/wKPzgOWlIi3A9QwZegw3yCuHvJv8iNcpjGfpY0OCzTZKNomTtwc75l+8FqgwPDW4wDkPG98275ERDR8mFSZfUAiQxlTnCbskFneUQ6hdN2gywkyJKuTEcrMkIpzwe9uqPaQg8GjUvvy162/LVaSQAVRIiTbW5URCD+hT5cKOkmFeBejHar8zR3SQQ+tIJlKERBwfE0sNR+RebSboYxWPECYPp0DMj30FnHbfYIVTgRCIlepy2hfis0+9C7dop0jK2nFREjcxSIqonF+juCrfJDt4cTlpn2SmcoMJQsUOedSh6ZoWweXm7lu8buCbA2Q6SY1L6jz7okwIikIinxGDq3qT1pWSgpntI8wvYZ8RD0umJsoAzPYH9zlfQ==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 11:01:21 CEST 2007',
+ updateDate: 'Wed Apr 25 11:01:21 CEST 2007',
+ accessDate: 'Wed Apr 25 11:01:21 CEST 2007'
+ },
+ 'c03d1fcf5b6981741f5d4787315534641c61daee9aa3c063540fbb704989ded6': {
+ header: '####',
+ data: 'sbn5IDJM7VtYov3sqW9+/0USxZEw2xq8di1XVPMMZ6kN6oZZrAY7ukxXHYh+mfuIa1/uV4i4v1YCaKZQShLgUS4cchlK4nnNVL8zejGwB+PaY0E8Um/Jg6E4UAFAZ+haZwzWLQS8lJ1r4hNMTeFqsDRUhC30awJRz8e0rBejLZiS2Hk/jgpH3i8Za1GwDzogw11iHXejYI7MaQGB0E9eQsYYTxGjmzcLfVYkd4AKj5pSEHvsKZklSuWIyDzwaFiIO7xqcJmS/8Wkm63JGNOW3nLR5Ao9V/2vthFHBqS2lQNRnkPWXbmNK3v7vi57zu461w1Nn1U/70EvhHRMk8BdML3XI/U6WgDARjQuVsB8FnTkzapaORG5vUd7nTtWjPdyQzOqacm2YKWpAiG6fUQTZiBusEd8jdnv8BioGUTbXgNVG23zcRbbbEdjKc1aizXHQE1LnROvoHZHkwg=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:59:57 CEST 2007',
+ updateDate: 'Wed Apr 25 10:59:57 CEST 2007',
+ accessDate: 'Wed Apr 25 10:59:57 CEST 2007'
+ },
+ 'dbc283f49de6e303c06a52725b8187f344ba7b433b0158d704f094edba782710': {
+ header: '####',
+ data: 'fbNrpIoYF+gpMUjSxoOc9Y68qRlE2yk7FPPkrHTu07HHWkAWy7H7nFw4BwGiFViMkyEC2orUrMeDYhKmMYFj8DEcALk6452BtNutGZSoqDhD8xnSEPF6fP2Xyy+vZHp4JWDXZt/xHk4vPbxcwTTlmRz5aO8ChXIH5iqfRL9+Dx+gJDKgKmCRMZYMT1pyOUewmsT6QDYdGFJTRRiDmoLfCVAXhJRtqQSBcx3kN3kuf8gyOMAeJnFGISTAj7THzo7eGuQol1omTMgGbDZoL7WJNfZIDamiT9TWwzp3UmQcKIsRvA2ZKtePWRmpWyq6WydJgFXHUuUDVpwT+kc1Rn9Wq2zwm1VBw6gqKCp6W9bZO86rRMs2CtuLT+agSpqb4kz4SEYDCW0+aUsJDCYBXx5yWRM26r0XAbU6X0D+xopGuaVzsV5G7chkCO8mUsjHzZCK7hOAz6OgjR2+',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:38:17 CEST 2007',
+ updateDate: 'Wed Apr 25 10:38:17 CEST 2007',
+ accessDate: 'Wed Apr 25 10:38:17 CEST 2007'
+ },
+ 'ec525dd942f72b71b5fa1aca0a36a9960b71608bb27f32bc7923713bde021b12': {
+ header: '####',
+ data: 'AHP4MFiGukFCCnjLDGoqJUDEr6QNL+KoZlcwOqJIYusRtl5qmhZSsODHbAEpmadxLGogDPrWoH5/XLZ85ASGRF5ALzDgrFKP47/bSEzKVTDABY5BJSqvKgS/lCf2LdR7+0HWUVJ6Z3GOb9GqsXC70pMxDo/RfclOQPa+k/sXCW5u0TmLb/0i/dZEM8N++4umXsyy2WPLtUVzQZ/VdTMDwl50FeQxu3aNGy4qYd4XFk/7gxBH9skBD6/GqpNajHJrcbi/WZt7PZiN9skoVZHhm3YLmteP5hJnrcCGBFJHWuQpXfB7NR8rNmd2c6maemKYmUlX25wQF7JPcROOcyT8iYpF4Hk/eSPs0CSkaDdqSD0Nj9E4kqZrHfVGMwBbDFyAzdHTN3EyGuC4cBXdfNZbdBqwghuB1x7RLXs/pbXg1xqukjRdPLTxUogPdaQBHGo=',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:56:58 CEST 2007',
+ updateDate: 'Wed Apr 25 10:56:58 CEST 2007',
+ accessDate: 'Wed Apr 25 10:56:58 CEST 2007'
+ },
+ 'fda6581f0137dd641387a7be193b06edea4451835817bcda38d22ee24ebeb77c': {
+ header: '####',
+ data: 'QwDMobl0Kds+J8mknphumnONOIF9gH+pC/AJpxGmuy/rvKfHSeEuuWAZ/yWj8J/I4V7OjpyTs9/uCWeKs9khpdkcxtObB36IfcbWBHGOgFjvqKgwMa7eZSIUPZz9k1NsqJC9nU9U7w5EBzQKVIjJaey1EdhsggdtNOpQTzt7iu2mWKo33dJKQCQ5VEwhpGh6SH1TgKFbdMkOJJY8d5xPYUxR66LVFpFzgHP0ML5M5U53PK+apT95UIAlqf7N32BjPK63Nsj1WPsnuuL0vWA3KmefHzwKGeatTdsgck+1mwnCDJncPWv7hTwMLGPUaY+Yww3K3YPihuyCUtUdV3fer2VHVAn++JdzerHiLI/86T8gHiLAi/anFFh6i2kMMVxqzREh+62n34MrgdMqbSFQb0V4Dhm45FVJH43uuEaoe3OJPtyvj1HbcSR4VEVgGkDeced8aAK+Dg==',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:58:33 CEST 2007',
+ updateDate: 'Wed Apr 25 10:58:33 CEST 2007',
+ accessDate: 'Wed Apr 25 10:58:33 CEST 2007'
+ }
+ }
+ },
+ 'd5f700b9c3367c39551ea49e00a9ab20dae09dd79d46047b983fc7c4bfaa050d': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:06:54 CET 2007',
+ updateDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:23 CET 2009',
+ currentVersion: 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf',
+ versions: {
+ '12bd9887eb84b99ad40c1e413cccaa9ffd4deed340c71fe53610088faff349bd': {
+ header: '####',
+ data: 'MiAIw+S6GDmLLMcGtkl+wveV7dZAFrL1zGZh/FPvG4kpOBbnyaolRynNrL1yeUbEp4gLL2cK2BGYiVc9196PMOvKPHR5Rqp6GlT6h4RUJ+nFFF5/3LNGzQtJbiY0rrYKptqyPBC8mhlqtdK7sQkQonj5LPhKeCX6AyE3juBPEuFYhvTv9a/iRPub7BdlAocz+bb8ObpbVHnNvbGhiRpx9MpUg44JRxLQYhtDUMi2UFtURidKaK0k2lP81ckPDCgVgxy65FjCq05vSaCW0hanNrIwl+zAgi+3ChriqmflvsZYC7TQzUBPXrAQ8bKmzppZWlArIOppRF7+paWrHA3Qcz4uO5Sw3DvMwbgl+XINnmkE/EbA6VJOjrWYJjsibvbCw6vNr4q1A4Yxwy0a7EXbjFiwpEr+jMUhsq8+d0DxP3tQTusV0l9wcT2OWrDRKdjDUXLQOV9BVw==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:27:40 CET 2007',
+ updateDate: 'Wed Mar 14 17:27:40 CET 2007',
+ accessDate: 'Wed Mar 14 19:00:21 CET 2007'
+ },
+ '35af99615d1be9d9841b4a37488fde9aac291c73c8c3aaa570cd05b3fd0baf5d': {
+ header: '####',
+ data: 'lv0pIfnhZZ6ktahFGl3AgAfdcveIcUyAh9x0iVOCzmQ9VjelBztlvxZEo+uByaFh1ptM+eqOFT/Vk9IKhNjRWTXrDXioP7oZ8IZ1kLfk/XuMFH9AgYzm3H1T/yLq5lg1WqqZ+OfO9m37Z4kbTjK9+adIAJ3TwsMxIDpIHYz+qbznjJocubYCbi+DC+4wo6qu5C44gf8n5QF8DOCGaBCyamxFvkqrSMo/Y+3SG3yt98MSgeMScGESuwKKGDHZX0v3ZXvl4UFbxywUtdbipDv4PAlzh0aadMsGqYwO8bPKEUElCWBXd6kASugaqiJaZFtb02EnC+nncv33ZSx+WyJqwKIBk/Kpd3/YDJnX9t3QU60j0YKf0my9oX1746F5u0XGX1DNRaw/1g95zRHoMu6j2cSTTX7CJglzIlTU8kglSO1LOasxm3Gt8iT+8+Lhh4Dw86ugqHXl',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:09:07 CET 2007',
+ updateDate: 'Wed Mar 14 16:09:07 CET 2007',
+ accessDate: 'Wed Mar 14 16:39:40 CET 2007'
+ },
+ '7cc6c6f2eccd8bdefddca21a59669655d7515f440b025144b9ba6b18472cf189': {
+ header: '####',
+ data: '3W8FqWzBVaEbMZRukwXcm03WbvITt8WVKKuJlcSszN0dCJEsIZ9vLAiDp6dfsFF4PEPcSkiy9Ww4FiBYSg5OLW6snRNdA7Wo62dJ3lqn8TjBzv/Rt+khf9mj/WwJZZ4wum+qdwTRPyaoZcAWgA6PAPPVp85iDBP8UBdiFOs+y5kz9GiB3psvOvqC9LZ/RyK3J+H7ierfWecnbqB9LT5Yuhfi8SO/gw+5vve6z1v8sVcexI0o8gk97rDV1W2gZz2WNtO7K5+233Z7aZlzouEbDZEOGG+zEYh6SctWCspgUATElf8vZ29fABsk3uZQO2tnBvINChs6jCRxnbmnjb2Y9R8u2QRtHjjvRro9E+zhQf3laJc0G0ZJp1zN0wwKx+sL7uM6kG1aszNJkzpykR/Uz8bKvoOfG9vkz9+4Pczh5xR+k9rCE8nbu6Yt4EMiUfdfjZJHAhST',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:01:05 CET 2007',
+ updateDate: 'Wed Mar 14 19:01:05 CET 2007',
+ accessDate: 'Tue Apr 17 19:20:33 CEST 2007'
+ },
+ '95ef5754f9a4514e5bf883436d60c38c3cbb15c3f5452d512a05839ce20125ca': {
+ header: '####',
+ data: 'Rko0V7wG9GEmH9pZtXSfxKGDLRhZr65ef/DjkwhsPoYfLryET/ViMjcZcM2blyiLKOxjiS/avGGcXUmInz2AyD5dAFTGge3qAZ3QtxTcNn/fvfJeN+JyGJPIsTIQ7P+jd0uJAb3vPuymISGJluTsP0MZ8zxahSSRUV/VIYwm10tiMVvWEq0+8FynKfWDqJ1eU4pnI47CAdN9CuWhxi12RkMBYgiUzNzTh/tbPTFMc7DIyRfR+si6TuPS3PmtnKt4FMFAX3FznGBCNsonUFf/n7Zy+EYEU/B8wJO+18mqbui5YvmPCPPKiW/pfVuaWarF7zcIcthYoKQfTaCaulO0VRtTA+Wg2LtJv+QcWWWTiY2A9FC/PppLZ8+nFDeng6LqJYKoGnn6qwtSVH38s3Inzbs4r8mSOR099tqwfCnZc9zZHisdIbVm82H3gnqelPmc3IXb3nHb',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:17:20 CET 2007',
+ updateDate: 'Wed Mar 14 17:17:20 CET 2007',
+ accessDate: 'Wed Mar 14 17:22:06 CET 2007'
+ },
+ 'cc7ee01d38e4f1de010d2a235e3b76e838ca05fe70223b8358a5e41975bf2b7b': {
+ header: '####',
+ data: 'TJ5ClYK5JmZvEuNCA+/UeUJQ2rGXbPnFqWP31GAGXqhZmC0RuDNjl3sv0nFKmcdMa/BzvLSywJhkidoRhfKGwN8nZc8M0VpujFkpvdXgNsod6x+5LTMP67qCyvD67pkYMa7O+aosKi/ZWWnYBavZSdhyuWnU1wPxxk+wwcjjIrA5Tm5zTXM/68nLLnIWs2bQbUtcwHgLrBEUshG5oTUFGxrs8zYwodsYUuT1CVwODZrzMxvvbHfH6Lqt94m4hBF0oIrDCd1cSaXghS4PiZkJWQVxJNSsuYF/4PlPrV4ATZS3Jm+DqOxLOOnU2Xu1Qe9DxBppnXjs/WpohYuMV5YeD8iOJLXTQbFKhBJNSCoLp73QywWazuKkasC6cbBrTHYykEKXpt74iE6oKg67YrPkIZJ/jKEGnZ7wsY4ObeDTS7OUbHKxPHRM3ZrmB672R/8ktglg',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:06:54 CET 2007',
+ updateDate: 'Wed Mar 14 16:06:54 CET 2007',
+ accessDate: 'Wed Mar 14 16:06:54 CET 2007'
+ },
+ 'cf70cadd4ae3e7f658a705ff124ddb24de78083a57bfe4fe2855ae2be2fcf8cf': {
+ header: '####',
+ data: 'CiJDd/ShGw3rE0xCNZspkdH6hRzvSyaNiuQeMBI0NR1MReaa9uVMV6Ymj+BWVQ8FaOziQ94aolsWre51EKwDWC1otdovPXWHxBXBBI/Y5A4dyQisBeR5E456juUwDtLKX5En4iIuOL14IGt+keUtb5JyfBGuTTA+EnohYzvDxu9MDh/7nzCcWzUxh2zHEBSyowfOwJhx7G2xEvbBgTg+TkejMudbq9k3Owebe9QNdhU9rsY1UMxjL8+HgJmgyo0C0SA91tZXBB3i5ePvg++ze/SW/r+XO/nnVzcEwCJE2UWAL+vNh8tUm+sEbWaqyKwjHNSquxV4cYOG2Lzo45Wp/vZwiUR/8MK9THf0FO1mn3QCd/37AMMneI1Gqk0TNwNtoQKgLVBNhhgX7dIVpRxB2iiSBYyUK6N9LlFahW2QVDS7kdnKH3vk1cP50dj21E45jEhhd75v',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ updateDate: 'Tue Apr 17 19:23:41 CEST 2007',
+ accessDate: 'Mon Jan 19 16:10:23 CET 2009'
+ },
+ 'd65b23008b22e5000726db3fd22b074b08553fe82245c3526f708b8d89f70963': {
+ header: '####',
+ data: '0y9WhoXwZSfzfxuql8LBc5/RiclPKQxcBYjcdGv7v6B+WuGrB6uu6d8pjNoUtsZnFv/25sefW3ggVgDuI5iZNg2lBQVIwgcvK5jPM5foit49d3RSWl74XdHY2XqykRNDbboKAiNfro+abo/YYQXjkhNBOC0dWSUUw+HmgK/Bm5NmJD4fDTV7OYFsvX4ExjnX9pktaB6aiLZWN1cZruW3Lsszx/ryHpDtcPrmK2hgLQ4FjRSXunbqXKJLOADQiMbGZ8DKZchB5NcEWlE3AfL6ybJzTyr4jXuS7A9PyitxYNKFHAHpJEhxGkyuhUE66QMt1n9NKzkNx6yhhGdIUF2zVGsBUb/pRrL2gt0X2lsZ+CnWFu4jRAeSi3KfK4VrvnoYkVlJImxPiLrzJAvqkuA6TyQRpJ4yFVJ0dgxBoxZVSN1fp9Yvkph+Os8LZscJtpYPPwVDlCnC',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:22:08 CEST 2007',
+ updateDate: 'Tue Apr 17 19:22:08 CEST 2007',
+ accessDate: 'Tue Apr 17 19:22:08 CEST 2007'
+ }
+ }
+ },
+ 'd620764a656bfd4e1d3758500d5db72e460a0cf729d56ed1a7755b5725c50045': {
+ data: '+iiHiN91FfHKOXC8Z/tg+YynPECa5sgYGGofcoJeXt3FAAkAFu3NsLuwjYIaddJiB3MIxFccrCrB5eDDL0SzOS+j63GcoMCeeiXss9YfVunA4RQTTktiU1BknPYfsfHj8EOPDSVHkPFs7KhAnBlgyaDiQPjYko5Np1H2i7F7pRmfC8W5LGdisaqxFDa+1ghu8K6a54QIpbfOmolQU3w7T5qiOdoZv8GLDDoORvMMb4P09IzXpk/yDEZe1GJ4g1a9t+lHAhiKSvdnZf+MhK0jvs6R6ALlmO84lRP34DmT/35Fr5C7D6EJl0OxXkWgYWelTlfU4b8+SStYP5LPYeD38fodSmObpKmpp653T1v2yaTybI1hojgLbH2DuA5VcQAM5JHMjoSy6s76mf2AZZeRnej1dqdvIOTf1Q6CR+ZNIqnkukrtGq/6elF3eZZh1Ln1EZDiTzsMxUHBngtiRmRDofqRSJUGbEAjw90dBoiaIO/WwLAy4cTec0nJxwYd5M7nchEly8Cb+zz7naP+vEGEAWq991u9NFZhrw7WgNgHnG0E3km+X+SYvv0i2MkqjYs6ItDkBNyi0Udnc4CqfWuKa9q04t8mZiy49LU34Ho4/ijuez3rdOeCO/oIwkRkLZYfFO6IxO56tAI3d6iJqmXY+DX0YUZrJ6FT7bDsUj0umV1htuj/uEgQZyOnKOyA8cSjOTMRIkodI12HrtdrIA966BDznsKW4F7f31VaSxI5ezHsdiYEsTqwaZlFQMsjfZX62EvDLJksJTe3JG15BNgsDUUh1mqIDCmVswFTpUTTb+50ap56c/uERSET0iXP8mb4hKwJkmngrBEir3btuMEMS0xSFQ2jTRjlnWRQr9eZT2biarzgEhKHyu2qCUtsUj7TiieQJY09EXCP3g3Da+61nBMoAwi/VqTI6vQaLGtuDrA2+VYGc8x1SiahmAkRPpQS+5N9qPvxxFRbKforMOvmeboFVxdKesub7BHIXQsSOKsHFZnFHswa/oLBITomp3ewfp125RjBUf1C3hMBNg/tmE5pgLqPfQqWK7IOnfdyt0jc391XWb6H3CVcgC8DcPKJ68o7DBucg9xTNwlIxBTafupsBa9JUkBigqYOW8729lNjj/QTvTUaCxWub9SDT6/y1wQUI1wyyg+EaR0fHqumMhIMbuvIPd/SvKMmZ4TXtBc1U3H3IGbkqIfx0f5rI6AuNMD7/pXTAy2Ot1ZBohnQmEotXRvDwxPMqBvPU74t3USTrysyXfJqeFtHi8GTR5X0m/PYQKWCCHgKvjw3d1CJk7tTe3iV2ulk5cnO7tOydTMJFgPuT2oyDDDTp5jYJPRE0OzZcpAzvRSjELfJ111sFBOEzTqtBUHA/E4BnTIM13md0ZaMr33E7ii8rS7vaKrQAI5moonAtAEOVbx/ZrcZ3kGzHpRCISeteHgnM4I90x391HqDkc1A7b+iDQF8OY0H/0as/3gaVaqs5jsuhIByj0+KmoXsdq3ZBhEQRW151QDCdMKdulNUxbKTYV/t92z3slU6lO8fiy+ON/6sTtS6jgnM+oCLxTfpfBdz0uKG7jiSOyunj27QxNjLyu1nF2+mAcDhtMN18QkJGLXKYv39kx7ny1H74i5rba32/QEAFl5eLJNIQbJZfZG3HzKMVS19ZGwgsYNqV1G52x5+bZUTR8YcrLWmPTJ322UxlhTmyjQv+fVCnpksBtjLGntsGloemFF5YVlcl1AfyHb+KlXiAZn+8vpfVVBddFFMeehokzYE1G8Doa/3huhqdtC9qvAtpP54G2p3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:36:20 CET 2007',
+ updateDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:28 CET 2009',
+ currentVersion: '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130',
+ versions: {
+ '0bea892da673bf4b3d3e4e97cd3e1645eb177a8423dc761583b876c5ffb1e2ca': {
+ header: '####',
+ data: 'BmZz8j6Khuz7Q11xPA5zSECcqn7BOcMtLx8AmX2iE4OrIwKWcZ+u4B5kCBxtFPRZWLdWcxAF8VfaedkHx5jxPNeWNIa7NEXXcFLYQv9lwUaxmtqodYtVapAg7N+onw28UnV1vB/h7ll26u263jWYohtd5eMnXhEjIEbrQYpf84jQYlpMKjUDhsVQeZvTI/KfiXa6O38ygO9R+xlq8xKgPPX2bkXfPJiyzlA+GoLSORc0tdqseGGOK4BFyp1V/KRUQ/7uQmGs1yNWt/ijaQtJXpWkWXmjHyTjXsi0z+1s0KH8TwSOfu8yjVshMyIyEDd+EsmZeK0QwMCm96v311cRhMgAkQOqL8xc2uRpGygtTkV2frthF237GOV5vwO9IoMZQFlvKZreV5mPPPBeqfP+o4QRpdnJRRCaP8Ds/MmzGBqE13ntwmo1UVX1k408ZtMCO7h1eQVTgCZ/Y2RD',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:51:02 CET 2007',
+ updateDate: 'Wed Mar 14 16:51:02 CET 2007',
+ accessDate: 'Wed Mar 14 16:51:02 CET 2007'
+ },
+ '335e2fc3f76b3db69d7575194a8313bc3ad031d441b6f2f81cecba6d3d630130': {
+ header: '####',
+ data: '++u0MEaILPK8riF0UzCnb+MnC51GYcdqCFRKOP7XYt5QvzWtxhDMOvq8ugCDF8G9sYPAoBLiCxFcuCtnkG4fp563VeEeC/dRnArzMDvjILYKAETgpnLQAfyIR+D8RfUkCbr+aOJ4XEKcy9a240OQJFDT0whoTKuX/6XVzVM/D7F0r+hJiOD1ELsVEi/+U+dXXO/VDxoyjFxfa1+M+Ygk8ewecX4nVqwOiFWHNK2lXW90inip0p8yqDsADx0KhE2tjARWVsjoNdf5RSUOYr0Sb0syyjBMi7oF4jpbLvHpu9fe8vpIcve+aSA/MF0Acxh0/gToDcO8ER3K4wcJgNPIs9lXiSrmuklK7kmS+uhz/rWCtZZH/OB/ov5sez5H51EYLmSNQbx5wZGZhtJWNN+AkJobg/Nt4XKRTe98CutbeiiYUGPxQvwG431Erg4y/q216n55FmCBIHZcUsa6Hk7ezF66c52EuAnVEkn7TZLl7vvym+sv9lKev31xpAGwX5Gy0tx2A7cSE55ZoyqOS9kf1s5Kwprx6RSBzfy7sffLSWHxyOSBnd7B1MNZglVSsbB1r4gMgZdYG//MZ/3IhTFbUqqw2xXHzTvBPA2Hl96g5Xzx0dVx2wHWcPcTSH23VrLscQCwyiDVINwmIzyG4CVSW/6gzA5VM4QYOrUDX2ZA5ligkZpWs0HTqmCB4SoqYJUpafaF2sEtCWHUjuVdw+rQiTBCcRTr8f1Vah2q2xbXMedLCRS3Vq4vlT0a/3wGgVD05CsAom31ZzmHQm94hZrx3FTPenhxLtTOHtDYXnbzYWufWEBSJs6VNtG9F5Md63NZvzEZiggfxTREDRZ7I9MBOPhrxz/3tAo+xInwvLXOEnTNOHVATm9u50kDs1qkJgqiXlxi9pZKmrTu4BeXS8cOxJ8O+Yb0Nh9bExfw+CC8X5xiWE58OwalxY2qlvuoR6mOqdcd+L7YPbGq+hJ/7WgJlrvtQe8IjGF1sJg6jfO8ZeGaPMF5NnbQVxGAq39g00on/z6dW0BLZyA6uglv99si8aRLpMk=',
+ version: '0.2',
+ creationDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ updateDate: 'Mon Jul 09 15:10:15 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:28 CET 2009'
+ },
+ '63760358c7f5783d11fd769c78ca3f1ce787113368743655ade89bfa67d0d30a': {
+ header: '####',
+ data: '7lG/UvX5KjLbN+OrHbDeqXmweYeOL+0p3/UoLi2K93mCYdwsvx8mg+zghxwg5ITKPiZ9D/QWIShqiPpl+dvQJGWgs9EcP5W7k32CS2RNFaZ7U820rSpahHP561HDcBU1++5wHWszLnqFFiCuDja3OU90dsCTLI3g0igFgqpaRbjLcRTddI/1N48xNfV1YieC5Kei+jZ34zzrfKRn1f0F7mTkCqCSfygjnpRBgZyo9BfJ9rHULBvplvpslUUfFTShkLnCx0UbWPXog7DIZUCOwvPr3KJvmcZtCJp/1nW7gm0E5PaueJF10+ZlB6pKvueu+5yEgVmVu/lctmPX/UwTYZDgY5VWSWS3C+JNAvV87ZQKKmp8N6aMFMNOLCsOYL5hFN9uWGtMmvtgawqt7OhO9HukSUs8pDTgNeXoWyrorLM0cH2fa6a78GxNs3nCSUmqSQchJf5eWmASZgvI5xXmHXsNbuc4w5R9BaEPzyrrSAIa6r9D3rpFbUhMm+qPv9pZE2HF9liJVdWCBOSF8ZfCjsq5suyYz+YCsFHnwwpYmKAqJNXUMIhxkjgOTi5lNIsvS/iNSN9kdkeWINZk5iQFta34uJbGgjUhRy930ZGMBEV36T+Vb5tz50M6/MnlzAoUDeZAu54btKcrIpIq1Se+8zldwd6UKGq5nG+dMPk7CyKfZ5LkM065KGbgEJfHO651AMWp1sMAsbIAM6h1gVKbRjNyNwO+UK8eDpIX1nXHVj8bDVh96160cFbZj7htsUnXZh2AWuY6ahwdrGwYeSFoVAnd6xUF2oH+zFz2coLmLjD4Xm9IuQFsFO0U1Vo7EKUJHkPgIsXUT9He9tl8/K7UYQMXGgPTpercQFQ1ctFEqlPbFoVNO0j7Z9lmeSBcLdvY67CCbsoBDVJzj/wLRdBQStfeSUe7bEI6ff8+0gVkEFFACc48fWWA6NLLtvJkYjdojjA+C/Xf6EGNeXU/VENMJokB10EJUTueVWKHCLGI/JDBQBBB3HKX2VNFcEMJxES7Gfcbhysm5bdmltyRUJAIdXvw',
+ version: '0.2',
+ creationDate: 'Wed Mar 21 12:56:43 CET 2007',
+ updateDate: 'Wed Mar 21 12:56:43 CET 2007',
+ accessDate: 'Wed Apr 25 09:59:58 CEST 2007'
+ },
+ '6e0dbb3c582039d985e80e10d94f424a63f0cb5b2ffac6388fd806ef89c1da40': {
+ header: '####',
+ data: 'f5hBUeedsvb1VBTpmpQ+XgGbnuVDMVEAdbEN7ZLK5k++4Iuw7l52zX6AHCWUFMDRfT6joiD2DMj0O8B2g55SeOQIAtZb4PZnbf3+ZEqKMOOI7iYSfo2PctLbzzzztma8EUXYkg7sJKCuZuyXhkWZxikBqVQIp9WE/bhRxa/atnB0jJyttnDMdTAN8kxIizrHFfT25hSbcPI1cSzsmF2nLabO6hLlm7mdLZCOD6DSv9hMeOXgqXo7XdfLA4k8swnOA/85HZFmhaYjTyoDGsK8yoJny/xBbiaRij1HQcHkbG6k2QKcs96pjmiJPoCv2dmsU3Bh06l1O4OEXl/RL4qBGJBKsDW/TXy7Qqa5y6LCEnlFAfefTHVgzuEQjJ2qb/z//oIrmujt+8hEa8F7Jyn6+FGqMNRxDvIQn5Ty/CPUStS1lNL1PEb7TA3ChYkYvnuhNVq8HHf47neGMpUwC5ppk5Zzb/5zEP0XH4XXkNbR5/TYjcb0Df3egNLSQLdO13CO3mKeoccmtfcmaFCtOLXWc2xNNcu09s+/QlZMuiu1TAzhWXU2CAXT7K794mTXHXjgGEaEe86Pj1nO1zHN7QhKDN92WMEdYasRAVDu/XYdzpsKJZ3POhNJp6pynotVBOkPk+2g04S8uujLVSIPZIwu7p3RmPQGGvfMviswhyPvSsPqND77j5msYOLCnXXjeXhOe0E7fIRpxPK1F6/N0R4tZCYNJe9Zo248XdqBvl5ZQWDC6aQH1E4djPK/08CS7/kAECqGqOCDPRvvMUNkGOnxsMx5eofr1YR7zWOZajr2GnfhA9fjrLv6KxXPVU0z702aS/Mfnf87ckGpOKA8/ssJiyZ4fzP6uN4pEb6wEta2DnnacUDd96nMvB9HvGCDoYZH646+n4oev+AnkYTy+ZRpmnsG6/3Z85iH3RwN6P2I3DWvGuN2e+1zQ2kaBMDms8qeXVY1+8qWr75ihizHCJr6E8Rd2Sw7xM0+6mKpu6gVGIi09auHg1+6Q6PlCr8Hy/pc4Exj9Hx1m14WKSF2SB1SYOnm',
+ version: '0.2',
+ creationDate: 'Sat May 19 11:26:44 CEST 2007',
+ updateDate: 'Sat May 19 11:26:44 CEST 2007',
+ accessDate: 'Mon Jul 09 15:08:39 CEST 2007'
+ },
+ '84f3b8571428014d04d7c05528af73c89cedf17e23b1f9541fe7060512f4c1a3': {
+ header: '####',
+ data: '2/zsq97zQBq8wE0oAC15HW5pbbzgokoDkLSEGniP1VL+sW3b+tXYOQV+VSFJo8ERNlCSoy679G7N8tPKgA+rO2/roGP/iKEuE38et9R6v9nhCPfo1vKt7XpvzJYow/qDwdStylXbfW9QN12Yx12r/nkPldVTXCYQDF0Vs0h/I1XMjbILpq1smbNXAUdn9I3W9o8KpREvac2H1ir2vYOzq9Ubhq4jggX/9s+FGm40f5MX/OM+lJGdRPCMG3rfWVeFeWEGWpmg0AXpV7eEuKH7sPrWy+QLXD1IwNE03QLhuOh0qEPsEi6kcCaZyLlCHYlzJ/hIAR1CBlCtGm+vqD+WRr0mGQtl81MMl6/BoW40dya/6aIKNOWfmYNgdfplknkVqxFsJnwVqjQJWfCzbW1KqBvMHx/7oPNjbMS0KKhd8ctOsTLSvq4zFI+mvR6BggwT8rwcfa66shJIaDDC',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:38:54 CET 2007',
+ updateDate: 'Wed Mar 14 16:38:54 CET 2007',
+ accessDate: 'Wed Mar 14 16:38:54 CET 2007'
+ },
+ 'a4218c7ece0287ebad7f3cdd6510f424245a4d7d42ceb083b664a4335bcb7690': {
+ header: '####',
+ data: 'hQ123ZhZ4AiXD25P/0Laq3MtRO2oSIrY+GoYe3UAiyEHc9HZDCvR+POEEaARXNyh+U6z8S12P1GvQbzo23ZCt5byhqC+UmbfF3Y4FikM7WmHaRPtWjv8JNf3X0iJ9a2IBLA1BlqgJolnVDtrLsFx+6rBIU9r8pI2jdcsw9w9feRbE9/0S0filh66azojT5RM1qLcIUVWGixROY6PALSnA9PCjA6IG5WUa/DX7DyRrosZ9V4ZheMlzlz8CgEKBTN/HREIbPrEocBOvmnbupIEpOvH3OXKDXf39KAGVBAU2IIkOrGyWfT12p9dK+Zf+MQUl4DDIdAbF81Lus+LQmqtQ1ieyV0nNiqFhPuglLvKRj7QZRFfHNyejkMTZQWjQhBdHRmfSxyEgmFrM17yVVz4cMis/44g3szHMgAAfFIc79wq09oNDEV+ZUMS2xyBCALjRmhedqYIMGRCAG15',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:36:20 CET 2007',
+ updateDate: 'Wed Mar 14 16:36:20 CET 2007',
+ accessDate: 'Wed Mar 14 16:38:12 CET 2007'
+ },
+ 'c6613ccf0c1c6b65798c6f35657a10d4c6033aa32204a90d9d0274783a1098ed': {
+ header: '####',
+ data: 'ATU61Uq3Fe24JAEauMRtY8vMjzaQcPtnt1fshTD4dGuptFH9XoZ4bMC4XKHI7JKbx1NUEbR2ySOj9K/NJuWEGZjRgZbNI/KtuxNedlm/7jEpHQx4ZfhXQ8OiUDd+2bB9g6V0Ck2T1gM4IyaZMJ1QfOlYmGGv8n4flhHC5kUzL2OIiAxNHvKQjdEOccnEsk25Gg6FveKHD6NqVunsiCqhxJ84VBNzHJscuCTRcbt6KwR1+dw7Y+nhTjdDFq9UidlxTO0BKYsqj9F4Kq1LXORkSyab7zKooFH5kNd8torb5UFto8dfI8/+DOVHMxNRh2aWSn3O9bzwi1PfYO1nky2O6OKR48Y65Hp1sm3Xj4AAVHWSGakYUSV5M5XxKKzvoKY6Qqhz8GhbkzM2FC0IKTEcmINMvzXdzKRTqBFg6i0t7Qo80i3sQSoju3/4CYRozI2RrF8W4f3/0XgJf21oUAdTXOmSePSZoqhdejXeNQAgb89v+ZextxA6NJNYqvrx1NjdKmWKJIU+o3AgPYj4UIwWHwVADHITKrIWl/SbOsGP5aERtSiLnC+xqfRUOpgfkAYLcytspouHxvQjgNY4I1U/2S1DThG/N2EzuPl7GLYQ+Y3RAvLObFbrV8S3DS6vXIkigxyJT++MotIKoPBq0xDq0ck6joyvwvg4jXUMKlJa8/LQewJlbH8Lszx7SwjynzEQUJcpCnmxixzSNfRzpzgEBQSiClEEqArYykew3rjz9lc9nkdXUCzz81WYsvk6rGJ6ZdDsfKsG9+kaybuLL8huE0ERhznKDJW44ehDGQLr0phO3CI8n/9Px0PhPeZ1hvoiiH8CFSW5f45ZrFaaQG8hNyzWCpCFoX0/dNsNPsAkOJnO4v0PvO0HDOif1JjgPjCS51vBzxu8gYhkWlPo2hZxHhnnrbhxeBUU9jhLAx+NmxxfTjIWkbtHtVjm3ea/D2nuL1YrZKmQ3Qs6GamKlh3WwkRWRAVU3+/mbSGOISxo0u5v8QSmh/IPIXltniaQgWweqGNnCLWluuTyhoqnqDo0II7q',
+ version: '0.2',
+ creationDate: 'Wed Apr 25 10:04:29 CEST 2007',
+ updateDate: 'Wed Apr 25 10:04:29 CEST 2007',
+ accessDate: 'Sat May 19 11:22:01 CEST 2007'
+ },
+ 'dd2b4cdeaedfc97c384f79c2878fca9a981efde6ebe212138db235e51b80c64a': {
+ header: '####',
+ data: 'd7ZpqQ4CTF00+/UnTvNnnkMXB2Ow/K9dys8V09Nedq4sgMUk08E1vqi9mdWbzNfRD7aV3blru8PfoRrxXRLTG/bjQ6xncecQoAJeUtSplKEO8fhuzGqbMqz47/y3aQDHBbygMAGV3wLgJO2Pv8p+8U/P3cEJisd9OqTNE+EYQz4eiq9dllMNUQjDY9aLHE8H0ny/5r9uohGNjXX/LfFMshjeS4rToCG5mzRaJPaRs1jkjzSntpF0RLxfU1acpJX4pNSuaLscdJ1lIwc17vygg6f3xexqvCeeFZBot1RwwbztZKbMfap4pRF5KoftD9bXJwoFMXigeMGLy0scpzsp1s8zBIwLhwUxEE0IBh7qeStg/3eRSW9slazuIR452O3Rysb+n/jWMyAhIOCSrnncjjH4XHbzV5GgT2d4f8jfBPmOT7l7C1ev41D3FGFxEb5TZGcJTaIW6ofLi5T5',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:52:12 CET 2007',
+ updateDate: 'Wed Mar 14 16:52:12 CET 2007',
+ accessDate: 'Wed Mar 21 12:16:29 CET 2007'
+ }
+ }
+ },
+ 'de13c0d036234c44214062bc0a89e5f127470c464333493a485729f43cdc26e4': {
+ data: 'ZYvHAVCnw96hB+0XxnBY6p+vwvup1BopHUeepu7yOOSdYNFFOFEvtCbxXXoyVaKZAeSd2Vd7YEwRP4TTJjjWNPapT0D65AFqM8x+0rEjhmVfQGZAS4L3QctzRAgBoR1qTr0iqI/46ETkNq6vHz9mPLHEL3MQ/zoh4Pp0T+uMsY5ptzuMPcG0YwajSm5J8XXV2V5ZBEANpgL91xjgh1I9LiKJa/Lv3R9HAZG1uuCvzqjA2LWYeH+6ZcSpadk/UPxDw9c78FUnSNbHAcjuYZ/yI3v5SaZTjEzsB1MtAh6AFiHtvKIMWpqoOs7XQPhz1xXPoGZ7VR64A+/bN2h+Uqn49bQrKjTRGegqkEWFcBwhFH/ZkYfSHCGmZQTVqOakqyofJ22tS0ief45gYaO54YvIliTNTY7SZMRCEhUzz6dz8ENqP7FxhUVcQRbBr0JTmaf6DAwu86iDgkvcp1cY2trnUmlvrgz2GW6TgXoFjFlchUkHIByFeIJ02olfJg4zP8PzgYp2zhwmXL8iXHXnwzuP9bQKq5j8o+UhR11zn4MFvWQyD1UEplK6vphMdS8iXDViLrOwuMz1XUf7RxNdW0gqXwx+qLU+CeypyWLMIlgTlOr1pBqD/S5Jx+Gbn5GHQViuFZHJUjJsU0xel001KjB2Wf1Y15OSdLZ5l0tn/4HYKmZLufTYpub0xrss5r3Z72RYz3wvAWFXzkxWa+oBiRQiF6+ix8DBPTc3tm+ORnQBYcV/VNVRziimV3MFSsD1nHgIF1zu+eXIKE7/b3lzY19KpvtiBio94dejWoA/WO7KXWv2sHH0JoZnRh6lzu0HRFgYqVm/052nCGVA6XSfrFtfIupxdBs22C9wrwC5/Rwanf1S8BQIXpm25P4dv9Y9cS6c2/DUHcle4tsUJlqC+LpRGKXRdolFkiL9r01V09Kev/K2oXaWGYmBLbRfIyvEHyHNeNXv5fnaZ3pTlIwXjJ9K9yKA/1AKAsAEuKlM3N5ep9pfyuyfOWj1I6RvBwVqKvcBZtYJ4u8n9jrxiyq3ZZ35eB62D+ceOAD2s5+LL2IylYjiJA1OO2qpu4x9rt1NHXM6LYJAruBnUrJ0Ylqz/ElcJn/lXAzY6RLqVcZ+tuV580AUkFiaXFEDcqdJbbzh0R15g9DtaeiQZd1PG0a8Xblj9aMQoRDRJeksw1GWO7TfrJX1Cu4k+sgARWRzZ0DvB0SJAxPcmhg2iBByn2ESlcxPvMOpzuJI11BUQsZZ7dcynubeMvdqBeKsC6HMcm+8DLEUPmzsC3HIfARlNbt1fOrGJNuKaLvF1AAdwllELoPf3lQ6EVZI120=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:20:58 CET 2007',
+ updateDate: 'Wed Mar 14 16:47:01 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:06 CET 2009',
+ currentVersion: '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28',
+ versions: {
+ '201725aba7b4dd93531e40ee08eb8156e3aecd3db4f11e54d4d88ed5508c72a2': {
+ header: '####',
+ data: '4ndloDtoW1Mhat41ZlW+nN+WkdEriCn/z/oclyBFQSljJRlMwUFvzE/OCVYc2fQx1D1GBedY/O13v+SCAiJXUrr0dgrMDOfmYy7ZtNo0hYshjaYQucJovt7UQLeFAuLO6rNK9CrsYA/AWoiT878z2iCYCqVq41sL8juCm9n+d9aR0eyjXAKj8QJzVz/uvdudoGQ5xL18x2yUZnemY5gQklYlm0u9zzCJ3rLOENnnAggFnSJ0oysNjB2UwQY6P53bqXzF8E+u6Rv3OoIbmCIZMaoK1G5ivnWHwhLzp9UVdIj8ipfLsTJnGMk+aZ3nnEJ7wQCaaLy/lY2RYmSeUTTZt2ImK4ZLrSxRC21QkD+juyIiaEBJdhP8UOfcqE8Hw+etc/Cl0QgBtv9AgXD4BiZs3HUTXsV/PhIzP+6TGyr3/A2kt8dv33V7Gh2Ba+28wtsG/+HwCMk=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:45:40 CET 2007',
+ updateDate: 'Wed Mar 14 16:45:40 CET 2007',
+ accessDate: 'Wed Mar 14 16:45:40 CET 2007'
+ },
+ '59b84967035465bdf84c8aab3c43aec6cf60e1e2857e978b205a2cfda7546f28': {
+ header: '####',
+ data: 'eSAwxBi9CLckMV3o9PxBjVZZ47g2AOIsbPt8QMPta7U+6KKUm58cXHV7BDfRkbin3JYQJGYfu4HYHmayGt4IcX4RD3riftxnG3UFNqG4LQQ8+fwA3xTMBisnUSq0JYc/PKdBKzxH9x8moSqZC/cgFWe90p0PxdY13otjd1qvDL2ALAgY/uEDboTcLTbSEhpGIYQHtQ1ZjDG+KXI8J7atuMvS0KFreNUm9+uMZT0yCXwNpGy+ez2+ZDXTEjZUKaFPLI7g/vyySn6VMXmlqJftGXZ+fW5UWGaxb7WFa1hh/nI2okPuRlUQh50xXQJXVvanw1ATJbN1PRfYEfvQKLlAAwYuoB/qL0y0vU+3OktAbgBvwt9prs3IsqjwMeaejVTo3Yj9pQPJ14a+6lxQZQRFUaLePIPdYvq9NRM7chkNYminW0JN6umi6bvJ4KKTyjAglBQ6X4s=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:47:01 CET 2007',
+ updateDate: 'Wed Mar 14 16:47:01 CET 2007',
+ accessDate: 'Mon Jan 19 16:10:06 CET 2009'
+ },
+ 'c7398bb27021058c9965a332d678b0070287b8ad12694bc8732346e6d84fe9a9': {
+ header: '####',
+ data: 'L+wk8k9ejeUeVz0offdItFpy8drMl1hi0FODBMKlPIAmEcNjnHU/IktOlyLrK0YHj66DaplXw2EyRkJNcMIbfACUtavxhWBH9VTftOPepsbsrU19aP6Xk7R1pr1sC76w1TgKCjE6IyBnK5qk1oHqcGv71GJLMmiqGivKyYOXQ45SH9tbHC4GUrg0YxoAYRwXqg+SlwRHpSZkX55NzPCEZn9eatGKCznTZs7pg0uBoM546fOIEBMgGndNk6gnsAH7At8yYxDMnkGHUctsSExL1O+W3bDDDx7D3uPkkjtd9se0exPru0fmsfcKPrcRkx8b8MAdgcylOtMdYvSudPdR6foSIqKMqktH35QlH6Rr5E/ire3O632QlmCieKDoPk/cB/qL3gKedxT1NxtC7SNR3aumKBAKOBDTVSjWWq3sIImQPZz+RUdRajeqkryNDVVPLFyjdC0=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 16:20:58 CET 2007',
+ updateDate: 'Wed Mar 14 16:20:58 CET 2007',
+ accessDate: 'Wed Mar 14 16:43:46 CET 2007'
+ }
+ }
+ },
+ 'eeda70e0392261967bda71c3764da78989c45bbd2bb7be6b941b90f81d9b81b5': {
+ data: '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',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 13:35:58 CET 2007',
+ updateDate: 'Thu May 10 15:01:21 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:54 CET 2009',
+ currentVersion: 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec',
+ versions: {
+ '157b5933272bb6b8a70bbabb7fa0369eb2660f7f0848dcc653f592f5afd4f2a4': {
+ header: '####',
+ data: 'z8BUTeAbrs5GeJ+SxaV9ceaAoqxtW/touC8xhjkEqbG6+IgMrfuz6ABRn+vwiN1/Vmfw/tyad4kB2SyzKgaYPH7rXyBir1mzJi73/oHsXv5wWNhEePmjZginGGcWQ0P4AnrAoxlaI8tXo3fbsz8e40x1b56N5J6zIdvX3eewgIMU+J+iomZVPDQq5DNu0aGUL1xs797FNm4vLQbVRF+mzrZlT4XZNzOr/W/Br4vG/Ureoq1QRjAjj+8HRt7ojmzrpDX3RtmSbWqUPQqx/KpFGqVUNw0zs09MomVIYilRawe/zegW2KZKK4rmqoUm+mnWQTf/I31FYO2N8dLrI7OV71EWlVN4FSO2A7NRUd92uVxHzItMQPS3CSQ57FYAC+WhJh7k+/ikJumVSf18pZRSRaEeKPxbJZFJqrWsWk+SsqBIJ4EklAnBBU7zLmMVe3GO/ml3',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 13:35:58 CET 2007',
+ updateDate: 'Wed Mar 14 13:35:58 CET 2007',
+ accessDate: 'Wed Mar 14 13:35:58 CET 2007'
+ },
+ '1835468626573e6189e5302f6f354628f49900efe08adc931990d1c11fd522ef': {
+ header: '####',
+ data: 'Bv0je7USknogpb1ng86CEx6GbHlysuN3e5Iy43kg1iN83AgRm0Hp6/yMivQe/mEmQb+67cjHfKKrznAESYzY8uv3b+ystxoIaQL7tKJ5HYu2NUVvZxRC+PE7AkBhc+O28OzpZEHXXz62uZFsjRDw2hC/KP1XfYW+Deuulnpz6sgjuyWIYXF2486DzaycCqX0NmYXKE7oXAthOlbo+Zsm8Y5MWh5ploJFrzhAm0CCzjsGSa7NBOBWU2o6vN0NFMcOG2pdjZGWpWo1QQ5G9tx9UvM5pTamwcg5TOr4yOd16JmYTDjK2Fd5mdUuG3zIxFR8StIKI/Sd1ah8U+DGbNlVYAVb5OREJxQxVv6I5dxGC43CGWbpx3fB5wuFT3Jek6tv+LgBJaI9Ika79NFJQrLVMFbQgD0qU8YgCmLbxIJ4gxMBUgTN+v6PraIDHleYlpW3KVIiNxv2Ztc=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:24:49 CET 2007',
+ updateDate: 'Wed Mar 14 19:24:49 CET 2007',
+ accessDate: 'Wed Mar 14 19:24:49 CET 2007'
+ },
+ '47f73115ba2079f4b3703f502e3455498900a21941625c25d52ebb7da31055f7': {
+ header: '####',
+ data: 'pK+wAHWg4IJcixnFodLQ5EH+SFQIOMOrthx52u21WZ1ziRWJLSYGwA8CNNK8/welwzPHOPWu2El+zE6cwLHrzmL8EARLvvJ2fEK11ZIvF2C3R06uNrA7QFZr7iu6t67osrpfljqbjKQrMECUCUDrBywRvlpaeIlThfA3XByezK2HtbyHD1/xnyQSenUFu/6Zq1EkVdm9iCkbej2KxZSxA6qMl1WcnplBdOqBSmeGGJ0+Ikn3LZ7t4ztqflsug7QYyQlrmI+d0UB8MFWpf6jYjZQwf1rMH5XHFvrWUCi5IbFNJBUPF3n3IfUlrnjUSBEcW3tmodJa16/biK9/iKqh5ImlnpbQgK7CStgQ8ByJqddJre1idCiK/dyR1z+IXHTu4qm24cJeGUk7la4WMG2O5U/otFbXG5wTVgbLsxfXlE6fzxHAzvEftEE1ZPNOBpRZ+LVYEHKFESIz',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:41:15 CET 2007',
+ updateDate: 'Wed Mar 14 17:41:15 CET 2007',
+ accessDate: 'Wed Mar 14 17:41:15 CET 2007'
+ },
+ '6564169ac5bce1a632c602c51e9e5d637bfd4e87c1fa276e2cf65f39405fc4c9': {
+ header: '####',
+ data: 'fs5hydWDsT/FxWTb57K6zYKwVF310zjHHHtRS/AeBN8XZqTcirhV9oxJW6G6TdDkD7nQfWf53AbsivXn46Tx7oarzoU4R+1mz94TRCkEe5X2X7Wa3HbTj38+QwbkomF7np4MUkVc06aRPqkUE5hvSDbGn4SyKCjo/AnGhuW/QJIqnWVj70tf7CNTb+GR/y41JhJd7yk6U3cIP6Imik+DAvM5pE0KqxGLfLs4c1ChuTFNHfiQbYjs3tANqJCO185t4S8UIY5VxMRcnqgRoloFK3uFACIXoyDGG3FjILgxRCw2ePFsrm2Jtxv+JX4BsM+KDk67OsN91rjQnK5vBP72SzSge4EDCKJXYKdA8KJGYNwRIzk5d5ycbZgW4YCizVw8v7sLMn60v7YrDfBwXAJvvlTP1chA7HoE+WALqXkfBW29AOCNodE3eTXbI7iWz3vcWOCPvSm3hho=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 19:25:28 CET 2007',
+ updateDate: 'Wed Mar 14 19:25:28 CET 2007',
+ accessDate: 'Thu May 10 15:00:47 CEST 2007'
+ },
+ '7674ea33b650e84f9a461a91928bfc259de5549ce905339fc3b23623c6cfd09e': {
+ header: '####',
+ data: 'D7mLcDpylLnklOtIw/kvYX0M+CR6Si2t8CB9bTT3ZR+bTpXP88OtI19g1k9iPEUPdgbtFKPVw4oNmynP3x+pc8R/zzn4v697SvVtQxdF39Jmry5dnB4SMx6oRkuaISs0nxvTrHJe8U+s5ehzvQ2WWxWZ+LaoBWaYR7slgUFKLdJFyWEalPwMPVu//DoLZeWg19n2C/0Sy8u0DGdYHJVserWrQqxxg0h0m0x1wuKhF7IGvqgyJ31T5w00nMHNZbs89cUuqB/2doMgoUD9BqV7F/53AveuBDcdCc6jlEe8NOdoUyMuhwwwTyKONfjY5e5Cu5W9I36o7GpeKlckoKrTIWFO+NLG8XZvP/f2WJCsIOrCk/LI3C+bxBP+bK4tHRH13iXLeJYUlMK4ibcf8WI445qNoggJSbZzGr7Dav23KZWPcxzRxhI2u6j25/kKGnu4kcMB8ke5N+4=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 14:46:36 CET 2007',
+ updateDate: 'Wed Mar 14 14:46:36 CET 2007',
+ accessDate: 'Wed Mar 14 17:40:01 CET 2007'
+ },
+ 'b454ac54afb60c9bb6a1791843aaefadd8483630611c2bbd0ea37658985c62ec': {
+ header: '####',
+ data: 'u9HEcfobxZhG9BY3dVG68ZUYkREFcZ4q1o/xWyt3qje3icA+Nu9yCrZip/4fqe1daUX/MHyzUQdulIfjSwATjj3vvDSPjuGvrtx8oUjJ/K6GFsL366ozi45LkqkOaH02/nVrb+ik2HWIgcne/OzNrwf1mWLJoBF+8ZwQ44xqQK7ikG1mblNWWbZFFQE1B0QPmE/I/1ovm2hAr1ZsNj1l+N96hwGsdsdVFTzn+S7Sg8GTbxEFAxDQkBYEw1k/R8i9EIBndPoDZCebr8vP+c8qSEk/YmBXJ1MGVVvic0/Utn67iNLz9aBnv2z31DvvBj8bIwOxQpB+tom5Ivwe84tFkwwvpxFqYccrEg4bbMcevUo67TBVe+Lb2wzcK0zOr7iHhswbXaLzzOEQ6uF/v2ibTbATP2zNq09AIJjynoSDmrisGHsBrHgeXjiDspc9U70PVC83EsjPRwA=',
+ version: '0.2',
+ creationDate: 'Thu May 10 15:01:21 CEST 2007',
+ updateDate: 'Thu May 10 15:01:21 CEST 2007',
+ accessDate: 'Mon Jan 19 16:09:54 CET 2009'
+ },
+ 'e699fa287c2de3d483144b48064a47cd0bc56a436431ce23b48cb8d8c42ce851': {
+ header: '####',
+ data: 'hVD8NOt8g/DIe48JbUUo77e2hMf2UBN6ah23PrIzGTpq0LifC2K/0/s0yeL/PHUOncdT56NccKpF8Fp6EWJqDKoKZPWASuB1vHCEkdbcxlqzqo98VS3A7p2JFwQzSv+5t6y909hhbxobXMCUfZ10HBqGo6TaFc6+pkYqQ/d7MEnj2NuAXC9X9TLLuZSrZ96NCKGr8YVKzxinxHdiF3TdRvIppFByXPlbZ3xiielEnYm6pu/GffW7Hkwd7Vou6jwyggxVqvoVtuAdiIy67l8GX0gQUGipFkvvrAkXfm0sgtWGQvpgDuV/bXq/L5vX/sFpWI2u066lMUOsJQmptNP/Nkp31+ZNk1nCcUIYDDa6vcOy/gRrOFcenPTUQjRkE95KPaCqYBSIWsjoFE0EIB+iBnBCTK3laBSC7pplOtuLCY1YJcJuOkzCVQCVXjhWrNJM77s7a5OyTuE=',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 17:43:29 CET 2007',
+ accessDate: 'Wed Mar 14 19:23:51 CET 2007'
+ }
+ }
+ },
+ 'f215d89bf4583c12f5ed4f4330f488dad3fffa448f4dc784f15ef135dda2c732': {
+ data: 'vxOgJv/v3pP8GFqbFLTcgtBqw8V3zhCN9rRXUuWAfatABtr3pySWvt74ITeGw+sDtApBsu+zTY/95BFVtK3y0QJkC5cjJYhLDwvMwpqa0lRfCXWSYmuEhbPETwkW1MN0kAEOMqsUD9cQCH9GDD4A17W89AoTG5Ce//X03YBG0cDjbotgENsWjQpK88LXABHBQAoTF0BPDjN+xai2QPCgN0l1IVpUzI87oZJS7x/4r6DjGTOgcc3+vtEujr+8dGNaq9xTEfAFs1kv6GMeT+R/VkIQLVO+vSxi2fd+954EAXQplt047+aZ3c0c78N6B+GhSi9DgNnbTLu6sl332Zdgo9R09uucS8nvRp3HcTzxriKpx0ZMDh9K9ig5NT9Z2H49pDjCJKTukDU7b2ktOEUNZt58s+uIlw1bMFY1TMETGAHbTq+hld8Szg8f7nJGDQF10kV2ykVEQ2oUBMC9y9VCLyYD0BWId6DUcTNXyI+MqAC4j8pp0NhURY8VSjtnV4Rlq+b48ahP/ifJdq+xrSiT9ykGqc/EyebC1uCTIZewk9MtIAndVYPckMIe0xQ2xhX6/m2bdNboVa3dnS5eKFdbd++un6FD+QAjgtcBkXQnwfptottZoghclKL5h5gPePCQL/66CLYy5+3xctfCG9u+VkH97JKL2hW+XZ/KuxLPFkIAYmbFKsNdIizfpbk5WJvoSzacpo1mwNjZ53zn9xhy/VkSIz3lGl83a6FyoHuR9VklyhTaKrj2JNWzjLaQPiR9Sv2eFNjLTivxtxLwKae5Tz14WU2QlXATC5xdcLeF9nK7yYVarcKlRsYkkvetrVpRiWUVfy9mZQIHOWJtY5AcptKso2Q0v4CuD1C/wV18DMDXzwMXeOq0cKxCsZOuWjO6RwWKzfeZnJ99S+EsFmdI/wxqiu9slJ0xXvgLvjiJhJ03qWwZV45peU1qmvKQrXS80QqLp3kUfRGLbZNOvkZbyf5OK96MA7lok8PuCZGg5jZHFX4B3vxSQ32P7VGSWO5CqHpF45YwtlONZKB0cuvKTRazZ+B2zJfwMYRQloj6sL5501oPqmjVtDg+0aoqKe5DmTf+fHV4FwAxQ8RuW7/BVL+lwf+zjtd31I/yrlDdb/Scs6yayLV026yuHxdQRl+ByogtrXbY4ViuU3NCkVrme7K7meRHnQdXyidhjzHdoJnRPa0IoI4VW3VwWNENRRNDTta2whOdIKsQYtscWBWZnQplRmDChGikERYQVCWejDNgvnbnGrlyQYPF0/vcv6PoDpIvh7Pze9y0MLBU8DnWqAhpdqHPNVdjdq51OKlSitUk5TSN9kxePe0KNFZueLjxZHUFIZ+SIkTxoCoaRWYMJIWvYkcT5S9Y/7NbdapuUaLZNGDc6tgD+LVYRRvGEdPWaOHb7G+qOmdtx8vYxZUqq5mtwnIBRzEllTJyKwwK/kOfAxiRjLxf7SOXsubPuA7bHR9fI5rROSR5rcU+nOfSV9Wf4wZkYBlSmQYqzQfmwl0UCiipJVa1DwYwLimgo2RqhI0M38gEH+mrknnevE8zlUIaEWzxoOnyWbtCecakXS2XvE9j64dswJ3bbeQ3fDQr1308x9qKSjFdDl3eNcJx2e9YwC7wZnTmHeHzRXnZwXsJXqMPDQV99wEDBr71BjlDjMx7vG9bOWrhsyJ37EOvO2X41Ij3j0X4MYpbNgxBFP6zJSu3gILrtqQRpQq6mQJ1bWHyCN1ge1zKNT9pG6rGTRPE9LqHROQuROpgFM1R+DqW4XnGOBYSOtznnsnj5fxfdpGeFq+v/ftvVuN5XsgX6dnT8R77iNUs86Iz2mkxLaQokkNzXl5o1rnQIse9+kcKVZ72mf5SG9s9DD7cZ7bOtmkuZCexJpieIosqLV8jc0IA',
+ version: '0.3',
+ creationDate: 'Wed Mar 14 17:39:39 CET 2007',
+ updateDate: 'Wed Feb 13 15:29:04 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:41 CET 2009',
+ currentVersion: '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74',
+ versions: {
+ '33ce5a03b6d36f59d0fbc9445dd01a515cb56eccc6d854cffbf8aa66f3e4a45f': {
+ header: '####',
+ data: 'pwMmqFOwpW/uSys3hm/AcoERF3eDj4dO+O5SdYsR2mJtmEfXcjhS9altLhVOsck0KMQJdxE3rNDFbduF35yVetXuQrrL+bSRlXMq03EXETyrRzIVhFEM4BjoCSS9nKGgixp04Ve9WSuwD4cXRmcN/L9kCJSCqflXqhkYkjAywQoj1KxHPdAqMaGRpEWioUIfX+NiWbO/qtOu/USAhHmWFXla6/A9kKQeU2d+P3zl9KF2Zm8qm8NXjPKmh2dkd70ATbdzxt9P3BafoRf/Ud8zLIVdQYTbv0pn6UMIiUDRK1ryvgfSY180zg4qkP5pBnxhEgOxbjT8JO6hCl8n2jUCRJLdUXHwgpeuHcKYDyZizc+p9Kbc4+d8K/2UEKgSR6gza6Cpw5TQbZQq+2LxWUoVb3HM3lTqBKUPM0FdY2/3twZm/1bI1uBMPnyp9x/JsQV+xOpu0ZulTA==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 17:39:39 CET 2007',
+ updateDate: 'Wed Mar 14 17:39:39 CET 2007',
+ accessDate: 'Tue Apr 17 19:09:44 CEST 2007'
+ },
+ '686ea579db132287e8e322194652ec57cba6e60274c00f734db7a0b36702c817': {
+ header: '####',
+ data: 'ilf8U30hSq2mqje9kZkKQAMiEFV0aptXrm8fOtoOR8pp36V29kXyUX6FEOh5eXSRr/jbqGytxKENJeAGxnsv5U+8GgbvlYaR4MPM8lbKcpAoBCc0+CCOiwnp4XCoXFCNttbTzfb6qgR7wqdK7YLnrvfzJieQqJukQZvtWtsVZB/Tis+5niomz8Ca8lo/FjFOIjAq6xtwrW4CS12+yZdTKNbj8e+HwoUcesF9RbCKQlpVHuwhZ/8ghdzDgjEE8z44rDepEv3Lx/aUi+67velLH3j+1crnxBUz7wP/dWzftwWgIxDkCR/vW63yY2Xebt77swDg8g1Qj5OJdYiAq231HKaZjxr10y88JI5HC1EvbbduDN6pknKUgM+qEdojpi2BmjK+9MtV7sVhJoWqwHG8q9z03kgGoFnWEb53HyMVes1n6HYfzwnw+idPFWGZJ4IB25WfJLfQuQ==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:12:39 CEST 2007',
+ updateDate: 'Tue Apr 17 19:12:39 CEST 2007',
+ accessDate: 'Wed Feb 13 15:27:04 CET 2008'
+ },
+ '6cc9ed382347f8ac5b5073f459428897d36cc9913947d003da874dfaee5a7b74': {
+ header: '####',
+ data: 'l18dnf2TRfinuu9KDraIo41yvG3mNFqiSCOkyMI6WZZD4RnF8R2Ob19fJ8zXv04eDx7TYyyGP1IlFWEdT3LBrOmmbtUmIvtYanIfKTkT6UGHNH2jh1HyHqJbpgIlr67mOm6Es/AgF44BiyJrk5R1y9tA90oeUQynMufiM2MFLpdalDYWEh+W7GV9WCmbBIU/soioTJ1ep2gvy4kJvTSrXENaxHevKfYwn8ucocvY+hjkWB4GWOR40qtaG06wWMLeRsrTBH1jBG9srzbBa4u2IQ0+NJjQrYdiu7nfu6Uyu7Ya/4bxV3Sukao91XvXSFIhcI2OuKl0njUshv6BDEfHwXIQuPtn7KaTx2uYl1pUeTv/tAFvf8Ng9OFNgK0siIMkeg1thFwRiGSmxjP0QZipDtcCekIxj2k=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 15:29:04 CET 2008',
+ updateDate: 'Wed Feb 13 15:29:04 CET 2008',
+ accessDate: 'Mon Jan 19 16:09:41 CET 2009'
+ },
+ '7ee6a662d1980467eea86a58cd7299ee02000740693df2a7ab9dd64347dbbaa4': {
+ header: '####',
+ data: 'ZnwtGdkg72+TQKCJQhZQIqP9sz79FcptnmH8VJEDQY9xTburh4cyhgbgROBis+awp1C5OyiAAoWfPnuRAN8Ai3d9f8M8yjnDGJ4BAJ6OjQ5r4RDQxNycCApXWO3mJpBrx56wMsCVWT6Z8a4khzPrf5HlDtus4lRV4GRdhU9FMpwuaCfgVD38MhlYXDaPgyu/8N+6eQHuFxquXjOJmptfO6tVhP1+/tEHo6iUAX3sXMZAionssRgPllQJxfzrsu7GQk3h66PakRzgStTHUCcdyoEe9c4VnvUgaasTbhENA4x8xPrxjo24zwxfFpWNEb1+pe8N3+dOXTsIdd3CMKrxQ5KkwzyN/Bj9jXNk9YX8PC0geJiR3bCGtPsAd7aEFB7E6y0RVX/RL5f6x0utSYw8mg6lfprlr5A=',
+ version: '0.3',
+ creationDate: 'Wed Feb 13 15:28:28 CET 2008',
+ updateDate: 'Wed Feb 13 15:28:28 CET 2008',
+ accessDate: 'Wed Feb 13 15:28:28 CET 2008'
+ },
+ 'c860f9bbcab5fa70854212e18c11a3e9bdc2382f91cfbd25636955c443a05f8e': {
+ header: '####',
+ data: '1rztZ6mKVFVjlL1kEoUsXEMketdElGbOpYK9iy3g1/WeMcTd4D/UjgHvmQHzzNuYJc/yx6cCMMU9dofLe3vWLKhqDAPAVCo49qiH527hP9rQE+0SNO1v2Ymk80hL/gqBfju51bIYxPKAD0uYA+GMX7OdL+S7qdealebERcnVa0K1AHiVU8lu5yIKk55U8zwitk0u86J1zwcraiM3RGXir/x3oZRIKDwT+lhUJPr8GbVjgKlPu07Ii8OdrAGdHefETDlyNnaKPJHTbGXkd3HZ2CYhJCQZGn1Hwfs46iRd5aO+3UErYtgIHl6CXuXd4E+DNW4UJZedP9YV860DBkpqMiQokEMYTh8Y2sOUyf3ZEOshfGvJUhj8O5p7rNm4+2BYO3XhREdV39tn4vUj56wYj+GL5CekEl0c4Mx7ViTQA+gLvk52V2w/5gFyFNQ9U+jUQpb2n+d9cw==',
+ version: '0.2',
+ creationDate: 'Tue Apr 17 19:11:33 CEST 2007',
+ updateDate: 'Tue Apr 17 19:11:33 CEST 2007',
+ accessDate: 'Tue Apr 17 19:11:33 CEST 2007'
+ }
+ }
+ },
+ 'fe21497ef7435d31f9746c132e4b5ecf5aac5f13b5961ddb55d2bdc3409f28f6': {
+ data: '4zgqvaaWm7nJO09LKN6o5hbWwGzOv7VVmXDu5T+JCHTSOXbteogax2Zrv0uKLkfooGFThJBk0rXfXxE64vMOq3AeHXGw7Chg7hz8Z2Lpjr4FfE6q7Em7UuAlAuL1PiyXXJJK5iSsRY9tkizuYl19aXW+CgpPznYD/PyXgeYxqt9WLqK8cl5iAU87R0cQDhwl16ivzVgiiFeaB6B5FQqWBAHCEgXhqTsaw2gv4snbmPOqcUZbHy/Vb9hv4lPBJwGFNxQzeZUad92VBC8YbIjmbohDsXjteqD2/k1qOgpUB/U5BpyVwsi+5ahgb8gbS+AqYoRDYzkaj83ksPI4JzWyZhpqjhDauaI6M7hGnJ4GB8UZc0M3WPgrlf1r+TXCgpcfembqL1MyteM+C+ItPRP/QdaIXxLOmvGFOBKQYEI7UceUWBCSEzORlS2S2lltlqt+K4B8QTULiKaXCfRmF/u60FpJufIkUX0pE/rQVChxswSWvh7uJFDBIDx8MplTX724A7DN5d4/Ad4Yi2cj3V8X/DEErnHTvirP3tZ2F2oAe7kIdu+JuCqKcMaGB4hVijzv+yim2TCPvrGTFaMmg9PvcWHpik9jEIabCkdqAR8EGIkD29+yvG4vD0DTRKv2vPIfr60ZQnsgs8nlPPoNa6lNHvI/EO0nBGBYBc1TW+syV5h/zOG3rHX0XCHhISZmDMjra7eUETWChncR88P7ciC4yJQtzXFGzeXp2ktzZ8m5g1EQfgtlUVZsHN8e4OQ9DjKt0unfq5RFBj2jlG8TBZn6ZpebxWR2qOxp81KQLHJND9zRTy3h65+k5wo3MnnxE3GbeXg2dFIORRvGUT6bWsqW1fqR/pg1GO8KNtrt3CryZofgE52kuk6hlcmSk9974JR5523+1/hbts8n5VrTi1C6GWhnxpiJb1XIvICdag5g7C2iYppzLKVzbJcFMegwDUrapbmGhkqnGwSY1EQSDyagPr2xlziWhdWdCOVAYcyw8dOpdD97QhVef0OWrJ8nbgFKD6wn21475OFxooheWiMCyZwXqESVG1cVCjeaCsymBtEVPpmQdSkOfMdXpKVF+3osb4K2XDpPeU1zPWVozeMp68YhLztQ/g==',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 18:43:29 CET 2007',
+ accessDate: 'Mon Jan 19 16:09:30 CET 2009',
+ currentVersion: '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a',
+ versions: {
+ '1b12c771a7f5f13d13f12016ad4132e9707be2ff00d72f77356204f0f86fc08a': {
+ header: '####',
+ data: 'QfC77EWgmmnxz9JqLdn9Tw7mNztfQZPdNpaML03EdFpphsjgLloqBRX0UZ21oozjQGHpcUMMOsaJgzCuDlfh7T7ePVV60Ps4AJtzv7bHSVGKsj1iALU1qjtesOYJayp8bA/3peo4HEnVgP86jc5NTwJxpsUhNG0Ae93xVu4lPF0gL0/yjgZUHqYZXkb+oXrcybL0BSOjRnB9fRpA1dEhcwJwoelLTvg7il354qp/Wo+S9Cz5E/K+xnlJAuSXCRXboWea/ZZ9TX88q5uUcY5jLF7Xi2HoFVZw2f5tbycxwGtT1CKXp+OAKn6mQaBAYM51zoMNDT7MvBDXD3v4Cidjgh24GZ2zndfkYT0kHCtY7OVIVSTsXTR+5/XMedojVvDlX9LBa9ST99NLCUy7Di94rJtX72ev3Ei3I1w3qPvCl3jgD2VbIwLogCzqLtY+2IkLAa8M2EpX/D+h',
+ version: '0.2',
+ creationDate: 'Wed Mar 14 18:43:29 CET 2007',
+ updateDate: 'Wed Mar 14 18:43:29 CET 2007',
+ accessDate: 'Mon Jan 19 16:09:30 CET 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'test_test_offline_copy_data': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ '9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8': {
+ s: '55a27b18e8fdf1fb5e5bcf859cfa50fcbc69c9a41f04e371606a86411a98f460',
+ v: '983a6c79e7d5d490c3f13645c49760180fca05cc677914bf60fee009ead5a65d',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13":"0"},"data":"Ki9chN/ker5c+7zB5NinstllVq1Vs+N5pezZIohKVVa15VLSIyre3DRilRoldy/94LbGaEM3SZsMlf28hYbWySln3ekNMIB+MItaYb8urw+8U6n8+QaRMAClHXukfi8te2d1OIlgjbrBQNMmzBorjIs="},"directLogins":{"index":{},"data":"54KM7x3emxWZH4CQDLBj4SkT"},"preferences":{"data":"AwOQXmReKkLpp8qZa4zjaWcY"},"oneTimePasswords":{"data":"YgSYIsDeVT87bfiASQqXA2E9"},"version":"0.1"}',
+ statistics: '6Kupec1ZD7Dw0WzK7pPesnLE',
+ userDetailsVersion: '0.3',
+ records: {
+ '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13': {
+ data: 'dXql3HZJQRpvwOe56SgzbbpMoYWRBjEp+E8uMJT7tprzYJ109H1SnxRWWiXlDOzH2XfoXahP3S59K7rHeJ+/icX+ZrsOvp3YEW7wdoEDosyvrQuxrmHdusZ3BeaFIhQMmK9wqpAzpKCRrz30l/yi81zNpLgTXLLK9fiAyksmsfQL3VHgQg==',
+// data: 'bXql3HZJQRpvwOe56SgzbbpMoYWRBjEp+E8uMJT7tprzYJ109H1SnxRWWiXlDOzH2XfoXahP3S59K7rHeJ+/icX+ZrsOvp3YEW7wdoEDosyvrQuxrmHdusZ3BeaFIhQMmK9wqpAzpKCRrz30l/yi81zNpLgTXLLK9fiAyksmsfQL3VHgQg==',
+ version: '0.3',
+ creationDate: 'Tue May 05 01:28:36 PDT 2009',
+ updateDate: 'Tue May 05 01:28:36 PDT 2009',
+ accessDate: 'Tue May 05 01:28:36 PDT 2009',
+ currentVersion: 'a22bad10653a70ec3287917bc23d642fe698042cabbcc1074b60122cf2bb9d4d',
+ versions: {
+ 'a22bad10653a70ec3287917bc23d642fe698042cabbcc1074b60122cf2bb9d4d': {
+ header: '####',
+ data: 'Pc18C1A9NwNlecbOtOOAEymNZD5oq20ZvPqMfiCyNhkcmaN9sEnifF31epZSjpDw4XM4ex3HFhhITttXlCrossDVYB8z00k6XsFruCkdwFRmBjb2PdrdZFAkGQeS/8xTarYWgiflkfGocGqVm6EUq1gh8QLE173Jzo15LOSuzuSS90BTMvcsqzzRrIEe+9jwF9/ehLyQ5yYxNImFGQQ2jkW0KiZsjyEbQAGry7B1/AiSUBaGYHYzcB3bFgXnzC3ecPwL+ENZ+azpTd143WneuVMUJrWNp3S+9ZRzboRzcYV6Ax3nOLPS7LTc+e9j9s4CrPvc1L6pG23AzNByDWst0JrqhN37yp67EVVrFQfUDWcKgZyyA/M82q1TVScx+I4A+g9ASC+PdQ3+M5+EOtEfClkgYJFqzXqwPKYwBv4CBKxikS2Vt8x40271kjmVYyGQOIRTo1UKn6u07TS5hxdEgEI+WdukG52813USiD8bQFbN0r4VhjFSqKMAJoItjqvafBNBl+OXYQ1p1zRCXP7wHS4/F7mvrK98gSuIsBgfL+/q9rExXaxIZJNSbs1HGAXR1TxYSvyKZvLa',
+ version: '0.3',
+ creationDate: 'Tue May 05 01:28:36 PDT 2009',
+ updateDate: 'Tue May 05 01:28:36 PDT 2009',
+ accessDate: 'Tue May 05 01:28:36 PDT 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'test_test_offline_copy_data_withExtraVersion': {
+ users:{
+ 'catchAllUser': {
+ __masterkey_test_value__: 'masterkey',
+ s: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00',
+ v: '112233445566778899aabbccddeeff00112233445566778899aabbccddeeff00'
+ },
+ '9a984e219b07f9b645ef35f4de938b4741abe2e0b4adc88b40e9367170c91cc8': {
+ s: '55a27b18e8fdf1fb5e5bcf859cfa50fcbc69c9a41f04e371606a86411a98f460',
+ v: '983a6c79e7d5d490c3f13645c49760180fca05cc677914bf60fee009ead5a65d',
+ version: '0.2',
+ maxNumberOfRecords: '100',
+ userDetails: '{"records":{"index":{"75b61c51726a35d1c12ac553947ff9e974d1a29339f87fbeee0d831b59938a53":"0"},"data":"YjlNzXUO9m0EXdi5fUguA6RjR5jc2mwuHkpMsHAheExR2zpoV6OJx8tBTdUGqDBAlbIn6xUx2TT+dzgjic/XubgKNsv6JpTvnfiW6ZMWiebKXVigoZw7L5EvmcHjVLI8aoIhVEj4ADwkh9qHm0Kt1zFGQPwwJfo="},"directLogins":{"index":{},"data":"4W5csD8DxlxeXVRROk7wVbXi"},"preferences":{"data":"/DjOoFcgquxUbW5ye2LrpsKM"},"oneTimePasswords":{"data":"DEqkd74lLAGtG4YKRPniBNBU"},"version":"0.1"}',
+ statistics: 'EkRr9wEXi/WOlZfCXphn9kfx',
+ userDetailsVersion: '0.3',
+ records: {
+ '75b61c51726a35d1c12ac553947ff9e974d1a29339f87fbeee0d831b59938a53': {
+ data: '/gtNfde5l2J9eeg+rlBHZtqO4RDaWNQwaMEluOVowKdUlGAYjo9FU0NwKsA9CM3ST4sTYl0mylP3C/AGybO8/9sTCkEn20wi0slharA61Rk8uB2lNjCICZB4l3ZGvD4AHKucu8YQzxpWop5dTN8f4us5eJ2VjvJPLqUzSKZL4g+6MiKbjQ==',
+ version: '0.3',
+ creationDate: 'Tue May 05 18:47:53 CEST 2009',
+ updateDate: 'Tue May 05 18:48:59 CEST 2009',
+ accessDate: 'Tue May 05 18:48:59 CEST 2009',
+ currentVersion: '2c913151cec0422dfa51c5bccbca6ad09d8e195bff144d2b5f7a2da3bf55c11b',
+ versions: {
+ '0311012a897262b85b60a316f086f0576caa3c11a34779c02ad9e60232c79564': {
+ header: '####',
+ data: 'MZGx+tQAecxJNl6UbWHIM8g416Qa8DfWtGo7f2vLkPBbhsr20xnZ233oPqIGceG5/6WMssQd9c8U81urISK+4Ar8zHGUxTdIYLZaDq33Q0uF5vO7OsaBcjL7m+tX7zB+e/eu0ABbqvt+saMsZKKSdIZv2KNbAg5VTiL7GjWuowM23tWgiUBgX3eO5fnUUQWVkBygk0qy2O45oNfb1XcbsGMCfS4YPF9GB/wGSQKG8keMoy1ZWZh4nG+Pdx2ymIrYKLv8T+i7jtWEbyhvEglb7TadCMBBF0pnkYvG3F29skWooZC92dy5213o+3/uSKi0od5tAbvSYZHjT5hDulUtmjRFGq4ZRERLqvrZs9Sg8G2mjtf8Ta99Hob8WLxyGF9x7s1LcLPERtdsP9qCD+I0WtwrDiodl/sPQ/5s3G2S+M/YejKXBvG3AWwoO1gkdhec3+d3meFNvCr0hKNzotrHmDLC4tGyZIaAcBmPQ8xSD5KmNJJFU+V0QIdiEYKnPjo95oSmKyK1UtIoPrWCahfYSKXh+aW53XnzY4JKHRER9vWwdJzz',
+ version: '0.3',
+ creationDate: 'Tue May 05 18:47:53 CEST 2009',
+ updateDate: 'Tue May 05 18:47:53 CEST 2009',
+ accessDate: 'Tue May 05 18:47:53 CEST 2009'
+ },
+ '214d184d75418af71d18f412bc6bb153fd6435a4a675af6bf2a744ecbd7a53b7': {
+ header: '####',
+ data: 'Y38v4jhKwcsW8LDTigIhtdLJ2zgv+1rSutqyu0AilBQeSTe4D0rnapZZTW/mNnD5IGpWKFoEl8+WGj1zvGzleNdkOa08nWJEYDNe2h0+FjBSHBUAgH5fraezomRWzJ/Z5HHFiZuFfpjt2BHd0Y3Not6AuL3aBgjjkEai90r2o59Xr70maUwo1UqmtVg3gvX067MC3hlqhNIp390J8LFiSj8Z4US9x/WzVR5Xx069+0PFMBwipq9WJPrcfTPwvP6xVa+J8BCJk3HtboRutq1ZhhHpibm+TY3Xl3gFTTCHWDZCSJ4Rm1dWkyqpx51u/AVg2TC+ljFLKv7hq3euVZNMLNMY2BqoCkcb+w6dFLDs3WfPAW0aQN2P++GFa/eVpN90YxAeXufjsXKaArTMjGWKiHqyU1iVVI8N1QEiFYjjBV1GvkJxog5PjtAzJF++qwHDIa+gJ+NnOfenVF0wIRMCEnpGyvbg3SkUoenKFoHO0IcSP2CW2RWV/GAmiEZEuVD393mKi5B6fpjdO9JVPNyz0i0kW++dtzInwPnglhOAY1ywT0ExOBLIEr8=',
+ version: '0.3',
+ previousVersion: '0311012a897262b85b60a316f086f0576caa3c11a34779c02ad9e60232c79564',
+ previousVersionKey: 'f45/Sx3jMC8CgdT8cjfcC4ApA8xMXABFO48jiTh5VjJfTlVqw3NnHRO2KDBIhy0znPvP2AKlpKQHruW8LQno7YLyhEIXh4ChjMUjJsFFwB/LUg==',
+ creationDate: 'Tue May 05 18:48:11 CEST 2009',
+ updateDate: 'Tue May 05 18:48:11 CEST 2009',
+ accessDate: 'Tue May 05 18:48:11 CEST 2009'
+ },
+ '2c913151cec0422dfa51c5bccbca6ad09d8e195bff144d2b5f7a2da3bf55c11b': {
+ header: '####',
+ data: 'tkiW41JHOfbYOt2KHx1HtDJEzxbfVS1Y2HJQqdQZ73zhvxnkWLw/X6FMiBexLeoKXO1H9NIWS884MzEO782vg8QRxTizg66Yye+q1Hox+QsaEoaD4UQ54XV1duTOB/XS5P0P9DFvtIz9msEu8GJrvizAdxu/7FG2b5XfENDkwqIzydI7JMfGC0JzDnfGvYkWqoL8jx3Joxa7TNqN4he4v771Ho1ZoUv3Pp7ZGwBU+btl6Q9mcycSf5KXdTw+6nDjfQh8qyts/u7O5xPFh2Yn8zS48x95I4SA4yFKtERU3pLAxIkcZWVb17xT8xlbPESreZ0RyYSR0CgW0wPMxkLHH1uqWycTa7yIxUhyn+JK9jCl4eDa/KUSGbN1yb6pOyjGuev1vHEZv3bOmO52RVVIdMHTe3LezCKY8xpDqtQKSfAvFg1TmabugXePXB+KvPbDDWI5otDEIwLYhDFcSn2FyqUEATSzeU2o1uXO+ffbU3QBrwr27tsreughWSP7905FQbEEshsRUc2Xt92WhTnVM6W74Y0bMLWjTrXbu+hNsjtFYYN6gtezcltnB58MVw==',
+ version: '0.3',
+ previousVersion: '214d184d75418af71d18f412bc6bb153fd6435a4a675af6bf2a744ecbd7a53b7',
+ previousVersionKey: 'XtJ8Ub99GXIkxErIPr0HaIrRqlAO0Naa/tPwUA51K2D5R6R3CR6QbHd3GpkCnu+y+bcEIRYrQqgabi3LROYT+1SZ9B9FctX6FyaTjYEazFdCvg==',
+ creationDate: 'Tue May 05 18:48:59 CEST 2009',
+ updateDate: 'Tue May 05 18:48:59 CEST 2009',
+ accessDate: 'Tue May 05 18:48:59 CEST 2009'
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+
+ //-------------------------------------------------------------------------
+ 'syntaxFix': ""
+}
diff --git a/frontend/gamma/tests/tests/Components/UnlockPassword/index.html b/frontend/gamma/tests/tests/Components/UnlockPassword/index.html
new file mode 100644
index 0000000..5534068
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/UnlockPassword/index.html
@@ -0,0 +1,117 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>UnlockPassword - test</title>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/DOM.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Style.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Visual.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Set.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/BigInt.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/AES.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SHA.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/PRNG.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Crypto/SRP.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Toll.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Test.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Proxy/Proxy.Offline.DataStore.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Connection.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Crypto.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Strings/Strings_en-US.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/EncryptedRemoteObject.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Version.Field.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/DirectLogin.js'></script>
+ <!-- script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/Record.Field.js'></script -->
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.Legacy.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/DataModel/User.Header.RecordIndex.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/BaseComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/Button.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ComponentSlot.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/PasswordEntropyDisplay.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/ProgressBar.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/SimpleMessagePanel.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TabPanelComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/Tooltip.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Components/TranslatorWidget.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/CardDialogRecordFieldComponent.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Components/UnlockPasswordComponent.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Common/Controllers/TabPanelController.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/PM/UI/Web/Controllers/CardDialogController.js'></script>
+
+ <script type='text/javascript' src='./User.data.js'></script>
+ <script type='text/javascript' src='./unlockPassword_test.js'></script>
+<script>
+ Clipperz_IEisBroken = false;
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+</script><![endif]-->
+
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/clipperz.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/compact.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/ytheme-clipperz.css" />
+
+</head>
+<body>
+
+<div id="tableWrapper"></div>
+
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/Components/UnlockPassword/unlockPassword_test.js b/frontend/gamma/tests/tests/Components/UnlockPassword/unlockPassword_test.js
new file mode 100644
index 0000000..87f3275
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/UnlockPassword/unlockPassword_test.js
@@ -0,0 +1,136 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+Clipperz.Base.module('Clipperz.Tests.SimpleMessagePanel');
+
+Clipperz.Crypto.PRNG.defaultRandomGenerator().fastEntropyAccumulationForTestingPurpose();
+Clipperz.PM.Strings.Languages.initSetup();
+
+Clipperz.Tests.SimpleMessagePanel.Tester = function(args) {
+ args = args || {};
+
+ Clipperz.Tests.SimpleMessagePanel.Tester.superclass.constructor.call(this, args);
+
+ this._user = new Clipperz.PM.DataModel.User({username:'test', getPassphraseFunction:MochiKit.Base.method(this, 'getUserPassphrase')});
+ this._unlockPasswordComponent = new Clipperz.PM.UI.Web.Components.UnlockPasswordComponent({
+ 'title': "Unlock account",
+ 'text': "Insert the passprase to unlock the account",
+ 'type': 'INFO',
+ 'buttons': [
+ {text:"Cancel", result:'CANCEL'},
+ {text:"Unlock", result:'OK', isDefault:true}
+ ],
+ 'openFromElement': null,
+ 'onOkCloseToElement': null, // this.getElement('cancelButton'),
+ 'onCancelCloseToElement': null
+ });
+
+ return this;
+};
+
+Clipperz.Base.extend(Clipperz.Tests.SimpleMessagePanel.Tester, Object, {
+
+ 'toString': function() {
+ return "Clipperz.Tests.SimpleMessagePanel.Tester";
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'user': function () {
+ return this._user;
+ },
+
+ 'unlockPasswordComponent': function () {
+ return this._unlockPasswordComponent;
+ },
+
+ //-------------------------------------------------------------------------
+
+ 'run': function () {
+ var deferredResult;
+ var proxy;
+
+ proxy = new Clipperz.PM.Proxy.Test({shouldPayTolls:true, isDefault:true, readOnly:false});
+
+ deferredResult = new Clipperz.Async.Deferred("unlockPassword_test.run", {trace:false});
+ deferredResult.addMethod(proxy.dataStore(), 'setupWithEncryptedData', testData['test_test_offline_copy_data']);
+ deferredResult.addMethod(this.user(), 'login');
+ deferredResult.addMethod(this.user(), 'getRecord', '8280842f41162b673335b63860637e8472e8bbff0efa2bc78b0dbc5e09712e13');
+// deferredResult.addCallback(MochiKit.Base.bind(function (aRecord) {
+// cardDialogController = new Clipperz.PM.UI.Web.Controllers.CardDialogController({record:aRecord, delegate:this});
+// cardDialogController.run();
+// }, this));
+ deferredResult.callback();
+
+ return deferredResult;
+ },
+
+ //=========================================================================
+
+ 'getUserPassphrase': function () {
+ return this.unlockPasswordComponent().getPassphrase();
+/*
+ var deferredResult;
+ var confirmationDialog;
+
+ confirmationDialog = new Clipperz.PM.UI.Web.Components.UnlockPasswordComponent({
+ title: "Unlock account",
+ text: "Insert the passprase to unlock the account",
+ type: 'INFO',
+ buttons: [
+ {text:"Cancel", result:'CANCEL'},
+ {text:"Unlock", result:'OK', isDefault:true}
+ ]
+ });
+
+ deferredResult = new Clipperz.Async.Deferred("CardDialogComponent.askConfirmationForLoosingPendingChanges", {trace:false});
+ deferredResult.addMethod(confirmationDialog, 'deferredShow', {
+ 'openFromElement': null,
+ 'onOkCloseToElement': null, // this.getElement('cancelButton'),
+ 'onCancelCloseToElement': null
+ });
+ deferredResult.callback();
+
+ return deferredResult;
+*/
+ },
+
+ //=========================================================================
+ __syntaxFix__: "syntax fix"
+});
+
+
+
+init = function () {
+ var tester;
+
+ tester = new Clipperz.Tests.SimpleMessagePanel.Tester();
+ tester.run();
+};
+
+MochiKit.DOM.addLoadEvent(init);
diff --git a/frontend/gamma/tests/tests/Components/crossWindowsBookmarklet/CrossWindowsBookmarklet_test.js b/frontend/gamma/tests/tests/Components/crossWindowsBookmarklet/CrossWindowsBookmarklet_test.js
new file mode 100644
index 0000000..cb80473
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/crossWindowsBookmarklet/CrossWindowsBookmarklet_test.js
@@ -0,0 +1,66 @@
+/*
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+*/
+
+newWindow = function (anEvent) {
+ var windowURL;
+ var htmlString;
+ var newWindow;
+
+ anEvent.preventDefault();
+
+// htmlString = '<html><head><title>TARGET WINDOW</title></head><body><h3>this is the target window</h3></body></html>';
+// windowURL = 'data:text/html;charset=utf-8;base64,' + (new Clipperz.ByteArray(htmlString)).toBase64String();
+
+// newWindow = window.open(windowURL, 'CrossWindowsBookmarklet_TEST');
+ newWindow = window.open('http://mail.google.com', 'CrossWindowsBookmarklet_TEST');
+ MochiKit.Signal.connect(newWindow, 'onload', targetWindowDidLoad)
+ console.log("new window", newWindow);
+
+ MochiKit.Async.callLater(2, runBookmarkletScript);
+};
+
+targetWindowDidLoad = function () {
+//console.log(">>> targetWindowDidLoad")
+ runBookmarkletScript(null);
+};
+
+runBookmarkletScript = function (anEvent) {
+ if (anEvent != null) {
+ anEvent.preventDefault();
+ }
+
+ window.open('javascript:_cble=null;ilf=function(_1){var%20_2;var%20_3;var%20i,c;_3=0;_2=_1.elements;c=_2.length;for(i=0;i%3Cc;i++){if(_2[i].type==%22password%22){_3++;}}return(_3==1);};flf=function(_6,_7){var%20_8;var%20_9;var%20i,c;_8=null;try{_9=_6.getElementsByTagName(%22form%22);c=_9.length;for(i=0;(i%3Cc)&&(_8==null);i++){if(ilf(_9[i])){_8=_9[i];}}if((_8==null)&&(_7==0)){var%20_c;_c=_6.getElementsByTagName(%22iframe%22);c=_c.length;for(i=0;(i%3Cc)&&(_8==null);i++){_8=flf(_c[i].contentDocument,(_7+1));}}}catch(e){_cble=e;}return%20_8;};iev=function(_d){var%20_e;if((_d.tagName.toLowerCase()==%22input%22)&&(_d.getAttribute(%22name%22)!=null)){_e={};_e.type=_d.getAttribute(%22type%22)||%22text%22;_e.name=_d.getAttribute(%22name%22);_e.value=_d.value;if(_d.type.toLowerCase()==%22radio%22){_e.checked=_d.checked;}}else{if((_d.tagName.toLowerCase()==%22select%22)&&(_d.getAttribute(%22name%22)!=null)){var%20_f;var%20c,i;_e={};_e.type=%22select%22;_e.name=_d.getAttribute(%22name%22);_e.options=[];_f=_d.options;c=_f.length;for(i=0;i%3Cc;i++){var%20_12;_12={};_12.selected=_f[i].selected;_12.label=_f[i].label||_f[i].innerHTML;_12.value=_f[i].value;_e.options.push(_12);}}else{_e=null;}}return%20_e;};fp=function(_13){var%20_14;var%20i,c;var%20_17;if(_13==null){_14=null;}else{var%20_18;var%20_19;_14={};_18={};_17=_13.action;if(_17.constructor!=String){_17=_13.getAttribute(%22action%22);}if(%2f^https?%5c:%5c%2f%5c%2f.*%2f.test(_17)){_17=_17;}else{if(%2f^%5c%2f.*%2f.test(_17)){_17=window.location.protocol+%22%2f%22+%22%2f%22+window.location.hostname+_17;}else{_17=window.location.href.replace(%2f%5c%2f[^%5c%2f]*$%2f,%22%2f%22+_17);}}_14.attributes={};_14.attributes.action=_17;_14.attributes.method=_13.getAttribute(%22method%22);_14.inputs=[];c=_13.elements.length;for(i=0;i%3Cc;i++){var%20_1a;var%20_1b;_1a=_13.elements[i];_1b=iev(_1a);if(_1b!=null){if(_1b.type!=%22radio%22){_14.inputs.push(_1b);}else{var%20_1c;var%20_1d;_1c=_18[_1b.name];if(_1c==null){_1c={};_1c.name=_1b.name;_1c.type=%22radio%22;_1c.options=[];_18[_1b.name]=_1c;}_1d={};_1d.value=_1b.value;_1d.checked=_1b.checked;_1c.options.push(_1d);}}}for(_19%20in%20_18){if(typeof(_18[_19])!=%22function%22){_14.inputs.push(_18[_19]);}}}return%20_14;};pp=function(){var%20_1e;_1e={};_1e[%22title%22]=document.title;return%20_1e;};rs=function(o){return(%22%5c%22%22+o.replace(%2f([%22%5c%5c])%2fg,%22%5c%5c$1%22)+%22%5c%22%22).replace(%2f[%5cf]%2fg,%22%5c%5cf%22).replace(%2f[%5cb]%2fg,%22%5c%5cb%22).replace(%2f[%5cn]%2fg,%22%5c%5cn%22).replace(%2f[%5ct]%2fg,%22%5c%5ct%22).replace(%2f[%5cr]%2fg,%22%5c%5cr%22);};sj=function(o){var%20_21=typeof(o);if(_21==%22number%22||_21==%22boolean%22){return%20o+%22%22;}else{if(o===null){return%20%22null%22;}}if(_21==%22string%22){return%20rs(o);}var%20me=arguments.callee;if(_21!=%22function%22&&typeof(o.length)==%22number%22){var%20res=[];for(var%20i=0;i%3Co.length;i++){var%20val=me(o[i]);if(typeof(val)!=%22string%22){val=%22undefined%22;}res.push(val);}return%20%22[%22+res.join(%22,%5cn%22)+%22]%22;}if(_21==%22undefined%22){throw%20new%20TypeError(%22error%22);}res=[];for(var%20k%20in%20o){if(typeof(o[k])!=%22function%22){var%20_27;if(typeof(k)==%22number%22){_27=%22%5c%22%22+k+%22%5c%22%22;}else{if(typeof(k)==%22string%22){_27=rs(k);}else{continue;}}val=me(o[k]);if(typeof(val)!=%22string%22){continue;}res.push(_27+%22:%22+%22%20%22+val);}}return%20%22{%22+res.join(%22,%5cn%22)+%22}%22;};closeBookmarklet=function(){var%20_28;_28=document.getElementById(%22clipperz_bookmarklet%22);_28.parentNode.removeChild(_28);};lfp=function(_29,_2a){var%20_2b;var%20_2c;var%20_2d;var%20_2e;var%20_2f;var%20_30;var%20_31;var%20_32;_2c=%22http%3a%2f%2fwww.clipperz.com%2f%22;_2d=_2c+%22help%2fbookmarklet%22;_2e=%22data:image%2fpng;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAAAXCAYAAABOMABkAAAACXBIWXMAAAsTAAALEwEAmpwYAAANJ2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjardd5NJRv2AfwaxbGMmbGGHsY2Xcle%2fYtkWzZUpKdYSYmScqSlDVLKNoo2oQWEonqR5YkyZKtyJKlFLJkmfcPqd7feZfznvNefzzneu7nj%2ft+7nM+3%2fvcAHgNdxqNggSAwCB6sK2ZIdnJ2YWM6QQM4IAXsCDi7hFCM7C2toT%2fuhAA852AAABoV3Cn0SjwfytcsJOzCwBCHgBIPuu9PgCQDq739gBAOkKn0QEQvgBA8vB19wRARACAfLC9rREA4iYA4HzW+woAwB1c7xsAABfq4UMHQHQDMBODPP2CADBTAMy6nl4hHgA4eQDw9AzxCATApQKAVWAg1RMA9xEApD1owXQAPAsAKDg5u5DXl7w3AWAbPwCLxZ+xI5kAZXkA0rv+jIk9AuBxB8hP%2fjM2awsIAEDwtIZ4q2xd30GsIQDTAIMxKwmASQdYTWMwlvMZjNVrAKg+gFqKx+Hg0I39RrQA%2fG%2fv6%2f%2f8q1AIACQAQhxRiAxHRaAjmE4wR2FiWE6yGrPWsZ1mP4ON50jClRN8OdOIaVzppHPcmTyZvNl8dQJUwdxNuUKXhBvIh0XzN18Ta5U4Jlko1SZzQvaOXKdCjOJdpZ4tp7feV%2fmgmqRWrj6omaJVqT2qk6H7VG%2fCIMvwudFXkxzTerMZ8ys7myzmd+Vbvd79xvqNTZvtiv3tPR0OnY5dTt0u6L33XPv29e8fcPtw4ONBrMdjz2GvEe9RnzHfz37jAdyUZ4Ffgr5Sp2nfDn0PngmZo88d%2fhE6f2QhbPHoUvjPYysRK8dXI2WiOmIQJ5GxqFPoOKbTzGcw8SwJrIlsSezJ2BSOs7hUfBohnTODeI4rk5TFnc1znvcCXw5%2frsBFwUubLgtdEb4qkkfOF722+bpYgXihxA2pm1K3pG%2fL3JG9M1lEuStfrFCiVKp8b8v9LQ+2PtxWplquVj7%2fKLRC%2fbFGpVaV9pPt1duf6jxdq4ms1Xum%2f9zgheE%2fRnXouth6k5emDWaN5k3mzWzNia8sWixfW7XiWs++sW6zeWvbTmxPf2fXYd+5p4unK7vb8b1Tj0uvQG9un2u%2f68C+D8Ifrnx0GzwwJDqU%2f+ngsMeI56jEaOGY92efcd8JmYnbk%2f5TAV8oXxW+Fk8HfaN+p81smbk%2fGzwX8oM+rzpfvhC6GLZ09OfRZa3lqpVjqxFrOmtPGQwAhBgSh%2fyGakbfYcpgjsD4sNizGrFtY5fCSnHw4XjxfAQ+Tm6iJJc0SYPbkmc%2fbwhfCn+JQLPguBCXsJqID%2fm86EsxhLiOxCHJe1LTMtKyFLkqBZSigVKa8uBWGZW4bV1qsuo0jTotXu2w7a90efSo+s8NxY2OGbeZCpuF7ag2X7LYYum1K9OqzRpnY2YbZldg%2f86BzVHf6ZDzJZf6vdP7RPbvdgs%2fkO9ed3Dck9tLz9vJ54TvVb9a%2f%2f6ApUCuIDmqMc33UERwakg+vexwQ2jvkYmw+XDUMc4I8nH5E6qR+lEW0btj9p48EOt1ihJHPx18Jio+KuFkYnxSenJiSs7ZC6nZaWnpFzPSz2Vlns+6mX3jfPGFmzl3cksuPrn05HLdlVdX2%2fLa89uvtV%2fvLRguHLsxdHPk1vTt73emi77enSmeLpksnbo3dn%2fwwdDDnrK28sZHtRWPHpdUXqxKfxJVHfh0b41F7fZnss+Jz5defPynqe5hfcbL4Aa7RrUmwSZGc8+rhy0Jr11axVpH3zxoO%2f7WpB3X3v%2fuaod%2fp0rnaldLd8b7fT0yPbO9lX0x%2fRYDpIGBD7c+hgxqD6GHmj6dG94%2fIjUyNVo5Fv155zj3eP%2fE9UnKlOrU2pfGr+nTe7+Jf5v6%2fmAmYtZsjjjX%2faNgnrqguYhafLmU9nPvstjyl5Xy1ag1cwYPgwEAJxFhyHCUNqoSfZxJj6mGORpzisWUpY41ju00ewJ2J7aZIxmXjE8h7Ca0cqYS07kySBnc9tzveLJ4s%2fjO8+cI5Armbroo5CrUL3xF5Co5TzRvc57YNfHrEgWShVI3pG%2fK3JL1k52Quy1fpHBXsVipRLl0y72t91UebHuoWq5Wrl6uEaaxqFmpValdtf2JTrXuCd01vRr9WoNnhs+NXhjHmqBN6kzrzV7uaDBv3NlkkWiJtXy1q8Xq9e5W61Qbgk2b7Vu7dvt3ezodshx5HLucup3fu%2fTszXUVdO3b17%2f%2fg9vHAx%2fd8w6KHhzy+OQ57DXiXegjuZ4g%2fhMBdyjylKn%2flCKzv1Ok4qjG0aXwn8eWI1aOr55Yi2REQwzyd5JgzmDiWeIbE3Ymsidhk7EpHGfxqYQ0zt9ZwpPNe57vV5Zs+jtL8oeueVwXKxAvlLwhuZEmRfJ3FYoV%2f8oSlbJt5aqP1CvUH2tUalZpP9Gu3v5Ut0b3rxwxqTd9adpg1rijybzZ4lXo682tVm+s26zf2rQf75DtdOhy7I7pUep16YsbUPkQP6g6lDTsOao9ljbuN+n%2fhTJN%2fZ4w5zJ%2fdilx1ZbBAFg%2f+wAAmNUAsuQAHHIA7PIB4uQApNwAeG4CWHMA2GsCkkkYkDo0QOzU2Tg%2fAAEEEAJFMARnCIFUKIVFBBlhgQhD3ES8Rowh8UgzZDSyGrmC0kFFo+pRK2hRtDO6EP2DyZTpFFMJ0zSzGXMe8yiGG+OKqWbBsGiyxLJMsmqxUllr2RTYotgq2HHs0ezvsSRsEPYzhwnHSY5BnDvuOR6F98ZPEWwIWYRVznjOGaIWsYBLnauAa5rkRlrg9uMu55HjecnrzYfhu80vwX+Ef07gkqCZ4Oymq0LiQhHCCOEyEX+yKLlH9NzmzZujxPBireJpEnskBSSHpO5IG0nfkjGU5ZQdlHsgf1rBVVFFCas0pvzPlvytMSqe28xU5dW41FbURzWyNXGatVql2nnbz+mc0Y3UO6J%2fyIBi6Gfka+xrEmAaZEbfccw8dudZi1zLW7sqrBp391l%2ft8XYCdtr7LFzoDmmOBU7v3GZdeXbp7vf2y31QJX7Zw9eTzOvo95Ffnz+1gEJlLogJNWAFn3oRQgz3eJwepj4UWr4kwi24y4niiIZ0faxyFOucY%2fOcMUfSmhLzkxZSnVLq89QOpeTHXL+U45dbt3l4qsSeZeu8RYSbqTcwt0+eze7RKj0+n2FMuPytgr3x9+reZ8W1Rq+oNfh64sadjYntCi8bnsT2l7fQesS7G7ok+zv%2fpAwqDdcNOr5WWS854vDNM+3rpmcObeFqaWy5UgGH4MBAEhgA16QAT1wgsOQCRUwgMAglBFuiBREDWIWKYt0Q+Yg36HwqF2oJFQLmgO9G52J7mUiM%2fkxlTItMhsxn2V+j5HAHMa8YCGyeLJUsLKzurIWs6HZ9rM9ZGdj92CvwXJjadgWDlmOZI4pnCWuBM+Bp+I7CfqE65w4zlDOXqIp8R4XmSuda40UQvrC7c89wUPhmeGl887zhfMj+JMEBARuC2oK1m9y2DQuFCXML1wuYiMyQY4TlRRt2Bwkxiv2VNxDAivxTDJISkTqrXS8jKHMqmyVXIS8jvyCQo3iGSV7ZVHl6S01W9NU%2fLcZqwqrLqt1qD%2fWuKQZreWj7bhdR0dJV1SPqI82QBnMGH43mjaeNBk1nTWb3PFjJ9KCZMm7a4uV7u7d1rY2AbZH7XLt7+955dDruOJMclHaa+V6aN+F%2fXVuY+6sB5U9fD1zvGq8v%2fnK+Hn5Zwd0BAoG7aHm0j4HS4eE0htDhY6EhDWFix1LiZg44RzZEK0WUxBLPJVymngmK4EvMTdZNeV1qlfaz4zkTPWskfOXc%2fwv7rksc5Upb+ra84KyGxduxd3xuOtaYnpP48G2MsVHCo+lqySqpWuUn+m92FFn85LSeKg5reVq65O2gXZGp0i3To9nX+JA5cepT%2fwjhmNR4zcnh78KfPOeuTw3uiC9FLRcvoZgMACAGQggBIbgDKlQCm837G+4X1ePxqOd0T+YTJlyfnlfw7iyiLDEskyy2rPWsimwXWTHsUezL2CDsJ85PHHuuE94b%2fwUIYSwyhlP5CEWcKlzNZHcSAvcqb9NW%2fHP%2ffJsLYwQLvtl2WZd8i%2fHoTKGfxv+I%2fiX37eatVqlf+z+kfvfu%2f2f1PoM+vH5W%2f9bbWjPv93G3P5bbtLWP3KzmDfsXtLc0Hs9Y8NvEXFD8IOKDcNVJ9cVP+vZcNw43pzw6p+WrNdtb0LfCrXXd9A6S7viuht6Qvsk+wMGjD8kDOoNnf50cLhoZH60%2fbPIeMCE+aT0FOaLw9fC6bhvPt93zMjOss9+nXvz48F81oL9wtRi7JLhT6mfo8uRK3wrl1c5V2NXF9auMxIZDID1+xIAALAZUSnUYLKlkTH8%2f1Yg5fDGHEgAwHoF7bEDACIASPvRze0BgAQAWmAEVKAAFYKBDJZgBMa%2fnmTw+P3FD2D9LgcAwEwAuOgIAFCzeCzq3%2fPSvcLoAABGVNrRYD8fXzrZgEajeJGNqIG0w3SvYHmyeZCHojx5q7KyKgDAfwBYjP%2fgNJJdnQAAAARnQU1BAADY6%2fUcFKoAAAAgY0hSTQAAbZgAAHOOAADeVAAAgmQAAHjTAADDvAAAMucAABx04zkiNwAACnFJREFUeNrsnHts1FUWxz+%2f32%2fenemL0sLQ0kIfUh5ioQiCQGtFRNmCWElFWFwDEohgQNmwJVAx+pcEWERJLFZFDQ93eSgiAtsl8iyV1LYLpaWtpVBK2Q6lj5npvH6zf7QMjFOUxXUTy++bTGZy55x7z9w53zn3nHMzgtfr9aJAgYJuofo1yuXldaxZ8zEej0zv3qGsXbsQg0HL9u0F7NjxTwDS01NYsmSGstMK7j+CtLfbKSmpRpZloqN74%2fHIANTXN3Hy5FkkSSQmJkrZZQX3J0FEUUCrVSPLXtTqW1PFxvYhLe0hRFEiObm%2fsssK7k+C3AlZWRPIypqg7K6CnkmQ8vI6jhz5gZqaBjwemX79evHww4MYM2YIarX0i5NWV1+hqqoeALM5gmHDBgBQUlJNWVkNXi+MHp1MbGwUu3cfpbi4GpfLTXx8X6ZMGc3AgX395jt1qpyqqssApKWlEBxsYM+eo5SV1QKQmNiPp54aQ3R0RLf2uFweTp06y4kTZ6mvtxAcbGDo0DgefzyViIhgP9mqqnqf7QMHmklKiubs2Vr27j1Oc3M7K%2f+STWhHIdhugCB2vwFeGdRGiJkEolrxsp5CEJfLw7p1O9m27R+0t9vxeGQ8HhmNRkV+%2fn5GjnyAN998ibi47vMKQeh8%2fvLL46xduwNJkpg+fTwbN74CwOHDZ1i%2f%2fgtEUWT+%2fKnU1l7l0KHvAdBoVEiSyNat37J8eTZZWRN98+7efYzPPz+IWq1iyZIZFBaWc+LE2QC93Ny5TJqU6mdTXd01cnM%2f5tSpszidLlwuD5IkIkkieXn7eOONFxk%2f%2fkGf%2fJ49x9iw4W8AvPbaTMrLzeTmfkR7ux2tXseSRZMJPf4qNJyH238rhK4HgAcINcPsMtCGK17WUwjyzjvbyc%2ffT1CQjtBQI6mpgzAYdBQXV2CxtFFYeI6lSzexdWsOJpP+jpNqNGqCgw2AgF6vvW1chcmkJyhIz969x7Ba7aSlPURUVDjl5bVcvHiVjg4na9Z8TEREKGlpwwHQ6dSYTAaMRh2ffnoQh8PFpEmphIQYKSur5upVC62tNlas+ICIiFBSUhIAaGpqZdGi9Vy4cBmNRsWgQfEkJfWnoaGJ0tJqrl69ztKl7%2fHhh39m+PB4n+0mkx6tVsOZMxfYvr2gkxxaNSqpixHGEDAZQKXrSsYk8AKO64AIHhdIkuJdPYkgJSXV7NhRgNGoRxQF3n57HpMnjwKgtraR+fPfoa6ukaKi8+za9R1z507+VQvb7U4WL36WRYumAWCzOVi27H2OHy9Flr1s2fK1jyA3Icte3G6ZlSvnMGtWBgDXr7fxyisbKSurwmZz8dFHB0hJ6YxYmzfv9ZFjxoyJrF79RySp81i0adNuNm%2fei9XawaZNe8jLe81vLbVaorS0Go1GxUsvPcUjjwxGlr2E946EJ%2feBx9EZMgSh8xh1+EX48evOqOIGBk5TokcPgO8QfeDAaTo6nLhcbjIyUn3kAIiLi2LhwmlkZIwkM3OcX8XqXuB0uhk8OJZ58572jRkMWl599VkMBh1qtYqKiotUV1%2f5iZ6LUaMG+cgBEB5uYvHiZxBFEa1Www8%2fVHL9ehs2m4MjR4rRaFSEhZlYsOAPPnIAzJ07mZiYSFQqkeLiSl%2fecTsZvV6ZnJzZ5OS8QHp6ChkZIwgyGkAXAUH9IMgMhr5QtrmLHBI4PDDoGZiwQfGunhRBzp+%2fhEolIcteRo16IEBwxozxzJgx%2fn+yqMvlZtiwAWg0%2fkRLSOiH2RxBVdVlXC43dXWNxMebfe+73R5GjEgMmG%2fw4FgiI8O4dq2ZlhYrjY3NSJKAxdKKWq3C7fbw1lufBujZbB1IkoTV2kFFxSUSEvr55WOxsX2YMuXhn%2f8wJX+FE6tBJYLTA3ETYdJW%2fBMUBb9rgng8MnZ7B6IoIIoCvXoF%2f8bLejGZDAGjarVEUJDeR4bWVluATHBwUMBYUJAOrVbti052uwNBEHA4XBiNOhwOFwcPFvHTWzU6nRZRhI4OJ42NzX7veTweoqMj%2fXKoAFTthGPLOsnhliFqKEzeBiqj4lk9iSCSJKLRqJFlkGUZi6U1QLClxUp9fVNnjmrU079%2f5K9YVuDGDWu35Vir1d5pmErCYAh0zhs32gLGrNYOHA5XF8lUaLVq37PT6SYiIoS1axd2fUbZp6fValCpJJxON9HRvbstNtwRlwvg8J%2fg5nwhMTDli84jl4Ked8RKSDBTWHgOlUqiqKiCmTPT%2fATz8%2ffzwQf7AC+zZk1i1ao597yoWq2itLQam83hR4Iff2zgypUmJElCq5WIje3jb2yXbV6vF+FmTRmoqLiExdKCIAiYTHqiosLR6dT06hXMtWvN2O0OBgwwB5Sna2oasFhakSQxoB%2fys7CUwLfZ4LJ1lnZ14fD0bggdpHhUT03Sp04di0ajQq1WUVBwhq++OukTKiqqYPfuo77k%2fPa+wb1Ao1FRWXmJd9%2fdhdvt8VWj1q37AputA5fLTVJSf5KSov30tFoNxcWV5OV97Ru7csXChg1%2fx+Vy43A4efDBeCIigjEa9UycOByn001bm42NG3fR1mb36R05UsLs2W8xc+Yb5OTkIct3eanZWg%2f7n4P2f3cm5YIIo9+EsEFgvXLbox7cVsXDekoEGTEikdmznyAvbx8Gg47c3Hy2bStApRKpqKjDbndis3WQmfloQPn1XmA06snP38%2fRo6VERYVTW9vAtWvNiKIIyLz88tRu9QwGHevX7+SbbwoJDw%2fmwoVLNDe3IQgiBoOa+fNv6S1YkElhYTlVVfUcOnSasrJq+vePwmq1U1l5CbvdiU6nYdmy57o9znV%2ftPoOLBdAowZkECT4%2fm0oXP2TUl0bpL0Pg+cpXtYTCAKwfHk2JpOBzz47iMXSysmT%2f+JmjmI06snOzmDFiudvS2RlX8fdZgvyJcFOp4vWVhuSJGG3OwIWdTicTJ06DoNByyefHKC0tMbXEe%2fVK5jXX8%2fuloQOh5Pnn3+clhYbO3cW4PHI6PUaAMzmXqxcOcfXJASIigrjvfeWsmbNJ5w+fY6amltXYDQaFVFRYSxZ8ixTpoy+5ddOF21tdkRR9OVD%2fumTt7NT7nTd3AXoaAiUcwIuJYL0KIKIosCiRdPIzBzHsWOlXLzYCECfPuGkpj7AkCFxfsqJidFs3ry0qyKk8VV8MjPHkZwciyAImM2B96Pcbhm9Xs2qVXPIyBhBYeE57HYnMTGRpKen3PFOldvtISQkiJycF3jyyVTOnKnE6XQzcGBfHntsBJGRoQE6cXFRbNnyOkVFFZSWVtPU1IJGoyIxMZqxY4fSu3eIn%2fz06Y8ydOgABEEgMjIs0AjzeJi24873sHy%2fHk7oM1rxsJ5EkJuIjo4gO%2fuxX1QOCzMG3H0CiI83+%2fUvuvUfT2e0GTt2CGPHDrlrg29WodLTU0hPT7krHUkSGTMmmTFjkn9RNiGhn18%2fJPBsGAMJMYrn3G9JugIFCu4ygvxWcDrdWK0O3+v%2fTq%2fjv9ZToOB3RZAnnhhFTEwkoigwYMDdN9SysiYwcmQisuwlOTlW+dYU%2fN8gKP9qokDBnfGfAQA9nOAwz2UemwAAAABJRU5ErkJgggo=%22;_2f=%22data:image%2fpng;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAGlCAYAAABAwstlAAANMWlDQ1BJQ0MgUHJvZmlsZQAAeJyV13k0lG0fB%2fDfLIxlzDDGHkb2XWQPWSJL9mwpMXbDTAyplCUpRJZQtKBoU5RIJKqHLAnJklBUZCmFSJZ5%2f5Dqfc553ue81x%2f3+d2%2f+9znuu77nM%2f3OhcAXsuTRqMgASA4hB5qb2ZEcnF1I2F6AAM44AMsiHqSw2iGtrZW8I9jvgcQAABdip40GiUc3ZFJftCtapBvLz7n36D0z+8BAAAu1MXVDQChAABEv7V6KwAQvdZqRwAg7qfT6AAIfwAgkv09vQEQUQCgEOpobwyAuAoAOL+1ugoAcF5rdRMA4CLIfnQARB8AMyHEOyAEADMFwKzv7RNGBsApAIC3dxg5GACXBgDWwcFUbwDcWwCQIdNC6QB4FgBQdHF1I60teVcSwGYBABbL3739WQAVBQAyO373xO8B8HoCFKb87s3aAwIAELztYb5qqgAAgMAaATANMRizUgCYDICVdAZjqZDBWLkEgBoAqKeQw0Mjfv4vBKIN4N%2fu177550AhAJAACAlEMfIgKgodxXSEOQYTx3KU1YS1ge04+wlsIsdJXCWnP1c6IZ07g3iaJ4s3iy+Hv0GQKpS3IU%2f4vEgTKVyscOMl8XbJQ1LF0p2yR+RuyPcoxindVO7fdFz1jtob9ZMalZrD2qk61bqjepn6Dw0mDLONHht%2f3pZr2mg2Y37RosVyfkeh9XObDtsOu077ZcfrO7udepx7Xfrc0Ltuuw%2fsHtwz5PFm71svLPm+93ufD76jfmP+HwPGg3goj4I%2fhXymTtO+7PsaOhM2R58L%2fxYxv38h8vuBxYM%2fDi1HLR9eiZaN6Y5DHEXGo46hE5iOM5%2fAJLIksSaznWRPwaZynMKl4dM5M7gyCae5s4jZPDm8Z%2fjO8ucK5AmeEzq%2f4YLwRZF80QJSodiljZfFiySKJa9IX5W+JnNd9obcjckSyk2FW4qlymUqtzfd2VSuendzhXqlRuX8vYgqzfta1To1ug+21G55qPdwtS663uDR1seGT4z+Mm5AN8Q3bntq2mTWbN5i3srWmvzMss3quXU7rv1Uh22n3Qv7LkJXxkuHbseenb28vTl9zq9c+t1eC77OG3AfdB%2fa%2fUbkzcW3HsN7R8RGCt95vSd%2f8B6VHC0e8%2f3oN+4%2fITtxfTJwKugT5bPi51vTIV+oX2kzm2buzIbOhX2jz6vPVy5EfI9cPPDjwJLOUs3yoZWoVb3VhwwGAEIciUN+QbWibzBlMkdh%2fFgcWY3ZNrNLY6U5+HF8eH5Ofi4eghS3DFGLx4p3D18Yf6pAqWCr0Lgwt4iGqB%2fpjNhTcYSEnuQ+qdvS07IychT5GkWUkqFyusqwqqxawuZeDTlNmlaDDp9u5JZn+rwG1K2PjSSMD5l0moqYRW6vNV+03GTlsyPLutMWZ2dmH+lQ5PjSic15q8s+1%2fNujbumd4vusfE4uLfQs8Fr3JvHx8DXxe+If35AfeBg0GIwd4g81YTmvy8qNC2skF4R3hTxev9E5PxB1CGuKNJhhSPq0VtjLGNt4nYd3Rvvc4ySQD8eeiImMSbpaHLiyYyU5NTcU2fTctLTM85lZpzOzjqTfTXnyplbZ6%2fm3sgrPffg%2fIMLDRef5XcWdBV2Xeq6%2fLroffHYlZGrH65NX%2f96Y7rk882ZW9Olk2VTt8fuDJeP3O2v6Kxsvldfde9+afW5mowHMbXBD3fVWdZveST3mPB48cnbv1oa7jZmPg1tcmjWaBFqYbT2P7vblvTcrV28fbSjvPPwi21duK7Bl%2fndgT1qPSu9bX2Zr3b3y%2fbPvq4eiBu0HCIODb259jZsWHcEPdLy7vT7PR+kP0yNVo%2fFfrQY5xkfnLg8SZlSn1r91Pw5Y3rXF4kvU1%2fLZ6JmzeYIc33fiuapC9rfUd+fLqb%2f2LUkvvRpuXIlZtWcwctgAMBRRCTyIEoXVY0+zGTAVMcciznGYsrSwJrAdpw9CWuBbeVIwaXgUzltONu50ggZ3JnETB5Hnpe82XzZ%2fGcEcgXzhPI2nBN2Fx4UuSiaTyoQK9hYIH5J4rJkkVSx9BWZq7LX5ALkJuSvK5Qo3lS6pVyqUrbptuodtfLNd9UrNSo1K7Uitb5rV+tU69ZseaBXq39Ef9Wgbmu94SOjx8ZPTOK3obc1mDaaPd3eZN5s0WKZbIW1erajzfq5Tbttmh2nXaf9C4cux5c7e5yynXmde136XF+59e%2fKcxdyH9g9uOeNx9u9bz0LvMS8RsjvvN%2f7fPAt9pNaS5DAiaAbFAXK1H+lyOyvFKk6oHVg8eCPQ0tRy4dXjqxGM2IhDvkrSTAnMIksic1JFsnsJ7Ep2FSOU%2fg0znSuX1nCm8N3hv9nlmz4M0sKRy6RL4sXSRRLXZFaT5MShZuKt5T+yBK1is2V6vc0qzTva1Vr1+g+0K3d8lC%2fTv+PHNnWaPrUtMmseXuLeavls4jnG9utO2w7bV%2fYdR3ulutx6nXui+tXfu02kDCk9iZxWH3k5HvvUd2x9PGAycBPlGnq16Q5t%2flTi8kr9gwGwNreBwDArAGQLQ%2fglAvgUAiQIA8g7QHAexXAlgPAURuQTCKA1KMBwkJvff8ABHCCMCiBEbhCGKRBGXxHkBCWiEjEVcRzxBgSjzRDxiJrkcsoPVQsqhG1jBZDu6KL0d+YTJmOMZUyTTObMRcwj2J4MO6YWhYMizZLPMskqw4rlbWeTZEthq2KHccey%2f4KS8SGYD9ybOM4yjGM88Q9xqPwvvgpTjvObM4VrkSuGYIOoYhbk7uIe5roQVzgCeCp5JXnfcrny4%2fhvy4gKbBfYE7wvJCZ0OyGfGEJ4SgRhEiFaCBJjNQvdnrjxo0x4njxdol0yZ1SglIj0jdkjGWuyRrJcckNy5crHFd0V1JTxiqPqfy1qVA1Ts17s5m6gga3xrLmqFaONk67XqdMt2DLab0T+tEG+7fuM6QYBRj7m%2fhvCzINMaNvP2Qeb3HKMs%2fq2o4q62abAduv9hgHEUetnQ5ONOdUl1uuHW6z7vy79ff4eqTtrfH8SObzNvM54FsSwB9oG5REaQhBUg1psfuehDHTLcMzIiUOUA8+iGI77HakJJoR6xiPPOaecO8Ed+K+pM6UrNTFNI%2f0xkzl07k5YWfe5TrkNVy4lS9ZcP4SXzHnldRruOunbuaUCpddvqNYYVLZWeV5%2f2st38OSeqMn9AZ8Y0mTRWtSm+Lzzo6IrsZuWq9QX9OA1GDfm6Rhg%2fclo94fRcf7PzlN837pncmd81iYWqxYimbwMxgAgAQ24ANZMAAXCIcsqIIhBAahgvBApCLqELNIOaQHMhf5EoVH7UCdRLWhOdA26Cz0ayYSUwBTGdN3ZmPmU8yvMJKYcMwTFgKLN0sVKzurO+stNjTbHra77GzsZPY6LA+Whm3jkONI4ZjCWeFK8Rx4Kr6HcyvnZS4cVwTXa4Ip4TY3iTuDe5UYRvzEE8gzwUvhneGj883zHxRACJwUFBS8LqQt1LjBacO4cIyIgEilqJ3oBClBTEqsaWOIOJ%2f4QwmyJFbykVSItKj0C5lEWSPZFbka+SgFPYUFxTqlE8qOKmIq05vqVNPVAjebqIuoL2l0a97XOq8dq+On67xFT09ZX8yAsBVtiDKcMfpqPG0yuW3UdNZscvs3C6Ql0YpvxyZrfRsbW3u7IPsDDnmOd3Y+c3rtvOxKdFPeZe2+b%2ffZPQ0eY56sXipkf+9cnzrfL%2f6yAT6BOUHdwUIhO6l5tI+hMmER9OYI4f1hkS0HxQ+lRk0ccY1uitWIK4onHEs9TjiRncSfnJeinvo8zSf9R2ZKlmb2hzMXcgPP7bwgm89UMHXpcVHFlbPXEm6Qb7qXmt7WKt9coXRP8b5MjWStTJ3KI4Mn2xvsnlKa97Wmt+W3P+gc6mL0iPbp9XsPJA9Vv516J%2fDBaCxm%2fOrk+8+CX3xnLsyNLsgshixVriIYDABgBk4QBiNwhTQogxfr9tfdr6lH49Gu6G9Mpky5P72vYtxZRFniWSZZHVnr2RTZzrHj2GPZF7Ah2I8c3jhP3Du8L36KM4xzhSuRwEso4tbkbiF6EBd40n6ZthaY++nZVgQhUvHTst2a5J+OI2SN%2fjT8W%2fBPvy+063XKftv9Lfef3f4vtX7DAfyBtn9XG9H%2fd7dx1%2f+Ue1L1t9xs5nW757XX9V7OXPdbQlgXXF61brjm6JriR%2f3rjpvHW5Oe%2fdWW%2fbyzI+KFcFdjN62nrDehr6k%2fYkBqMGjI5E3SsMHI8Xde70s+zI92fRQdD5own5SZwnxy+lw8nfDF7+v2GblZ9tnPcx3fyuezFxwXpr7HLxr9kP4xuhS9zL98YYVrJX5lYfUyI5nBAFg7LwEAAJsxlUINJVkZm%2fzL4e7%2fHcGU8PU5kACA9QnZ6QAABACQCaCbOwIAEQB0wBioQAEqhAIJrMAYTH5eSUD+9SQAYO0sBwDAzAlwzhkAoO77oZi%2fz0v3iaQDABhTaQdCA%2fz86SRDGo3iQzKmBtPC6T6hCiTzELKSAklVRUUdAOA%2f67wHk5DqTvYAAA7ISURBVHic7d1NjNz3Xcfx78w+2Y7tJo5rjEOVh6YoNaWAcqgSIiFURYVWEEJIT9wRF4SK4AZCQoJLIwWJCxcuHCo1TaJIqE3CgyrIg+K2qKVpm0DzUMWpHSdO4ti7ftjdGQ6zf+9%2f%2f95N7Zm1vZ%2fk9ZL+mp3Z2ZnxYd%2f6%2fn7z33EVAAAAAAAAAAAAAABsJb0P2fMCm2d4pZ%2fwSoSj+xy9DW7f6P7A1deN00bXL2vELlccuo%2fbX7mtHavu9cv5eoDJDda5Pqy1sepe31SbHYj247Uj1V%2fnst%2f6md4GjwFsDetFqTkGrWO9729auKY364HqwumpX1VTtRqnqc71dtDWm7aAq2%2fY+bq53o7Ucufr5noTs+7jjG2zgtVEph2n5uuZqpo6cOCOj+39yK2fn5nZ8dler39Tr9ff1+v1rtmk5weukOFwOD8cDo4NB4OfnFta+Pe33n3x8SNHDh2uUagWazVayzVqQzdeY9uMaaY9ITWxml45Zm644c4b9u05+Bcz03NfrOpNbcLzAVvKcHlx8czXjh7%2f%2fpePHDn0eo2itdQ6lmvt0nFskwarvYxrh2q6quYO3vrFz+%2fc+dG%2fr15v54TPA2xxw+Fw%2fuTJo1964aWHH6+qszUKV3O0l41jLw8nmXg2itVMVW3%2f9ME%2f%2fKPt26%2f%2fcq%2fXm5vgOYAQvV5vdnZ21xf2XPfx08feev75zrc3ZQ9rkgmrvQxsQjVTVdtu+%2fh9X9i1a%2f8%2f9nq9NY9%2f8y37655776zP3HFb7d+%2fp3bs0DJIs7Bwto4efbuee%2faFeuzRZ+qVl4+u+f5wWIMTJ177k%2f995bFvVNWZGk1bZ2t1edhMW5ds3GB196xmaxSruX37fu2mGw%2fc+a%2ftDfXp6an60z%2f7%2fbrv%2fruq3++v%2f4hAnMFgUA8%2f9FQ9+MAjtbS0fP724XA4%2f%2fJr3%2fzd48d%2f8GqNonWmqs7V6r7WWPtZ4y4Jm2A1pyrM1Cha2z9x02%2f%2f1fT07K82d5yenqoH%2f+GP6+7P3V6dgQsI1+v16pc+dWN9+lduricf%2f04NBsPm9tkd266%2f9o03v%2feftbpv1d58rxpjmThJsJpTF2aqaq6q5vbu%2feWb9u659e+qeufHqC%2f9+R%2fU3Z+7fcynARLccMPe2r17Rz3z9A%2fP3zY9PfuJhbMnvnHmzPH3au27hGOf4jDO+qx7GkOz2T67b89tv9U+deHmW%2fbXffffNc7rAsLcd%2f9ddfMt+1u39Kb2XX%2fw7qraXqvbRu1zNC95yTXJhlL77PWZqpqdm939G+073HPvnfas4EOi3+%2fXPffeuea27XPX%2fXqNVmCztTrcTNWFf5J3cc8x5mtb7x3CuX5%2f+hfad%2frMHbeN+fBAou7vfH9q5kBVbatRsGZr7YR1ycYNVvtPcM4vCfv9qb3tO+3fv2fMhwcSdX%2fnp3pT19dowmpOe2omrO4nuFyUcfewmssmXNNVNdPr9be37+g8K%2fhw6f7O9%2fpTzXTV7F+NHauqyZaE7T2sZsoC6Gomq+a4Ypvu3Y+D6XcOgK7uR0t1+3HRJt10735CA0BX+93Bsaerqsmmom4lncYOrGe9yeqKB6vqwkkLoGviUDUmnbAAfpaN3hG8ome6t1+ICQvYyHr%2fW9ZVWRIC%2fCybthoTLCDGJKc1AIzrii4Ju2tRAQPez0a9uGJ%2fSwhwsd6vGxfdFHtYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEECwghmABMQQLiCFYQAzBAmIIFhBDsIAYggXEmCRYw84BsJFN6cU4wRIo4FJ1mzF8n+9taNwJS7CAzXBJLbGHBcTYzGCZuoD1bFobNnXCGg6Wz7SvLyyc3cyHB7a47u%2f8YLB8trZQsAY1ejGDqhouD5beaX%2fz6NG3J3x4IEn3d355sHhi5cvmzbpBTfDG3STBGrReSFXVcHn53BvtOzz37AsTPDyQpvs7v7R05q26MFLdy4u2GUvCwcqxPL9w7L%2fb33js0WdqMBis%2f1PAB8pgMKjHHn1mzW2n5o8+X1XLreOKnofVPflr0D6OvvU%2fh4bD4flCvfLy0Xr4oafGfW1AkIcfeqpeefno+evD4XBw7Pj3v1udTrSOS47XJOdhtZ94qaqWTp16%2fY35hWNPt+%2f44AOP1LcOvTjm0wAJvnXoxXrwgUfW3HZq%2fsi35+ffOFYrfajVKasdrEsyNebr61fV9MrPz6wcs1U1d%2frsu0f2XveLv9nr9aerqgaDYT35+Hdq9+4d9cmDH6terzfmUwJbzWAwqK999b%2fqr%2f%2fyn2tpabl1+%2fLZH7%2f6xD8tLs6%2fXVWnqmqhqs5U1dmqOldVi7Uar4s2TrB6K0d%2f5ZiqUbxmq2rm3LmTg15v+p1dOw%2fc3utVb%2fTih%2fXM0z+s%2f%2fi379bi4nJds3Nbzc3N1szM9BhPD1xNCwtn67XX3qzHv%2f7t+tu%2f+Up9%2fV8O1WCwOiwNh8Ph60cOfeWdd%2f%2fvxaqabx1nVo52sC5pyhpn3OnV6mQ1W1XbqmpnVe2qqo9U1bVVteeWGz%2f7O9dfd9vv9YxU8KExHA6Hbx7%2fwROvvvbNJ6vqnap6d+XyRFW9V6NJ63SNJq1mmXjR0Rp3wqoaTVdNvJpjujneOfHK4RrU8Z07f%2f6TzfIQ+OAaDJbOHf7pcw8fPvLsszVaBp6q1emqvSRcrFGsmr2sizbuHlbV6rKwuZyq1YD1q6p%2fcv6nx989+ZPnt81du3N2dtfPmbbgg2c4HA7eO3n4+R+%2f+sRX3z3x0ks1CtXJ1uXCytGOVROsSzJuQJowNRPVtqrasXLsWjl2ty6v2b597%2f6P7jn4qd07D9w6PbP9uumpuWv6%2femZMZ8fuEoGg6XFpeWz84uLp0+cPHX45Tff%2ftGPTp8+%2fmaNlnpNqN5rHfMrtzVLwXO19rysizZJsLob7ttWjmtqtKe1s1ZitfL19pVjbuX+zbuMzZRW5dMjYCtqn5nenNK0XKNpabFGETpTq0u%2f9nTVLAtP1yhUzZQ11qkN4+4tNS+613rh7eVhr%2fWPa8a%2fsyvHbK0Ga7rzc1XjRxS4fAaty2Y6WqrR736zN7VQq9NU83V7qmqfyjDWeViTboZ3a9trHe1gnavRP+p0rR+s9pQlWLD1dKerQY1+55upqZmymv2qM63Lc7X6juBYoWpMEqzmxW%2f0vabCzT%2fqdI2WjLM1OiWiWU62gyVWsDW1%2fySv2TBvJqxmgmomrTO19iTRJljt0xjGitZmTVhVo9gsdm5vV3i2RtGaqbXTVfPuYjtW9rLg6lvv0xWaCamJTxOi9v5Uc9nEqrnfRB8tUzV5sKounLQWa+3oOFOre1hNrJrztjaarkxacPWtF5b23xA3IWoum32q9qkL7VhNtBys2pxgNdqbcu1gNWNjO1TN0d5sb09VggVbR3sqan7P25vn3T9ubp9n1XSgasJYVW1+GLonk645kbTWn6zaobIUhK2ne1pD1doYtb9u9qgm+hiZjVyOSaZ7TlW%2fLlz6rffOoKkKtrbup4a2V1ODdW6rWrtdNLHLGYn1YtTdrxIqyNKelNofk77esemuVCy6z7NRqMQLtq71%2fvfmsf4H53FttUBstdcD+D9HAQAAAAAAAAAAAAAAIN3%2fA%2fPNWgCA%2fF3MAAAAAElFTkSuQmCCCg==%22;_30=%22data:image%2fpng;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAARCAIAAAC0D9CtAAAABGdBTUEAANbY1E9YMgAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGiSURBVHjaYvz%2f%2fz8DiYAFU+jhg5cXLtx9%2f+4LLy+nlpa8hpYsIyMjTj03rj%2fu71l74fxdZEEFRfG8wkBrG224CCPcbfv2XKivWfjr1x+s7snM8U1IcoOwmeA24NEABNOnbN698yyKHqCTIBrcPU2WrKiIjHYEsh2c9BctK0tMcYeomdC37sePXyAW0G0P7r8wM8yBoFs3n%2fwHgwP7L%2f79+xfI+Pnzl6VpHkR27+7zQBGQPcie3rr5JIRh76DHxASS3bHtzN8%2f%2fyCCF87fgbrt%2ffsvcD3Ll+4%2feOASnPvg%2fsuO1hVwLjACoHqA8QAXBfrB1k4HOaDjEl3hXF4+LqgeYMTBRZNS3CFOAtoAEUlIdGNmgQaVlrYcVA8wpoHmQUT377v469fvTRuOR4W1zZi25cf3X6DAAPuHi4vd1l4XEadHj1wtypsB0QY0Fe5pZHZOvn9svAsifoBJAxjTEDZcETLbw8s0Js4ZPe0AATCmgRH35vUn5BQAdFJSqgdQAzylMqLlBWBMHztyDRgPoHTNxwX0NNAP%2fPzcyGoYycg%2fAAEGABYVzxqE3YcJAAAAAElFTkSuQmCCCg==%22;_2b=document.createElement(%22div%22);_2b.setAttribute(%22id%22,%22clipperz_bookmarklet%22);_32=%22%22;_32+=%22%3Cstyle%3Ediv#ClipperzBackgroundDIV{width:290px;height:420px;padding:20px%200px%200px%2020px;margin:0px;border:0px;background-color:transparent;background-repeat:no-repeat;position:absolute;z-index:20000;top:40px;left:40px;background-image:url(%22+_2f+%22)}%3C%2fstyle%3E%22;_32+=%22%3Cdiv%20style=%5c%22border:0px;margin:0px;padding:0px;padding-left:10px;%5c%22%3E%22+%22%3Cimg%20style=%5c%22padding-top:5px;%5c%22%20src=%5c%22%22+_2e+%22%5c%22%3E%22+%22%3Ca%20href=%5c%22javascript:closeBookmarklet();%5c%22%3E%22+%22%3Cimg%20style=%5c%22padding-left:28px;padding-bottom:10px;%5c%22%20border=0%20src=%5c%22%22+_30+%22%5c%22%3E%22+%22%3C%2fa%3E%22+%22%3C%2fdiv%3E%22;if((_29!=null)&&(_2a==null)){_32+=%22%3Cdiv%20style=%5c%22width:255px;border-top:1px%20dotted%20%23336;%5c%22%3E%22+%22%3Cdiv%20style=%5c%22line-height:10pt;margin-right:10px;margin-top:5px;padding:5px%2010px;color:%23666;text-align:left;font-family:sans-serif;%5c%22%3E%22+%22%3Cp%20style=%5c%22margin:0px;font-weight:bold;font-size:10pt;font-family:sans-serif;%5c%22%3EHow%20to%20add%20a%20new%20card%20or%20a%20direct%20login%20to%20an%20existing%20card%20for%20this%20website:%3C%2fp%3E%22+%22%3Col%20style=%5c%22padding:0px%200px%200px%2020px;font-size:9pt;font-family:sans-serif;%5c%22%3E%22+%22%3Cli%3ECopy%20the%20content%20of%20the%20text%20area%20below(Ctrl-C)%3C%2fli%3E%22+%22%3Cli%3EGo%20to%20your%20Clipperz%20account%3C%2fli%3E%22+%22%3Cli%3EClick%20%5c%22Add%20new%20card%5c%22%20or%20select%20the%20related%20card%3C%2fli%3E%22+%22%3Cli%3EPaste%20the%20direct%20login%20configuration(Ctrl-V)%3C%2fli%3E%22+%22%3Cli%3EComplete%20and%20review%20the%20details,then%20click%20%5c%22Save%5c%22%3C%2fli%3E%22+%22%3C%2fol%3E%22+%22%3C%2fdiv%3E%22+%22%3C%2fdiv%3E%22;_32+=%22%3Ctextarea%20id=%5c%22bookmarklet_textarea%5c%22%20style=%5c%22border:2px%20solid%20%23333366;font-family:sans-serif;font-size:8pt;color:%23336;width:240px;height:135px;padding:4px;background-color:white;margin:0px%2010px;%5c%22%3E%22+sj(_29)+%22%3C%2ftextarea%3E%22;}else{if((_29==null)&&(_2a==null)){_32+=%22%3Cdiv%3ENo%20login%20form%20has%20been%20found%20on%20the%20page%3C%2fdiv%3E%3Cdiv%3EGet%20some%20help%20%3Ca%20href=%5c%22%23%5c%22%3Ehere%3C%2fa%3E%3C%2fdiv%3E%22;}else{_32+=%22%3Cdiv%3EAn%20error%20happened%20while%20processing%20the%20page%3C%2fdiv%3E%3Cdiv%3EGet%20some%20help%20%3Ca%20href=%5c%22%23%5c%22%3Ehere%3C%2fa%3E%3C%2fdiv%3E%3Cdiv%3E%22+_2a.name+%22%20-%20%22+_2a.message+%22%3C%2fdiv%3E%22;}}_2b.innerHTML=%22%3Cdiv%20id=%5c%22ClipperzBackgroundDIV%5c%22%3E%22+_32+%22%3C%2fdiv%3E%22;document.body.appendChild(_2b);if((_29!=null)&&(_2a==null)){_31=document.getElementById(%22bookmarklet_textarea%22);_31.focus();_31.select();}};getLoginFormConfiguration=function(){var%20_33;try{_33={};_33.page=pp();_33.form=fp(flf(document,0));_33.version=%220.2.3%22;lfp(_33,_cble);}catch(e){lfp(_33,e);}};getLoginFormConfiguration();', 'CrossWindowsBookmarklet_TEST');
+ console.log("runBookmarkletScript");
+};
+
+init = function () {
+ MochiKit.Signal.connect('newWindow', 'onclick', newWindow);
+ MochiKit.Signal.connect('runBookmarkletScript', 'onclick', runBookmarkletScript);
+};
+
+MochiKit.DOM.addLoadEvent(init);
diff --git a/frontend/gamma/tests/tests/Components/crossWindowsBookmarklet/index.html b/frontend/gamma/tests/tests/Components/crossWindowsBookmarklet/index.html
new file mode 100644
index 0000000..10e2f2e
--- a/dev/null
+++ b/frontend/gamma/tests/tests/Components/crossWindowsBookmarklet/index.html
@@ -0,0 +1,73 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Cross Window Bookmarklet execution - test</title>
+ <script type="text/javascript" src="../../../../js/MochiKit/MochiKit.js"></script>
+ <script type='text/javascript' src='../../../../js/JSON/json2.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/Utils.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/YUI/DomHelper.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Base.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Date.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/DOM.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/ByteArray.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Logging.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Async.js'></script>
+
+ <script type='text/javascript' src='../../../../js/Clipperz/Signal.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Style.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Visual.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/Set.js'></script>
+ <script type='text/javascript' src='../../../../js/Clipperz/KeyValueObjectStore.js'></script>
+
+ <script type='text/javascript' src='./CrossWindowsBookmarklet_test.js'></script>
+<script>
+ Clipperz_IEisBroken = false;
+</script>
+
+<!--[if IE]><script>
+Clipperz_IEisBroken = true;
+</script><![endif]-->
+
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/clipperz.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/compact.css" />
+ <link rel="stylesheet" type="text/css" href="../../../../css/clipperz/ytheme-clipperz.css" />
+
+</head>
+<body>
+
+<div id="tableWrapper"></div>
+
+<ul>
+ <li><a href="#" id="newWindow">open window</a></li>
+ <li><a href="#" id="runBookmarkletScript">run bookmarklet script</a></li>
+</ul>
+</body>
+</html>
diff --git a/frontend/gamma/tests/tests/index.html b/frontend/gamma/tests/tests/index.html
new file mode 100644
index 0000000..75b8e95
--- a/dev/null
+++ b/frontend/gamma/tests/tests/index.html
@@ -0,0 +1,48 @@
+<!--
+
+Copyright 2008-2011 Clipperz Srl
+
+This file is part of Clipperz's Javascript Crypto Library.
+Javascript Crypto Library provides web developers with an extensive
+and efficient set of cryptographic functions. The library aims to
+obtain maximum execution speed while preserving modularity and
+reusability.
+For further information about its features and functionalities please
+refer to http://www.clipperz.com
+
+* Javascript Crypto Library is free software: you can redistribute
+ it and/or modify it under the terms of the GNU Affero General Public
+ License as published by the Free Software Foundation, either version
+ 3 of the License, or (at your option) any later version.
+
+* Javascript Crypto Library is distributed in the hope that it will
+ be useful, but WITHOUT ANY WARRANTY; without even the implied
+ warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU Affero General Public License for more details.
+
+* You should have received a copy of the GNU Affero General Public
+ License along with Javascript Crypto Library. If not, see
+ <http://www.gnu.org/licenses/>.
+
+-->
+
+<html>
+<head>
+ <title>Complete TEST suite</title>
+ <script type="text/javascript" src="../../js/MochiKit/MochiKit.js"></script>
+ <script type="text/javascript" src="../SimpleTest/TestRunner.js"></script>
+</head>
+<body>
+<script>
+TestRunner.runTests(
+ 'Clipperz/index.html',
+ 'Clipperz/Crypto/index.html',
+ 'Clipperz/PM/index.html',
+ 'Clipperz/PM/DataModel/index.html',
+ 'Clipperz/PM/UI/index.html',
+ 'Clipperz/PM/UI/Web/index.html',
+ 'Clipperz/PM/UI/Web/Controllers/index.html'
+);
+</script>
+</body>
+</html> \ No newline at end of file