diff --git a/SafeExamBrowser.Browser.Contracts/Events/DownloadFinishedCallback.cs b/SafeExamBrowser.Browser.Contracts/Events/DownloadFinishedCallback.cs index 3789f506..57c4d674 100644 --- a/SafeExamBrowser.Browser.Contracts/Events/DownloadFinishedCallback.cs +++ b/SafeExamBrowser.Browser.Contracts/Events/DownloadFinishedCallback.cs @@ -9,8 +9,8 @@ namespace SafeExamBrowser.Browser.Contracts.Events { /// - /// Defines the method signature for callbacks to be executed once a download has been finished. Indicates whether the download was - /// successful, and if so, where it was saved. + /// Defines the method signature for callbacks to be executed once a download has been finished. Indicates the URL of the resource, + /// whether the download was successful, and if so, where it was saved. /// - public delegate void DownloadFinishedCallback(bool success, string filePath = null); + public delegate void DownloadFinishedCallback(bool success, string url, string filePath = null); } diff --git a/SafeExamBrowser.Browser/BrowserApplication.cs b/SafeExamBrowser.Browser/BrowserApplication.cs index 7612f1b6..3950afff 100644 --- a/SafeExamBrowser.Browser/BrowserApplication.cs +++ b/SafeExamBrowser.Browser/BrowserApplication.cs @@ -145,7 +145,7 @@ namespace SafeExamBrowser.Browser var id = ++instanceIdCounter; var isMainInstance = instances.Count == 0; var instanceLogger = logger.CloneFor($"Browser Instance #{id}"); - var startUrl = url ?? settings.StartUrl; + var startUrl = url ?? GenerateStartUrl(); var instance = new BrowserApplicationInstance(appConfig, settings, id, isMainInstance, fileSystemDialog, messageBox, instanceLogger, text, uiFactory, startUrl); instance.ConfigurationDownloadRequested += (fileName, args) => ConfigurationDownloadRequested?.Invoke(fileName, args); @@ -201,6 +201,18 @@ namespace SafeExamBrowser.Browser } } + private string GenerateStartUrl() + { + var url = settings.StartUrl; + + if (settings.UseQueryParameter) + { + url = $"{url}{settings.StartUrlQuery}"; + } + + return url; + } + private void InitializeApplicationInfo() { AutoStart = true; diff --git a/SafeExamBrowser.Browser/Handlers/DownloadHandler.cs b/SafeExamBrowser.Browser/Handlers/DownloadHandler.cs index 7a20f00f..a1b74a18 100644 --- a/SafeExamBrowser.Browser/Handlers/DownloadHandler.cs +++ b/SafeExamBrowser.Browser/Handlers/DownloadHandler.cs @@ -92,7 +92,7 @@ namespace SafeExamBrowser.Browser.Handlers if (callbacks.TryRemove(downloadItem.Id, out DownloadFinishedCallback finished) && finished != null) { - Task.Run(() => finished.Invoke(downloadItem.IsComplete, downloadItem.FullPath)); + Task.Run(() => finished.Invoke(downloadItem.IsComplete, downloadItem.Url, downloadItem.FullPath)); } if (hasId) diff --git a/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs b/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs index 103b117a..f861b581 100644 --- a/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs +++ b/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs @@ -615,13 +615,13 @@ namespace SafeExamBrowser.Client.UnitTests var args = new DownloadEventArgs(); appConfig.TemporaryDirectory = @"C:\Folder\Does\Not\Exist"; - runtimeProxy.Setup(r => r.RequestReconfiguration(It.IsAny())).Returns(new CommunicationResult(true)); + runtimeProxy.Setup(r => r.RequestReconfiguration(It.IsAny(), It.IsAny())).Returns(new CommunicationResult(true)); sut.TryStart(); browser.Raise(b => b.ConfigurationDownloadRequested += null, "filepath.seb", args); args.Callback(true, string.Empty); - runtimeProxy.Verify(r => r.RequestReconfiguration(It.IsAny()), Times.Once); + runtimeProxy.Verify(r => r.RequestReconfiguration(It.IsAny(), It.IsAny()), Times.Once); Assert.IsTrue(args.AllowDownload); } @@ -633,13 +633,13 @@ namespace SafeExamBrowser.Client.UnitTests appConfig.TemporaryDirectory = @"C:\Folder\Does\Not\Exist"; settings.Security.AllowReconfiguration = true; settings.Security.QuitPasswordHash = "abc123"; - runtimeProxy.Setup(r => r.RequestReconfiguration(It.IsAny())).Returns(new CommunicationResult(true)); + runtimeProxy.Setup(r => r.RequestReconfiguration(It.IsAny(), It.IsAny())).Returns(new CommunicationResult(true)); sut.TryStart(); browser.Raise(b => b.ConfigurationDownloadRequested += null, "filepath.seb", args); args.Callback(true, string.Empty); - runtimeProxy.Verify(r => r.RequestReconfiguration(It.IsAny()), Times.Once); + runtimeProxy.Verify(r => r.RequestReconfiguration(It.IsAny(), It.IsAny()), Times.Once); Assert.IsTrue(args.AllowDownload); } @@ -652,13 +652,13 @@ namespace SafeExamBrowser.Client.UnitTests settings.Security.AllowReconfiguration = true; settings.Security.QuitPasswordHash = "abc123"; settings.Security.ReconfigurationUrl = "sebs://www.somehost.org/some/path/*.seb?query=123"; - runtimeProxy.Setup(r => r.RequestReconfiguration(It.IsAny())).Returns(new CommunicationResult(true)); + runtimeProxy.Setup(r => r.RequestReconfiguration(It.IsAny(), It.IsAny())).Returns(new CommunicationResult(true)); sut.TryStart(); browser.Raise(b => b.ConfigurationDownloadRequested += null, "filepath.seb", args); args.Callback(true, string.Empty); - runtimeProxy.Verify(r => r.RequestReconfiguration(It.IsAny()), Times.Once); + runtimeProxy.Verify(r => r.RequestReconfiguration(It.IsAny(), It.IsAny()), Times.Once); Assert.IsTrue(args.AllowDownload); } @@ -673,7 +673,7 @@ namespace SafeExamBrowser.Client.UnitTests sut.TryStart(); browser.Raise(b => b.ConfigurationDownloadRequested += null, "filepath.seb", args); - runtimeProxy.Verify(r => r.RequestReconfiguration(It.IsAny()), Times.Never); + runtimeProxy.Verify(r => r.RequestReconfiguration(It.IsAny(), It.IsAny()), Times.Never); Assert.IsFalse(args.AllowDownload); } @@ -689,7 +689,7 @@ namespace SafeExamBrowser.Client.UnitTests sut.TryStart(); browser.Raise(b => b.ConfigurationDownloadRequested += null, "filepath.seb", args); - runtimeProxy.Verify(r => r.RequestReconfiguration(It.IsAny()), Times.Never); + runtimeProxy.Verify(r => r.RequestReconfiguration(It.IsAny(), It.IsAny()), Times.Never); Assert.IsFalse(args.AllowDownload); } @@ -697,6 +697,7 @@ namespace SafeExamBrowser.Client.UnitTests public void Reconfiguration_MustCorrectlyHandleDownload() { var downloadPath = @"C:\Folder\Does\Not\Exist\filepath.seb"; + var downloadUrl = @"https://www.host.abc/someresource.seb"; var filename = "filepath.seb"; var args = new DownloadEventArgs(); @@ -708,13 +709,15 @@ namespace SafeExamBrowser.Client.UnitTests It.IsAny(), It.IsAny(), It.IsAny())).Returns(MessageBoxResult.Yes); - runtimeProxy.Setup(r => r.RequestReconfiguration(It.Is(p => p == downloadPath))).Returns(new CommunicationResult(true)); + runtimeProxy.Setup(r => r.RequestReconfiguration( + It.Is(p => p == downloadPath), + It.Is(u => u == downloadUrl))).Returns(new CommunicationResult(true)); sut.TryStart(); browser.Raise(b => b.ConfigurationDownloadRequested += null, filename, args); - args.Callback(true, downloadPath); + args.Callback(true, downloadUrl, downloadPath); - runtimeProxy.Verify(r => r.RequestReconfiguration(It.Is(p => p == downloadPath)), Times.Once); + runtimeProxy.Verify(r => r.RequestReconfiguration(It.Is(p => p == downloadPath), It.Is(u => u == downloadUrl)), Times.Once); Assert.AreEqual(downloadPath, args.DownloadPath); Assert.IsTrue(args.AllowDownload); @@ -724,6 +727,7 @@ namespace SafeExamBrowser.Client.UnitTests public void Reconfiguration_MustCorrectlyHandleFailedDownload() { var downloadPath = @"C:\Folder\Does\Not\Exist\filepath.seb"; + var downloadUrl = @"https://www.host.abc/someresource.seb"; var filename = "filepath.seb"; var args = new DownloadEventArgs(); @@ -735,19 +739,22 @@ namespace SafeExamBrowser.Client.UnitTests It.IsAny(), It.IsAny(), It.IsAny())).Returns(MessageBoxResult.Yes); - runtimeProxy.Setup(r => r.RequestReconfiguration(It.Is(p => p == downloadPath))).Returns(new CommunicationResult(true)); + runtimeProxy.Setup(r => r.RequestReconfiguration( + It.Is(p => p == downloadPath), + It.Is(u => u == downloadUrl))).Returns(new CommunicationResult(true)); sut.TryStart(); browser.Raise(b => b.ConfigurationDownloadRequested += null, filename, args); args.Callback(false, downloadPath); - runtimeProxy.Verify(r => r.RequestReconfiguration(It.IsAny()), Times.Never); + runtimeProxy.Verify(r => r.RequestReconfiguration(It.IsAny(), It.IsAny()), Times.Never); } [TestMethod] public void Reconfiguration_MustCorrectlyHandleFailedRequest() { var downloadPath = @"C:\Folder\Does\Not\Exist\filepath.seb"; + var downloadUrl = @"https://www.host.abc/someresource.seb"; var filename = "filepath.seb"; var args = new DownloadEventArgs(); @@ -759,13 +766,15 @@ namespace SafeExamBrowser.Client.UnitTests It.IsAny(), It.IsAny(), It.IsAny())).Returns(MessageBoxResult.Yes); - runtimeProxy.Setup(r => r.RequestReconfiguration(It.Is(p => p == downloadPath))).Returns(new CommunicationResult(false)); + runtimeProxy.Setup(r => r.RequestReconfiguration( + It.Is(p => p == downloadPath), + It.Is(u => u == downloadUrl))).Returns(new CommunicationResult(false)); sut.TryStart(); browser.Raise(b => b.ConfigurationDownloadRequested += null, filename, args); - args.Callback(true, downloadPath); + args.Callback(true, downloadUrl, downloadPath); - runtimeProxy.Verify(r => r.RequestReconfiguration(It.IsAny()), Times.Once); + runtimeProxy.Verify(r => r.RequestReconfiguration(It.IsAny(), It.IsAny()), Times.Once); messageBox.Verify(m => m.Show( It.IsAny(), It.IsAny(), diff --git a/SafeExamBrowser.Client/ClientController.cs b/SafeExamBrowser.Client/ClientController.cs index 7408309e..83a0438c 100644 --- a/SafeExamBrowser.Client/ClientController.cs +++ b/SafeExamBrowser.Client/ClientController.cs @@ -374,6 +374,31 @@ namespace SafeExamBrowser.Client } } + private void Browser_ConfigurationDownloadFinished(bool success, string url, string filePath = null) + { + if (success) + { + var communication = runtime.RequestReconfiguration(filePath, url); + + if (communication.Success) + { + logger.Info($"Sent reconfiguration request for '{filePath}' to the runtime."); + } + else + { + logger.Error($"Failed to communicate reconfiguration request for '{filePath}'!"); + messageBox.Show(TextKey.MessageBox_ReconfigurationError, TextKey.MessageBox_ReconfigurationErrorTitle, icon: MessageBoxIcon.Error, parent: splashScreen); + splashScreen.Hide(); + } + } + else + { + logger.Error($"Failed to download configuration file '{filePath}'!"); + messageBox.Show(TextKey.MessageBox_ConfigurationDownloadError, TextKey.MessageBox_ConfigurationDownloadErrorTitle, icon: MessageBoxIcon.Error, parent: splashScreen); + splashScreen.Hide(); + } + } + private void Browser_SessionIdentifierDetected(string identifier) { if (Settings.SessionMode == SessionMode.Server) @@ -397,31 +422,6 @@ namespace SafeExamBrowser.Client TryRequestShutdown(); } - private void Browser_ConfigurationDownloadFinished(bool success, string filePath = null) - { - if (success) - { - var communication = runtime.RequestReconfiguration(filePath); - - if (communication.Success) - { - logger.Info($"Sent reconfiguration request for '{filePath}' to the runtime."); - } - else - { - logger.Error($"Failed to communicate reconfiguration request for '{filePath}'!"); - messageBox.Show(TextKey.MessageBox_ReconfigurationError, TextKey.MessageBox_ReconfigurationErrorTitle, icon: MessageBoxIcon.Error, parent: splashScreen); - splashScreen.Hide(); - } - } - else - { - logger.Error($"Failed to download configuration file '{filePath}'!"); - messageBox.Show(TextKey.MessageBox_ConfigurationDownloadError, TextKey.MessageBox_ConfigurationDownloadErrorTitle, icon: MessageBoxIcon.Error, parent: splashScreen); - splashScreen.Hide(); - } - } - private void ClientHost_ExamSelectionRequested(ExamSelectionRequestEventArgs args) { logger.Info($"Received exam selection request with id '{args.RequestId}'."); diff --git a/SafeExamBrowser.Communication.Contracts/Data/ReconfigurationMessage.cs b/SafeExamBrowser.Communication.Contracts/Data/ReconfigurationMessage.cs index a658d9b5..29790395 100644 --- a/SafeExamBrowser.Communication.Contracts/Data/ReconfigurationMessage.cs +++ b/SafeExamBrowser.Communication.Contracts/Data/ReconfigurationMessage.cs @@ -21,9 +21,15 @@ namespace SafeExamBrowser.Communication.Contracts.Data /// public string ConfigurationPath { get; private set; } - public ReconfigurationMessage(string path) + /// + /// The original URL from where the configuration file was downloaded. + /// + public string ResourceUrl { get; set; } + + public ReconfigurationMessage(string path, string url) { ConfigurationPath = path; + ResourceUrl = url; } } } diff --git a/SafeExamBrowser.Communication.Contracts/Events/ReconfigurationEventArgs.cs b/SafeExamBrowser.Communication.Contracts/Events/ReconfigurationEventArgs.cs index b924e6a1..9c6b8a65 100644 --- a/SafeExamBrowser.Communication.Contracts/Events/ReconfigurationEventArgs.cs +++ b/SafeExamBrowser.Communication.Contracts/Events/ReconfigurationEventArgs.cs @@ -17,5 +17,10 @@ namespace SafeExamBrowser.Communication.Contracts.Events /// The full path to the configuration file to be used for reconfiguration. /// public string ConfigurationPath { get; set; } + + /// + /// The original URL from where the configuration file was downloaded. + /// + public string ResourceUrl { get; set; } } } diff --git a/SafeExamBrowser.Communication.Contracts/Proxies/IRuntimeProxy.cs b/SafeExamBrowser.Communication.Contracts/Proxies/IRuntimeProxy.cs index 489e7e2f..b02fbbc0 100644 --- a/SafeExamBrowser.Communication.Contracts/Proxies/IRuntimeProxy.cs +++ b/SafeExamBrowser.Communication.Contracts/Proxies/IRuntimeProxy.cs @@ -34,7 +34,7 @@ namespace SafeExamBrowser.Communication.Contracts.Proxies /// /// Requests the runtime to reconfigure the application with the specified configuration. /// - CommunicationResult RequestReconfiguration(string filePath); + CommunicationResult RequestReconfiguration(string filePath, string url); /// /// Submits the result of a server exam selection previously requested by the runtime. If the procedure was aborted by the user, diff --git a/SafeExamBrowser.Communication.UnitTests/Hosts/BaseHostTests.cs b/SafeExamBrowser.Communication.UnitTests/Hosts/BaseHostTests.cs index b591fb28..849ec1e6 100644 --- a/SafeExamBrowser.Communication.UnitTests/Hosts/BaseHostTests.cs +++ b/SafeExamBrowser.Communication.UnitTests/Hosts/BaseHostTests.cs @@ -257,7 +257,7 @@ namespace SafeExamBrowser.Communication.UnitTests.Hosts { var received = false; var simpleReceived = false; - var message = new ReconfigurationMessage(null); + var message = new ReconfigurationMessage(null, null); var configurationResponse = new ConfigurationResponse(); sut.OnReceiveStub = (m) => { received = true; return configurationResponse; }; diff --git a/SafeExamBrowser.Communication.UnitTests/Proxies/RuntimeProxyTests.cs b/SafeExamBrowser.Communication.UnitTests/Proxies/RuntimeProxyTests.cs index 72225160..0cc05523 100644 --- a/SafeExamBrowser.Communication.UnitTests/Proxies/RuntimeProxyTests.cs +++ b/SafeExamBrowser.Communication.UnitTests/Proxies/RuntimeProxyTests.cs @@ -101,24 +101,26 @@ namespace SafeExamBrowser.Communication.UnitTests.Proxies [TestMethod] public void MustCorrectlyRequestReconfiguration() { - var url = "file:///C:/Some/file/url.seb"; + var path = "file:///C:/Some/file/url.seb"; + var url = @"https://www.host.abc/someresource.seb"; - proxy.Setup(p => p.Send(It.Is(m => m.ConfigurationPath == url))).Returns(new SimpleResponse(SimpleResponsePurport.Acknowledged)); + proxy.Setup(p => p.Send(It.Is(m => m.ConfigurationPath == path))).Returns(new SimpleResponse(SimpleResponsePurport.Acknowledged)); - var communication = sut.RequestReconfiguration(url); + var communication = sut.RequestReconfiguration(path, url); Assert.IsTrue(communication.Success); - proxy.Verify(p => p.Send(It.Is(m => m.ConfigurationPath == url)), Times.Once); + proxy.Verify(p => p.Send(It.Is(m => m.ConfigurationPath == path && m.ResourceUrl == url)), Times.Once); } [TestMethod] public void MustFailIfReconfigurationRequestNotAcknowledged() { - var url = "file:///C:/Some/file/url.seb"; + var path = "file:///C:/Some/file/url.seb"; + var url = @"https://www.host.abc/someresource.seb"; - proxy.Setup(p => p.Send(It.Is(m => m.ConfigurationPath == url))).Returns(null); + proxy.Setup(p => p.Send(It.Is(m => m.ConfigurationPath == path))).Returns(null); - var communication = sut.RequestReconfiguration(url); + var communication = sut.RequestReconfiguration(path, url); Assert.IsFalse(communication.Success); } @@ -201,7 +203,7 @@ namespace SafeExamBrowser.Communication.UnitTests.Proxies var configuration = sut.GetConfiguration(); var message = sut.SubmitMessageBoxResult(default(Guid), default(int)); var password = sut.SubmitPassword(default(Guid), false); - var reconfiguration = sut.RequestReconfiguration(null); + var reconfiguration = sut.RequestReconfiguration(null, null); var shutdown = sut.RequestShutdown(); Assert.IsFalse(client.Success); diff --git a/SafeExamBrowser.Communication/Proxies/RuntimeProxy.cs b/SafeExamBrowser.Communication/Proxies/RuntimeProxy.cs index bd153f0e..27e6ef34 100644 --- a/SafeExamBrowser.Communication/Proxies/RuntimeProxy.cs +++ b/SafeExamBrowser.Communication/Proxies/RuntimeProxy.cs @@ -75,11 +75,11 @@ namespace SafeExamBrowser.Communication.Proxies } } - public CommunicationResult RequestReconfiguration(string filePath) + public CommunicationResult RequestReconfiguration(string filePath, string url) { try { - var response = Send(new ReconfigurationMessage(filePath)); + var response = Send(new ReconfigurationMessage(filePath, url)); var success = IsAcknowledged(response); if (success) diff --git a/SafeExamBrowser.Configuration/ConfigurationData/DataMapping/BrowserDataMapper.cs b/SafeExamBrowser.Configuration/ConfigurationData/DataMapping/BrowserDataMapper.cs index 56935300..e007c9e5 100644 --- a/SafeExamBrowser.Configuration/ConfigurationData/DataMapping/BrowserDataMapper.cs +++ b/SafeExamBrowser.Configuration/ConfigurationData/DataMapping/BrowserDataMapper.cs @@ -141,6 +141,9 @@ namespace SafeExamBrowser.Configuration.ConfigurationData.DataMapping case Keys.Browser.UserAgentSuffix: MapUserAgentSuffix(settings, value); break; + case Keys.Browser.UseStartUrlQuery: + MapUseStartUrlQuery(settings, value); + break; } } @@ -458,6 +461,14 @@ namespace SafeExamBrowser.Configuration.ConfigurationData.DataMapping } } + private void MapUseStartUrlQuery(AppSettings settings, object value) + { + if (value is bool use) + { + settings.Browser.UseQueryParameter = use; + } + } + private void MapFilterRules(AppSettings settings, object value) { const int ALLOW = 1; diff --git a/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs b/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs index eda77d81..8056f9b1 100644 --- a/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs +++ b/SafeExamBrowser.Configuration/ConfigurationData/DataValues.cs @@ -140,6 +140,8 @@ namespace SafeExamBrowser.Configuration.ConfigurationData settings.Browser.Proxy.Policy = ProxyPolicy.System; settings.Browser.ResetOnQuitUrl = false; settings.Browser.StartUrl = "https://www.safeexambrowser.org/start"; + settings.Browser.UseCustomUserAgent = false; + settings.Browser.UseQueryParameter = false; settings.ConfigurationMode = ConfigurationMode.Exam; diff --git a/SafeExamBrowser.Configuration/ConfigurationData/Keys.cs b/SafeExamBrowser.Configuration/ConfigurationData/Keys.cs index 3cb142d6..e2bab348 100644 --- a/SafeExamBrowser.Configuration/ConfigurationData/Keys.cs +++ b/SafeExamBrowser.Configuration/ConfigurationData/Keys.cs @@ -70,6 +70,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData internal const string UserAgentModeDesktop = "browserUserAgentWinDesktopMode"; internal const string UserAgentModeMobile = "browserUserAgentWinTouchMode"; internal const string UserAgentSuffix = "browserUserAgent"; + internal const string UseStartUrlQuery = "startURLAppendQueryParameter"; internal static class AdditionalWindow { diff --git a/SafeExamBrowser.Runtime.UnitTests/Communication/RuntimeHostTests.cs b/SafeExamBrowser.Runtime.UnitTests/Communication/RuntimeHostTests.cs index a8ddd580..3a897af3 100644 --- a/SafeExamBrowser.Runtime.UnitTests/Communication/RuntimeHostTests.cs +++ b/SafeExamBrowser.Runtime.UnitTests/Communication/RuntimeHostTests.cs @@ -266,6 +266,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication { var args = default(ReconfigurationEventArgs); var path = "C:\\Temp\\Some\\File.seb"; + var url = @"https://www.host.abc/someresource.seb"; var sync = new AutoResetEvent(false); sut.AllowConnection = true; @@ -273,7 +274,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication sut.AuthenticationToken = Guid.Empty; var token = sut.Connect(Guid.Empty).CommunicationToken.Value; - var message = new ReconfigurationMessage(path) { CommunicationToken = token }; + var message = new ReconfigurationMessage(path, url) { CommunicationToken = token }; var response = sut.Send(message); sync.WaitOne(); @@ -283,6 +284,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication Assert.IsInstanceOfType(response, typeof(SimpleResponse)); Assert.AreEqual(SimpleResponsePurport.Acknowledged, (response as SimpleResponse)?.Purport); Assert.AreEqual(path, args.ConfigurationPath); + Assert.AreEqual(url, args.ResourceUrl); } [TestMethod] @@ -320,7 +322,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Communication sut.Send(new SimpleMessage(SimpleMessagePurport.RequestShutdown) { CommunicationToken = token }); sut.Send(new MessageBoxReplyMessage(Guid.Empty, (int) MessageBoxResult.Cancel) { CommunicationToken = token }); sut.Send(new PasswordReplyMessage(Guid.Empty, false, "") { CommunicationToken = token }); - sut.Send(new ReconfigurationMessage("") { CommunicationToken = token }); + sut.Send(new ReconfigurationMessage("", "") { CommunicationToken = token }); sut.Disconnect(new DisconnectionMessage { CommunicationToken = token }); } diff --git a/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs b/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs index 789414d0..f48da372 100644 --- a/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs +++ b/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs @@ -70,7 +70,7 @@ namespace SafeExamBrowser.Runtime.Communication PasswordReceived?.InvokeAsync(new PasswordReplyEventArgs { Password = m.Password, RequestId = m.RequestId, Success = m.Success }); return new SimpleResponse(SimpleResponsePurport.Acknowledged); case ReconfigurationMessage m: - ReconfigurationRequested?.InvokeAsync(new ReconfigurationEventArgs { ConfigurationPath = m.ConfigurationPath }); + ReconfigurationRequested?.InvokeAsync(new ReconfigurationEventArgs { ConfigurationPath = m.ConfigurationPath, ResourceUrl = m.ResourceUrl }); return new SimpleResponse(SimpleResponsePurport.Acknowledged); case ServerFailureActionReplyMessage m: ServerFailureActionReceived?.InvokeAsync(new ServerFailureActionReplyEventArgs { Abort = m.Abort, Fallback = m.Fallback, RequestId = m.RequestId, Retry = m.Retry }); diff --git a/SafeExamBrowser.Runtime/Operations/ConfigurationOperation.cs b/SafeExamBrowser.Runtime/Operations/ConfigurationOperation.cs index 8e642465..7614625a 100644 --- a/SafeExamBrowser.Runtime/Operations/ConfigurationOperation.cs +++ b/SafeExamBrowser.Runtime/Operations/ConfigurationOperation.cs @@ -191,6 +191,8 @@ namespace SafeExamBrowser.Runtime.Operations { result = OperationResult.Success; } + + HandleStartUrlQuery(uri, source); } else { @@ -230,6 +232,19 @@ namespace SafeExamBrowser.Runtime.Operations return result; } + private void HandleStartUrlQuery(Uri uri, UriSource source) + { + if (source == UriSource.Reconfiguration && Uri.TryCreate(Context.ReconfigurationUrl, UriKind.Absolute, out var reconfigurationUri)) + { + uri = reconfigurationUri; + } + + if (uri != default(Uri) && uri.Query.LastIndexOf('?') > 0) + { + Context.Next.Settings.Browser.StartUrlQuery = uri.Query.Substring(uri.Query.LastIndexOf('?')); + } + } + private bool? TryConfigureClient(Uri uri, PasswordParameters passwordParams, string currentPassword = default(string)) { var mustAuthenticate = IsRequiredToAuthenticateForClientConfiguration(passwordParams, currentPassword); diff --git a/SafeExamBrowser.Runtime/RuntimeController.cs b/SafeExamBrowser.Runtime/RuntimeController.cs index 2b7ba6f8..1b5255a7 100644 --- a/SafeExamBrowser.Runtime/RuntimeController.cs +++ b/SafeExamBrowser.Runtime/RuntimeController.cs @@ -345,7 +345,9 @@ namespace SafeExamBrowser.Runtime private void RuntimeHost_ReconfigurationRequested(ReconfigurationEventArgs args) { logger.Info($"Accepted request for reconfiguration with '{args.ConfigurationPath}'."); + sessionContext.ReconfigurationFilePath = args.ConfigurationPath; + sessionContext.ReconfigurationUrl = args.ResourceUrl; StartSession(); } diff --git a/SafeExamBrowser.Runtime/SessionContext.cs b/SafeExamBrowser.Runtime/SessionContext.cs index 957c27bd..81925a35 100644 --- a/SafeExamBrowser.Runtime/SessionContext.cs +++ b/SafeExamBrowser.Runtime/SessionContext.cs @@ -41,5 +41,10 @@ namespace SafeExamBrowser.Runtime /// The path of the configuration file to be used for reconfiguration. /// internal string ReconfigurationFilePath { get; set; } + + /// + /// The original URL from where the configuration file was downloaded. + /// + internal string ReconfigurationUrl { get; set; } } } diff --git a/SafeExamBrowser.Settings/Browser/BrowserSettings.cs b/SafeExamBrowser.Settings/Browser/BrowserSettings.cs index 46f8142f..92cbff69 100644 --- a/SafeExamBrowser.Settings/Browser/BrowserSettings.cs +++ b/SafeExamBrowser.Settings/Browser/BrowserSettings.cs @@ -158,11 +158,21 @@ namespace SafeExamBrowser.Settings.Browser /// public string StartUrl { get; set; } + /// + /// A query for the which SEB automatically extracts from the configuration URL. + /// + public string StartUrlQuery { get; set; } + /// /// Determines whether a custom user agent will be used for all requests, see . /// public bool UseCustomUserAgent { get; set; } + /// + /// Determines whether the will be appended to the . + /// + public bool UseQueryParameter { get; set; } + /// /// A custom suffix to be appended to the user agent. /// diff --git a/SebWindowsConfig/SEBSettings.cs b/SebWindowsConfig/SEBSettings.cs index a69503b7..ba336a47 100644 --- a/SebWindowsConfig/SEBSettings.cs +++ b/SebWindowsConfig/SEBSettings.cs @@ -200,6 +200,7 @@ namespace SebWindowsConfig public const String KeyAllowReconfiguration = "examSessionReconfigureAllow"; public const String KeyReconfigurationUrl = "examSessionReconfigureConfigURL"; public const String KeyResetOnQuitUrl = "quitURLRestart"; + public const String KeyUseStartUrlQuery = "startURLAppendQueryParameter"; // Group Additional Resources public const String KeyAdditionalResources = "additionalResources"; @@ -718,6 +719,7 @@ namespace SebWindowsConfig SEBSettings.settingsDefault.Add(SEBSettings.KeyAllowReconfiguration, false); SEBSettings.settingsDefault.Add(SEBSettings.KeyReconfigurationUrl, ""); SEBSettings.settingsDefault.Add(SEBSettings.KeyResetOnQuitUrl, false); + SEBSettings.settingsDefault.Add(SEBSettings.KeyUseStartUrlQuery, false); // Default settings for group "Additional Resources" SEBSettings.settingsDefault.Add(SEBSettings.KeyAdditionalResources, new ListObj()); diff --git a/SebWindowsConfig/SebWindowsConfigForm.Designer.cs b/SebWindowsConfig/SebWindowsConfigForm.Designer.cs index c8c3b775..dd04ba9b 100644 --- a/SebWindowsConfig/SebWindowsConfigForm.Designer.cs +++ b/SebWindowsConfig/SebWindowsConfigForm.Designer.cs @@ -246,6 +246,7 @@ namespace SebWindowsConfig this.textBox4 = new System.Windows.Forms.TextBox(); this.textBox3 = new System.Windows.Forms.TextBox(); this.groupBox8 = new System.Windows.Forms.GroupBox(); + this.checkBoxResetOnQuitUrl = new System.Windows.Forms.CheckBox(); this.checkBoxQuitURLConfirm = new System.Windows.Forms.CheckBox(); this.textBoxQuitURL = new System.Windows.Forms.TextBox(); this.textBox1 = new System.Windows.Forms.TextBox(); @@ -446,7 +447,9 @@ namespace SebWindowsConfig this.editDuplicateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.configureClientToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.applyAndStartSEBToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.checkBoxResetOnQuitUrl = new System.Windows.Forms.CheckBox(); + this.groupBox17 = new System.Windows.Forms.GroupBox(); + this.checkBoxUseStartUrlQuery = new System.Windows.Forms.CheckBox(); + this.label23 = new System.Windows.Forms.Label(); this.tabPageHookedKeys.SuspendLayout(); this.groupBoxFunctionKeys.SuspendLayout(); this.groupBoxSpecialKeys.SuspendLayout(); @@ -502,6 +505,7 @@ namespace SebWindowsConfig this.groupBoxExitSequence.SuspendLayout(); this.tabControlSebWindowsConfig.SuspendLayout(); this.menuStrip1.SuspendLayout(); + this.groupBox17.SuspendLayout(); this.SuspendLayout(); // // openFileDialogSebConfigFile @@ -3010,6 +3014,7 @@ namespace SebWindowsConfig // // tabPageExam // + this.tabPageExam.Controls.Add(this.groupBox17); this.tabPageExam.Controls.Add(this.groupBox15); this.tabPageExam.Controls.Add(this.groupBox2); this.tabPageExam.Controls.Add(this.groupBox9); @@ -3089,7 +3094,7 @@ namespace SebWindowsConfig this.groupBox2.Margin = new System.Windows.Forms.Padding(2); this.groupBox2.Name = "groupBox2"; this.groupBox2.Padding = new System.Windows.Forms.Padding(2); - this.groupBox2.Size = new System.Drawing.Size(610, 118); + this.groupBox2.Size = new System.Drawing.Size(610, 108); this.groupBox2.TabIndex = 122; this.groupBox2.TabStop = false; this.groupBox2.Text = "Session Handling"; @@ -3107,7 +3112,7 @@ namespace SebWindowsConfig // checkBoxClearSessionOnEnd // this.checkBoxClearSessionOnEnd.AutoSize = true; - this.checkBoxClearSessionOnEnd.Location = new System.Drawing.Point(15, 88); + this.checkBoxClearSessionOnEnd.Location = new System.Drawing.Point(15, 83); this.checkBoxClearSessionOnEnd.Margin = new System.Windows.Forms.Padding(2); this.checkBoxClearSessionOnEnd.Name = "checkBoxClearSessionOnEnd"; this.checkBoxClearSessionOnEnd.Size = new System.Drawing.Size(570, 17); @@ -3137,9 +3142,9 @@ namespace SebWindowsConfig this.groupBox9.Controls.Add(this.textBoxRestartExamText); this.groupBox9.Controls.Add(this.textBox4); this.groupBox9.Controls.Add(this.textBox3); - this.groupBox9.Location = new System.Drawing.Point(605, 318); + this.groupBox9.Location = new System.Drawing.Point(605, 287); this.groupBox9.Name = "groupBox9"; - this.groupBox9.Size = new System.Drawing.Size(610, 181); + this.groupBox9.Size = new System.Drawing.Size(610, 168); this.groupBox9.TabIndex = 121; this.groupBox9.TabStop = false; this.groupBox9.Text = "Back to Start Button (Mac)"; @@ -3173,7 +3178,7 @@ namespace SebWindowsConfig // this.checkBoxRestartExamPasswordProtected.AutoSize = true; this.checkBoxRestartExamPasswordProtected.Font = new System.Drawing.Font("Microsoft Sans Serif", 7.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.checkBoxRestartExamPasswordProtected.Location = new System.Drawing.Point(14, 152); + this.checkBoxRestartExamPasswordProtected.Location = new System.Drawing.Point(15, 139); this.checkBoxRestartExamPasswordProtected.Margin = new System.Windows.Forms.Padding(2, 1, 2, 1); this.checkBoxRestartExamPasswordProtected.Name = "checkBoxRestartExamPasswordProtected"; this.checkBoxRestartExamPasswordProtected.Size = new System.Drawing.Size(300, 17); @@ -3187,7 +3192,7 @@ namespace SebWindowsConfig // textBoxRestartExamText // this.textBoxRestartExamText.Font = new System.Drawing.Font("Courier New", 7.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBoxRestartExamText.Location = new System.Drawing.Point(14, 101); + this.textBoxRestartExamText.Location = new System.Drawing.Point(14, 90); this.textBoxRestartExamText.Margin = new System.Windows.Forms.Padding(2, 1, 2, 1); this.textBoxRestartExamText.Name = "textBoxRestartExamText"; this.textBoxRestartExamText.Size = new System.Drawing.Size(526, 19); @@ -3201,7 +3206,7 @@ namespace SebWindowsConfig this.textBox4.BackColor = System.Drawing.SystemColors.Window; this.textBox4.BorderStyle = System.Windows.Forms.BorderStyle.None; this.textBox4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.textBox4.Location = new System.Drawing.Point(15, 126); + this.textBox4.Location = new System.Drawing.Point(15, 118); this.textBox4.Margin = new System.Windows.Forms.Padding(2, 1, 2, 1); this.textBox4.Multiline = true; this.textBox4.Name = "textBox4"; @@ -3232,13 +3237,26 @@ namespace SebWindowsConfig this.groupBox8.Controls.Add(this.checkBoxQuitURLConfirm); this.groupBox8.Controls.Add(this.textBoxQuitURL); this.groupBox8.Controls.Add(this.textBox1); - this.groupBox8.Location = new System.Drawing.Point(605, 150); + this.groupBox8.Location = new System.Drawing.Point(605, 138); this.groupBox8.Name = "groupBox8"; - this.groupBox8.Size = new System.Drawing.Size(610, 144); + this.groupBox8.Size = new System.Drawing.Size(610, 136); this.groupBox8.TabIndex = 120; this.groupBox8.TabStop = false; this.groupBox8.Text = "Link to quit SEB after exam"; // + // checkBoxResetOnQuitUrl + // + this.checkBoxResetOnQuitUrl.AutoSize = true; + this.checkBoxResetOnQuitUrl.Location = new System.Drawing.Point(15, 110); + this.checkBoxResetOnQuitUrl.Name = "checkBoxResetOnQuitUrl"; + this.checkBoxResetOnQuitUrl.Size = new System.Drawing.Size(146, 17); + this.checkBoxResetOnQuitUrl.TabIndex = 115; + this.checkBoxResetOnQuitUrl.Text = "Restart instead of quitting"; + this.toolTip1.SetToolTip(this.checkBoxResetOnQuitUrl, "Session in SEB is restarted after the quit URL has been detected, instead of quit" + + "ting SEB"); + this.checkBoxResetOnQuitUrl.UseVisualStyleBackColor = true; + this.checkBoxResetOnQuitUrl.CheckedChanged += new System.EventHandler(this.checkBoxResetOnQuitUrl_CheckedChanged); + // // checkBoxQuitURLConfirm // this.checkBoxQuitURLConfirm.AutoSize = true; @@ -5800,18 +5818,37 @@ namespace SebWindowsConfig this.applyAndStartSEBToolStripMenuItem.Visible = false; this.applyAndStartSEBToolStripMenuItem.Click += new System.EventHandler(this.applyAndStartSEBToolStripMenuItem_Click); // - // checkBoxResetOnQuitUrl + // groupBox17 // - this.checkBoxResetOnQuitUrl.AutoSize = true; - this.checkBoxResetOnQuitUrl.Location = new System.Drawing.Point(15, 110); - this.checkBoxResetOnQuitUrl.Name = "checkBoxResetOnQuitUrl"; - this.checkBoxResetOnQuitUrl.Size = new System.Drawing.Size(146, 17); - this.checkBoxResetOnQuitUrl.TabIndex = 115; - this.checkBoxResetOnQuitUrl.Text = "Restart instead of quitting"; - this.toolTip1.SetToolTip(this.checkBoxResetOnQuitUrl, "Session in SEB is restarted after the quit URL has been detected, instead of quit" + - "ting SEB"); - this.checkBoxResetOnQuitUrl.UseVisualStyleBackColor = true; - this.checkBoxResetOnQuitUrl.CheckedChanged += new System.EventHandler(this.checkBoxResetOnQuitUrl_CheckedChanged); + this.groupBox17.Controls.Add(this.label23); + this.groupBox17.Controls.Add(this.checkBoxUseStartUrlQuery); + this.groupBox17.Location = new System.Drawing.Point(605, 471); + this.groupBox17.Name = "groupBox17"; + this.groupBox17.Size = new System.Drawing.Size(610, 86); + this.groupBox17.TabIndex = 124; + this.groupBox17.TabStop = false; + this.groupBox17.Text = "Query String Parameter"; + // + // checkBoxUseStartUrlQuery + // + this.checkBoxUseStartUrlQuery.AutoSize = true; + this.checkBoxUseStartUrlQuery.Location = new System.Drawing.Point(15, 59); + this.checkBoxUseStartUrlQuery.Name = "checkBoxUseStartUrlQuery"; + this.checkBoxUseStartUrlQuery.Size = new System.Drawing.Size(133, 17); + this.checkBoxUseStartUrlQuery.TabIndex = 0; + this.checkBoxUseStartUrlQuery.Text = "Allow Query Parameter"; + this.toolTip1.SetToolTip(this.checkBoxUseStartUrlQuery, "If a seb(s):// link contains an additional query string, SEB appends it to the ex" + + "am\'s Start URL"); + this.checkBoxUseStartUrlQuery.UseVisualStyleBackColor = true; + this.checkBoxUseStartUrlQuery.CheckedChanged += new System.EventHandler(this.checkBoxUseStartUrlQuery_CheckedChanged); + // + // label23 + // + this.label23.Location = new System.Drawing.Point(12, 24); + this.label23.Name = "label23"; + this.label23.Size = new System.Drawing.Size(592, 27); + this.label23.TabIndex = 1; + this.label23.Text = resources.GetString("label23.Text"); // // SebWindowsConfigForm // @@ -5932,6 +5969,8 @@ namespace SebWindowsConfig this.tabControlSebWindowsConfig.ResumeLayout(false); this.menuStrip1.ResumeLayout(false); this.menuStrip1.PerformLayout(); + this.groupBox17.ResumeLayout(false); + this.groupBox17.PerformLayout(); this.ResumeLayout(false); this.PerformLayout(); @@ -6355,6 +6394,9 @@ namespace SebWindowsConfig private System.Windows.Forms.CheckBox checkBoxAllowReconfiguration; private System.Windows.Forms.Label label22; private System.Windows.Forms.CheckBox checkBoxResetOnQuitUrl; + private System.Windows.Forms.GroupBox groupBox17; + private System.Windows.Forms.Label label23; + private System.Windows.Forms.CheckBox checkBoxUseStartUrlQuery; } } diff --git a/SebWindowsConfig/SebWindowsConfigForm.cs b/SebWindowsConfig/SebWindowsConfigForm.cs index cefaf39b..5ebaa1c7 100644 --- a/SebWindowsConfig/SebWindowsConfigForm.cs +++ b/SebWindowsConfig/SebWindowsConfigForm.cs @@ -554,6 +554,7 @@ namespace SebWindowsConfig textBoxRestartExamText.Text = (String)SEBSettings.settingsCurrent[SEBSettings.KeyRestartExamText]; checkBoxAllowReconfiguration.Checked = (Boolean)SEBSettings.settingsCurrent[SEBSettings.KeyAllowReconfiguration]; textBoxReconfigurationUrl.Text = (String)SEBSettings.settingsCurrent[SEBSettings.KeyReconfigurationUrl]; + checkBoxUseStartUrlQuery.Checked = (Boolean)SEBSettings.settingsCurrent[SEBSettings.KeyUseStartUrlQuery]; // Group AdditionalResources tabControlSebWindowsConfig.TabPages.Remove(tabPageAdditionalResources); @@ -4608,5 +4609,10 @@ namespace SebWindowsConfig { SEBSettings.settingsCurrent[SEBSettings.KeyResetOnQuitUrl] = checkBoxResetOnQuitUrl.Checked; } + + private void checkBoxUseStartUrlQuery_CheckedChanged(object sender, EventArgs e) + { + SEBSettings.settingsCurrent[SEBSettings.KeyUseStartUrlQuery] = checkBoxUseStartUrlQuery.Checked; + } } } diff --git a/SebWindowsConfig/SebWindowsConfigForm.resx b/SebWindowsConfig/SebWindowsConfigForm.resx index 24f5daba..96084297 100644 --- a/SebWindowsConfig/SebWindowsConfigForm.resx +++ b/SebWindowsConfig/SebWindowsConfigForm.resx @@ -131,7 +131,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAq - 1gAAAk1TRnQBSQFMAgEBDAEAAXABCwFwAQsBIAEAASABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAGA + 1gAAAk1TRnQBSQFMAgEBDAEAAXgBCwF4AQsBIAEAASABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAGA AwABgAMAAQEBAAEgBwABAf8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A /wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A /wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A0QABjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGO @@ -157,10 +157,10 @@ Af8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGO AYsBAAH/A1IB9AMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA - Af8DAAH/AwAB/wNUAe4QAAMyAVEDTgH6A04B+gNOAfoDTgH6A04B+gNOAfoDTgH6A04B+gNOAfoDTgH6 - A04B+gNOAfoDTgH6A04B+gNOAfoDTgH6A04B+gNOAfoDTgH6A04B+gNOAfoDTgH6AzYBWTQAAzIBUANc - Ad8BsQGvAa0B/wGlAaIBoQH/AZIBjwGOAf8BhgGDAYIB/wGAAT8BPgH/AYABPwE+Af8BgAE/AT4B/wGA - AT8BPgH/AYABPwE+Af8BigGHAYYB/wGWAZMBkgH/AaUBogGgAf8BpgGjAaEB/wNUAa8DFwEgGAABjgGL + Af8DAAH/AwAB/wNUAe4QAAMyAVEDTQH6A00B+gNNAfoDTQH6A00B+gNNAfoDTQH6A00B+gNNAfoDTQH6 + A00B+gNNAfoDTQH6A00B+gNNAfoDTQH6A00B+gNNAfoDTQH6A00B+gNNAfoDTQH6AzYBWTQAAzIBUANc + Ad8BsQGvAa0B/wGlAaIBoQH/AZIBjwGOAf8BhgGDAYIB/wGAAT4BPQH/AYABPgE9Af8BgAE+AT0B/wGA + AT4BPQH/AYABPgE9Af8BigGHAYYB/wGWAZMBkgH/AaUBogGgAf8BpgGjAaEB/wNUAa8DFwEgGAABjgGL AQAB/wGOAYsBAAH/AbsBuQEAAf8C/gH9Af8C/gH9Af8C/gH9Af8C9AHmAf8BwgHAAQAB/wL+Af0B/wL+ Af0B/wL+Af0B/wLwAd0B/wHGAcQBAAH/Av4B/QH/Av4B/QH/Av4B/QH/AekB6AHOAf8BqwGoAQAB/wGP AYwBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEA @@ -168,16 +168,16 @@ Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/xAA AzQBVFj/AzgBXCwAAwwBEANRAZ8BtQGyAbAB/wGpAaYBpAH/AZIBjwGNAf8BhAGBAYAB/wGRAY4BjAH/ - AZkBlgGUAf8BjwGMAYoB/wGEAYEBgAH/AYABPwE+Af8BgAE/AT4B/wGAAT8BPgH/AYABPwE+Af8BgAE/ - AT4B/wGAAT8BPgH/AZEBjgGNAf8BpAGhAZ8B/wNiAe8DMgFQFAABjgGLAQAB/wGOAYsBAAH/AbsBuQEA + AZkBlgGUAf8BjwGMAYoB/wGEAYEBgAH/AYABPgE9Af8BgAE+AT0B/wGAAT4BPQH/AYABPgE9Af8BgAE+ + AT0B/wGAAT4BPQH/AZEBjgGNAf8BpAGhAZ8B/wNiAe8DMgFQFAABjgGLAQAB/wGOAYsBAAH/AbsBuQEA Af8MAAL1AegB/wHCAcABAAH/DAAC8QHfAf8BxgHEAQAB/wwAAeoB6QHPAf8B0gHRAZoB/wG+AbwBAAH/ AY8BjAEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGL AQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8DAAH/AwAB/wMAAf8DmgH/ A6IB/wOiAf8DogH/A6IB/wOiAf8DogH/A6IB/wOiAf8DogH/A6IB/wOiAf8DogH/A6IB/wOiAf8DogH/ A6IB/wOiAf8DogH/A6IB/wOiAf8DogH/A6IB/wOiAf8DogH/A5oB/wMAAf8DAAH/AwAB/xAAAzMBU1j/ AzcBWygAAwwBEANcAc8BtwG0AbIB/wGfAZwBmwH/AYsBiAGHAf8BiQGGAYQB/wGYAZUBkwH/AakBpgGk - Af8BpwGkAaIB/wGkAaEBnwH/AaIBnwGdAf8BlgGTAZEB/wGFAYIBgQH/AYABPwE+Af8BgAE/AT4B/wGA - AT8BPgH/AYABPwE+Af8BgAE/AT4B/wGCAUEBQAH/AZ0BmgGYAf8BpQGiAaAB/wM6AWAQAAGOAYsBAAH/ + Af8BpwGkAaIB/wGkAaEBnwH/AaIBnwGdAf8BlgGTAZEB/wGFAYIBgQH/AYABPgE9Af8BgAE+AT0B/wGA + AT4BPQH/AYABPgE9Af8BgAE+AT0B/wGCAUABPwH/AZ0BmgGYAf8BpQGiAaAB/wM6AWAQAAGOAYsBAAH/ AY4BiwEAAf8BuwG5AQAB/wwAAvUB6AH/AcIBwAEAAf8MAALxAd8B/wHGAcQBAAH/DAAB6gHpAc8B/wHS AdEBmgH/Ad0B3AGyAf8BxQHDAQAB/wGPAYwBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEA Af8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wMA @@ -185,7 +185,7 @@ Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DkwH/A6IB/wMA Af8DAAH/EAADMwFTWP8DNwFbKAADXAHPAbcBtAGyAf8BmwGYAZYB/wGQAY0BiwH/AY0BigGJAf8BiwGI AYcB/wGoAaUBowH/AaoBpwGlAf8BpwGkAaIB/wGmAaMBoQH/AaMBoAGeAf8BogGfAZ0B/wGdAZoBmAH/ - AY0BigGJAf8BgQFAAT8B/wGAAT8BPgH/AYABPwE+Af8BgAE/AT4B/wGAAT8BPgH/AYABPwE+Af8BmAGV + AY0BigGJAf8BgQE/AT4B/wGAAT4BPQH/AYABPgE9Af8BgAE+AT0B/wGAAT4BPQH/AYABPgE9Af8BmAGV AZMB/wGlAaIBoAH/AzoBYAwAAY4BiwEAAf8BjgGLAQAB/wG7AbkBAAH/DAAC9QHoAf8BwgHAAQAB/wwA AvEB3wH/AcYBxAEAAf8MAAHqAekBzwH/AdIB0QGaAf8B3QHcAbIB/wHdAdwBsgH/Ac8BzgGSAf8BjgGL AQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/ @@ -194,7 +194,7 @@ AwAB/wMAAf8DAAH/AwAB/wMAAf8DkwH/A5oB/wMAAf8QAAMzAVNY/wM3AVskAANMAY8BuwG4AbcB/wGh AZ4BnAH/AZQBkQGPAf8BkgGPAY0B/wGQAY0BiwH/AY0BigGJAf8BqgGnAaUB/wGqAacBpQH/AagBpQGj Af8BpwGkAaIB/wGkAaEBnwH/AaMBoAGeAf8BoQGeAZwB/wGhAZ4BnAH/AZ4BmwGZAf8BkQGOAYwB/wGC - AUEBQAH/AYABPwE+Af8BgAE/AT4B/wGAAT8BPgH/AYABPwE+Af8BmAGVAZMB/wGlAaIBoAH/AyEBMAgA + AUABPwH/AYABPgE9Af8BgAE+AT0B/wGAAT4BPQH/AYABPgE9Af8BmAGVAZMB/wGlAaIBoAH/AyEBMAgA AY4BiwEAAf8BjgGLAQAB/wGfAZwBAAH/AbgBtgEAAf8BuAG2AQAB/wG4AbYBAAH/AbQBsgEAAf8BoQGf AQAB/wG4AbYBAAH/AbgBtgEAAf8BuAG2AQAB/wGyAbABAAH/AacBpAEAAf8BvgG9AQAB/wG+Ab0BAAH/ Ab4BvQEAAf8BuAG2AQAB/wHQAc8BlQH/Ad0B3AGyAf8B3QHcAbIB/wLqAdAB/wGOAYsBAAH/AY4BiwEA @@ -204,7 +204,7 @@ Af8DAAH/AwAB/wMAAf8DogH/AwAB/xAAAzMBU1j/AzcBWyAAAyoBQAG8AboBuAH/AasBqAGnAf8BmAGV AZMB/wGWAZMBkQH/AZQBkQGPAf8BkgGPAY0B/wGQAY0BiwH/AasBqAGmAf8BqwGoAaYB/wGpAaYBpAH/ AacBpAGiAf8BpQGiAaAB/wGjAaABngH/AaEBngGcAf8BoQGeAZwB/wGhAZ4BnAH/AaEBngGcAf8BmwGY - AZYB/wGBAUABPwH/AYABPwE+Af8BgAE/AT4B/wGAAT8BPgH/AYIBQQFAAf8BoQGeAZ0B/wNcAc8IAAGO + AZYB/wGBAT8BPgH/AYABPgE9Af8BgAE+AT0B/wGAAT4BPQH/AYIBQAE/Af8BoQGeAZ0B/wNcAc8IAAGO AYsBAAH/AY4BiwEAAf8BuwG5AQAB/wwAAvUB6AH/AcIBwAEAAf8MAALxAd8B/wGzAbEBAAH/AuYBxwH/ Ae0B7AHWAf8B7QHsAdYB/wHtAewB1gH/AcQBwgEAAf8BzAHLAYwB/wHdAdwBsgH/AuoB0AH/AY4BiwEA Af8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGO @@ -213,16 +213,16 @@ AwAB/wMAAf8DogH/AwAB/xAAAzMBU1j/AzcBWyAAA1kBvwG6AbcBtQH/AZ0BmgGYAf8BmwGYAZYB/wGY AZUBkwH/AZYBkwGRAf8BlAGRAY8B/wGSAY8BjQH/AagBpQGjAf8BnQGaAZkB/wGqAacBpQH/AagBpQGj Af8BpgGjAaEB/wGkAaEBnwH/AaIBnwGdAf8BoQGeAZwB/wGhAZ4BnAH/AaEBngGcAf8BoQGeAZwB/wGF - AYIBgAH/AYABPwE+Af8BgAE/AT4B/wGAAT8BPgH/AYABPwE+Af8BigGHAYYB/wGmAaMBoQH/AzoBYAQA + AYIBgAH/AYABPgE9Af8BgAE+AT0B/wGAAT4BPQH/AYABPgE9Af8BigGHAYYB/wGmAaMBoQH/AzoBYAQA AY4BiwEAAf8BjgGLAQAB/wG7AbkBAAH/DAAC9QHoAf8BwgHAAQAB/wwAAvEB3wH/AcwBywGNAf8B0wHS AZwB/wHuAe0B2AH/Ae4B7QHYAf8B7gHtAdgB/wHuAe0B2AH/AacBpAEAAf8ByQHIAYUB/wLqAdAB/wGO AYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEA Af8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8DAAH/A6IB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA Af8DAAH/AwAB/wMAAf8DyAH/CAAD4wH/A6AB/wOtAf8IAAPIAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA Af8DAAH/AwAB/wMAAf8DogH/AwAB/xAAAzMBU1j/AzcBWxwAAyoBQAHAAb0BvAH/AawBqQGoAf8BnwGc - AZoB/wGdAZoBmAH/AZsBmAGWAf8BmAGVAZMB/wE4ATYBNAH/AQMBAgEBAf8DAAH/AwAB/wE7ATgBNwH/ + AZoB/wGdAZoBmAH/AZsBmAGWAf8BmAGVAZMB/wE3ATUBMwH/AQIBAQEAAf8DAAH/AwAB/wE6ATcBNgH/ AakBpgGkAf8BpwGkAaIB/wGlAaIBoAH/AaMBoAGeAf8BoQGeAZwB/wGhAZ4BnAH/AaEBngGcAf8BoQGe - AZwB/wGFAYIBgQH/AYABPwE+Af8BgAE/AT4B/wGAAT8BPgH/AYABPwE+Af8BgAE/AT4B/wGdAZoBmQH/ + AZwB/wGFAYIBgQH/AYABPgE9Af8BgAE+AT0B/wGAAT4BPQH/AYABPgE9Af8BgAE+AT0B/wGdAZoBmQH/ A1wB3wQAAY4BiwEAAf8BjgGLAQAB/wG7AbkBAAH/DAAC9QHoAf8BwgHAAQAB/wwAAvEB3wH/AcwBywGN Af8B2wHaAa4B/xAAAboBuAEAAf8BzAHLAYwB/wHWAdUBpAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/ AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGL @@ -230,9 +230,9 @@ Af8DAAH/AwAB/wMAAf8IAAORAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wOiAf8DAAH/ EAADMwFTCP8D/gH/A/4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/A/4B/wP+Af8D/gH/ A/4B/wP+Af8D/gH/A/4B/wP+Af8D/gX/AzcBWxwAA1EBnwG9AbsBuQH/AaQBoQGfAf8BogGfAZ0B/wGf - AZwBmgH/AZ0BmgGYAf8BmwGYAZYB/wMAAf8DAAH/AwAB/wIAAQYB/wEbASQBKQH/AaoBpwGlAf8BqAGl - AaMB/wGmAaMBoQH/AaQBoQGfAf8BogGfAZ0B/wGhAZ4BnAH/AaEBngGcAf8BngGbAZkB/wGAAT8BPgH/ - AYABPwE+Af8BgAE/AT4B/wGAAT8BPgH/AYABPwE+Af8BgAE/AT4B/wGMAYkBiAH/AacBpAGiAf8DIQEw + AZwBmgH/AZ0BmgGYAf8BmwGYAZYB/wMAAf8DAAH/AwAB/wIAAQUB/wEaASMBKAH/AaoBpwGlAf8BqAGl + AaMB/wGmAaMBoQH/AaQBoQGfAf8BogGfAZ0B/wGhAZ4BnAH/AaEBngGcAf8BngGbAZkB/wGAAT4BPQH/ + AYABPgE9Af8BgAE+AT0B/wGAAT4BPQH/AYABPgE9Af8BgAE+AT0B/wGMAYkBiAH/AacBpAGiAf8DIQEw AY4BiwEAAf8BjgGLAQAB/wG7AbkBAAH/DAAC9QHoAf8BwgHAAQAB/wwAAvEB3wH/AcwBywGNAf8B2wHa Aa4B/xAAAboBuAEAAf8C3QGzAf8B1AHTAZ4B/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/ AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8DAAH/ @@ -240,9 +240,9 @@ AwAB/wMAAf8DugH/BAADwAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DogH/AwAB/xAA AzMBUwT/A/4B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9 Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Bf8DNwFbHAADXAHfAbYBtAGyAf8BpgGjAaEB/wGkAaEBnwH/ - AaIBnwGdAf8BnwGcAZoB/wGdAZoBmAH/ARwBGgEZAf8DAAH/AQABjwG4Af8BAAGPAb0B/wEkAY0BpAH/ + AaIBnwGdAf8BnwGcAZoB/wGdAZoBmAH/ARsBGQEYAf8DAAH/AQABjwG4Af8BAAGPAb0B/wEjAY0BpAH/ AasBqAGmAf8BqQGmAaQB/wGnAaQBogH/AaUBogGgAf8BowGgAZ4B/wGhAZ4BnAH/AaEBngGcAf8BjwGM - AYoB/wGEAYEBgAH/AYQBgQGAAf8BgAE/AT4B/wGAAT8BPgH/AYABPwE+Af8BgAE/AT4B/wGAAT8BPgH/ + AYoB/wGEAYEBgAH/AYQBgQGAAf8BgAE+AT0B/wGAAT4BPQH/AYABPgE9Af8BgAE+AT0B/wGAAT4BPQH/ AagBpQGjAf8DRwGAAY4BiwEAAf8BjgGLAQAB/wGfAZwBAAH/AbgBtgEAAf8BuAG2AQAB/wG4AbYBAAH/ AbQBsgEAAf8BpAGhAQAB/wHLAcoBiwH/AcsBygGLAf8BywHKAYsB/wHIAccBgwH/Ab8BvgEAAf8B2wHa Aa0B/xAAAboBuAEAAf8C3QGzAf8C6gHQAf8BjgGLAQAB/wGRAY4BAAH/AcwBywGMAf8BlwGUAQAB/wGO @@ -251,10 +251,10 @@ AwAB/wMAAf8DnAH/BAADzgH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DogH/AwAB/xAA AzMBUwP+Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/ A/0B/wP9Af8D/QH/A/0B/wP9Af8D/QH/A/0F/wM3AVsYAAMMARABxAHBAcAB/wGyAa8BrQH/AakBpgGk - Af8BpgGjAaEB/wGkAaEBnwH/AaIBnwGdAf8BnwGcAZoB/wGDAYABQAH/AwAB/wELAaQBygH/AQABkAG9 - Af8BJAGNAaQB/wGsAakBpwH/AaoBpwGlAf8BqAGlAaMB/wGmAaMBoQH/AaQBoQGfAf8BngGbAZkB/wGR - AY4BjQH/AZQBkQGPAf8BoQGeAZwB/wGgAZ0BmwH/AY8BjAGKAf8BgAE/AT4B/wGAAT8BPgH/AYABPwE+ - Af8BgAE/AT4B/wGfAZwBmgH/A1QBrwGOAYsBAAH/AY4BiwEAAf8BuwG5AQAB/wwAAvUB6AH/AbkBtgEA + Af8BpgGjAaEB/wGkAaEBnwH/AaIBnwGdAf8BnwGcAZoB/wGDAYABPwH/AwAB/wEKAaQBygH/AQABkAG9 + Af8BIwGNAaQB/wGsAakBpwH/AaoBpwGlAf8BqAGlAaMB/wGmAaMBoQH/AaQBoQGfAf8BngGbAZkB/wGR + AY4BjQH/AZQBkQGPAf8BoQGeAZwB/wGgAZ0BmwH/AY8BjAGKAf8BgAE+AT0B/wGAAT4BPQH/AYABPgE9 + Af8BgAE+AT0B/wGfAZwBmgH/A1QBrwGOAYsBAAH/AY4BiwEAAf8BuwG5AQAB/wwAAvUB6AH/AbkBtgEA Af8B1AHTAZ4B/wHZAdgBqAH/AdkB2AGoAf8B2QHYAagB/wHFAcQBAAH/AaQBoQEAAf8BxQHDAQAB/wHF AcMBAAH/AcUBwwEAAf8BxQHDAQAB/wG4AbYBAAH/At0BswH/AuoB0AH/AZEBjgEAAf8C3AGxAf8EAAHr AeoB0QH/AZcBlAEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEA @@ -262,10 +262,10 @@ Af8DAAH/AwAB/wMAAf8DAAH/A9wB/wQAA7MB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/ A6IB/wMAAf8QAAMzAVMD/QH/A/0B/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8 Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Af8D/AH/A/wB/wP8Bf8DNwFbGAADKgFAAcQBwgHBAf8BvgG7 - AboB/wG2AbMBsQH/AasBqAGmAf8BpgGjAaEB/wGkAaEBnwH/AaIBnwGdAf8BnwGcAZoB/wERAQ8BDgH/ - AQABgwGZAf8BBwGmAcoB/wElAZIBpwH/Aa0BqgGoAf8BqwGoAaYB/wGlAaIBoAH/AZgBlQGTAf8BjwGM - AYsB/wGJAYYBhAH/AZEBjgGNAf8BoQGeAZwB/wGhAZ4BnAH/AaEBngGcAf8BnwGcAZoB/wGBAUABPwH/ - AYABPwE+Af8BgAE/AT4B/wGAAT8BPgH/AZUBkgGQAf8DWQG/AY4BiwEAAf8BjgGLAQAB/wG7AbkBAAH/ + AboB/wG2AbMBsQH/AasBqAGmAf8BpgGjAaEB/wGkAaEBnwH/AaIBnwGdAf8BnwGcAZoB/wEQAQ4BDQH/ + AQABgwGZAf8BBgGmAcoB/wEkAZIBpwH/Aa0BqgGoAf8BqwGoAaYB/wGlAaIBoAH/AZgBlQGTAf8BjwGM + AYsB/wGJAYYBhAH/AZEBjgGNAf8BoQGeAZwB/wGhAZ4BnAH/AaEBngGcAf8BnwGcAZoB/wGBAT8BPgH/ + AYABPgE9Af8BgAE+AT0B/wGAAT4BPQH/AZUBkgGQAf8DWQG/AY4BiwEAAf8BjgGLAQAB/wG7AbkBAAH/ DAAC9QHoAf8ByAHGAYMB/wHWAdUBowH/AvIB4gH/AvIB4QH/AvIB4QH/AvIB4QH/Aa4BrAEAAf8B2wHa Aa0B/wL4Ae8B/wL4Ae8B/wL4Ae8B/wHWAdUBowH/AcUBxAEAAf8B4AHfAbkB/wHcAdsBsQH/DAAB6wHq AdEB/wGXAZQBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wMAAf8DoQH/ @@ -273,10 +273,10 @@ AwAB/wOpAf8LAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DoQH/AwAB/xAAAzMBUwP8 Af8D+wH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP6 Af8D+gH/A/oB/wP6Af8D+gH/A/oB/wP+Af8DNwFbGAADKgFAAcUBwwHCAf8BxAHBAcAB/wHCAcABvgH/ - Ab4BuwG6Af8BqgGnAaUB/wGmAaMBoQH/AaQBoQGfAf8BpAGhAZ8B/wGfAZwBmwH/AQABHwEqAf8BCgG9 - AdoB/wEnAZ4BrwH/Aa4BqwGpAf8BogGfAZ0B/wGSAY8BjQH/AZQBkQGPAf8BlAGRAZAB/wGLAYgBhwH/ - AZ4BmwGZAf8BoQGeAZwB/wGhAZ4BnAH/AaEBngGcAf8BoQGeAZwB/wGGAYMBggH/AYABPwE+Af8BgAE/ - AT4B/wGAAT8BPgH/AZUBkgGRAf8DYgHvAY4BiwEAAf8BjgGLAQAB/wG7AbkBAAH/DAAC9QHoAf8ByAHG + Ab4BuwG6Af8BqgGnAaUB/wGmAaMBoQH/AaQBoQGfAf8BpAGhAZ8B/wGfAZwBmwH/AQABHgEpAf8BCQG9 + AdoB/wEmAZ4BrwH/Aa4BqwGpAf8BogGfAZ0B/wGSAY8BjQH/AZQBkQGPAf8BlAGRAZAB/wGLAYgBhwH/ + AZ4BmwGZAf8BoQGeAZwB/wGhAZ4BnAH/AaEBngGcAf8BoQGeAZwB/wGGAYMBggH/AYABPgE9Af8BgAE+ + AT0B/wGAAT4BPQH/AZUBkgGRAf8DYgHvAY4BiwEAAf8BjgGLAQAB/wG7AbkBAAH/DAAC9QHoAf8ByAHG AYMB/wHZAdgBqQH/EAABvgG8AQAB/wHTAdIBnAH/AcwBygGLAf8B2wHaAa4B/wHbAdoBrgH/AdsB2gGu Af8BvwG+AQAB/wG7AboBAAH/Av4B/AH/EAABugG4AQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGO AYsBAAH/AY4BiwEAAf8DAAH/A50B/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA @@ -284,19 +284,19 @@ AwAB/wMAAf8DnQH/AwAB/xAAAzMBUwP6Af8D+QH/A/kB/wP5Af8D+QH/A/kB/wP5Af8D+QH/A/kB/wP5 Af8D+QH/A/kB/wP5Af8D+QH/A/kB/wP5Af8D+QH/A/kB/wP5Af8D+QH/A/kB/wP9Af8DNwFbGAADKgFA AccBxQHDAf8BxQHDAcIB/wHDAcABvwH/Ab0CuwH/Aa8BrgGwAf8BrAGqAagB/wGmAaMBoQH/AagBpQGj - Af8BtwG0AbIB/wEbASMBJAH/AQABxAHfAf8BEAGpAb4B/wGOAaEBpgH/AZYBkwGRAf8BlAGRAY8B/wGZ + Af8BtwG0AbIB/wEaASIBIwH/AQABxAHfAf8BDwGpAb4B/wGOAaEBpgH/AZYBkwGRAf8BlAGRAY8B/wGZ AZYBlAH/AacBpAGiAf8BmwGYAZYB/wGjAaABngH/AaEBngGcAf8BoQGeAZwB/wGhAZ4BnAH/AaEBngGc - Af8BhgGDAYIB/wGAAT8BPgH/AYABPwE+Af8BgAE/AT4B/wGWAZMBkQH/AasBqAGmAf8BjgGLAQAB/wGO + Af8BhgGDAYIB/wGAAT4BPQH/AYABPgE9Af8BgAE+AT0B/wGWAZMBkQH/AasBqAGmAf8BjgGLAQAB/wGO AYsBAAH/AbsBuQEAAf8MAAL1AegB/wHIAcYBgwH/AdkB2AGoAf8QAAG+AbwBAAH/AdYB1QGiAf8B6AHn AcoB/wwAAdsB2gGuAf8B1wHWAaUB/wG2AbQBAAH/Av4B/AH/CAABwwHBAQAB/wGOAYsBAAH/AY4BiwEA Af8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wMAAf8DmAH/AwAB/wMAAf8DAAH/AwAB/wMA Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wOwAf8D6wH/CAADngH/AwAB/wMAAf8DAAH/ AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wOYAf8DAAH/EAADMwFTA/kB/wP5Af8D+AH/A/gB/wP4 Af8D+AH/A/gB/wP4Af8D+AH/A/gB/wP4Af8D+AH/A/gB/wP4Af8D+AH/A/gB/wP4Af8D+AH/A/gB/wP4 - Af8D+AH/A/wB/wM3AVsYAAMqAUABqAHAAcUB/wFBAbIBwAH/AQ8BogG8Af8BAAGaAbwB/wEAAZcBugH/ - ATIBqQG5Af8BrgGrAakB/wGrAagBpgH/AbgBtQGzAf8BQQE+AT0B/wEAAY8BoQH/AQABvwHbAf8BAAGi - AcEB/wE1AZEBnQH/AaABnQGbAf8BnwGcAZoB/wGmAaMBoQH/AaYBowGhAf8BpAGhAZ8B/wGiAZ8BnQH/ - AaEBngGcAf8BoQGeAZwB/wGhAZ4BnAH/AYgBhQGEAf8BgAE/AT4B/wGAAT8BPgH/AYABPwE+Af8BlgGT + Af8D+AH/A/wB/wM3AVsYAAMqAUABqAHAAcUB/wFAAbIBwAH/AQ4BogG8Af8BAAGaAbwB/wEAAZcBugH/ + ATEBqQG5Af8BrgGrAakB/wGrAagBpgH/AbgBtQGzAf8BQAE9ATwB/wEAAY8BoQH/AQABvwHbAf8BAAGi + AcEB/wE0AZEBnQH/AaABnQGbAf8BnwGcAZoB/wGmAaMBoQH/AaYBowGhAf8BpAGhAZ8B/wGiAZ8BnQH/ + AaEBngGcAf8BoQGeAZwB/wGhAZ4BnAH/AYgBhQGEAf8BgAE+AT0B/wGAAT4BPQH/AYABPgE9Af8BlgGT AZIB/wNZAb8BjgGLAQAB/wGOAYsBAAH/AZcBlAEAAf8BugG4AQAB/wG9AbwBAAH/Ab0BvAEAAf8BuwG6 AQAB/wHGAcQBAAH/AdkB2AGoAf8QAAG+AbwBAAH/AdYB1QGiAf8C5wHKAf8MAAHbAdoBrgH/AuoB0AH/ AY4BiwEAAf8BtgG0AQAB/wH+Af0B/AH/AcMBwgEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGL @@ -304,10 +304,10 @@ AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/A7AB/wgAA9UB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wOUAf8DAAH/EAADMwFTA/gB/wP3Af8D9gH/A/YB/wP2Af8D9gH/ A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/A/YB/wP2Af8D9gH/ - A/oB/wM3AVsQAAMyAVADVAGvAVgCYgHvAQABmgG8Af8BAAGmAcYB/wEAAbgB1AH/ARgBxgHfAf8BFwHC - AdwB/wEAAZoBuAH/AboBuAG3Af8BuQG2AbUB/wG1AbMBsgH/ATEBhAGKAf8BAAGEAZwB/wEAAbsB1wH/ - AQABrgHPAf8BAAGVAb4B/wFBAZQBngH/AaoBpwGlAf8BqQGmAaQB/wGnAaQBogH/AaUBogGgAf8BowGg - AZ4B/wGhAZ4BnAH/AaEBngGcAf8BoAGdAZsB/wGGAYMBggH/AYIBQQFAAf8BgAE/AT4B/wGAAT8BPgH/ + A/oB/wM3AVsQAAMyAVADVAGvAVgCYgHvAQABmgG8Af8BAAGmAcYB/wEAAbgB1AH/ARcBxgHfAf8BFgHC + AdwB/wEAAZoBuAH/AboBuAG3Af8BuQG2AbUB/wG1AbMBsgH/ATABhAGKAf8BAAGEAZwB/wEAAbsB1wH/ + AQABrgHPAf8BAAGVAb4B/wFAAZQBngH/AaoBpwGlAf8BqQGmAaQB/wGnAaQBogH/AaUBogGgAf8BowGg + AZ4B/wGhAZ4BnAH/AaEBngGcAf8BoAGdAZsB/wGGAYMBggH/AYIBQAE/Af8BgAE+AT0B/wGAAT4BPQH/ AaIBnwGeAf8DWQG/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/Aa4BrAEAAf8B3gHdAbQB/wHeAd0BtAH/ Ad4B3QG0Af8BzwHOAZMB/wGpAacBAAH/Ab4BvAEAAf8BvgG8AQAB/wG+AbwBAAH/Ab4BvAEAAf8BtgG0 AQAB/wHWAdUBogH/AucBygH/DAAB2wHaAa4B/wLqAdAB/wGOAYsBAAH/AY4BiwEAAf8BoQGeAQAB/wGO @@ -316,10 +316,10 @@ Af8LAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/A48B/wMA Af8QAAMzAVMD9gH/A/UB/wP1Af8D9QH/A/UB/wP1Af8D9QH/A/UB/wP1Af8D9QH/A/UB/wP1Af8D9QH/ A/UB/wP1Af8D9QH/A/UB/wP1Af8D9QH/A/UB/wP1Af8D+QH/AzcBWxEAAZABvwH/AQABjAG3Af8BAAGy - AdIB/wEDAccB4QH/ARgByQHhAf8BgQHHAdcB/wGaAcQBzAH/ASsBygHhAf8BAAGhAcIB/wEsAZ0BsQH/ - ASUBmwGyAf8BAAGWAbYB/wEAAaABwgH/AQABrgHMAf8BAAG4AdYB/wEAAbMB0wH/AQABmgHBAf8BEgGI + AdIB/wECAccB4QH/ARcByQHhAf8BgQHHAdcB/wGaAcQBzAH/ASoBygHhAf8BAAGhAcIB/wErAZ0BsQH/ + ASQBmwGyAf8BAAGWAbYB/wEAAaABwgH/AQABrgHMAf8BAAG4AdYB/wEAAbMB0wH/AQABmgHBAf8BEQGI AaUB/wGrAagBpgH/AaoBpwGlAf8BpwGkAaIB/wGmAaMBoQH/AaMBoAGeAf8BogGfAZ0B/wGhAZ4BnAH/ - AZ4BmwGZAf8BhwGEAYIB/wGEAYEBgAH/AYIBQQFAAf8BgAE/AT4B/wGsAakBpwH/A0cBgAGOAYsBAAH/ + AZ4BmwGZAf8BhwGEAYIB/wGEAYEBgAH/AYIBQAE/Af8BgAE+AT0B/wGsAakBpwH/A0cBgAGOAYsBAAH/ AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/Aa0BqwEAAf8C9gHsAf8C+QHxAf8C+QHxAf8B6wHqAdEB/wHV AdQBoQH/AvkB8QH/AvkB8QH/AvkB8QH/AecB5gHJAf8BtgG0AQAB/wHKAckBhgH/AdoB2QGrAf8B2gHZ AasB/wHaAdkBqwH/AcQBwwEAAf8B6gHpAc8B/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/ @@ -328,8 +328,8 @@ Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DigH/AwAB/xAAAzMBUwP1Af8D9QH/ A/QB/wP0Af8D9AH/A/QB/wP0Af8D9AH/A/QB/wP0Af8D9AH/A/QB/wP0Af8D9AH/A/QB/wP0Af8D9AH/ A/QB/wP0Af8D9AH/A/QB/wP3Af8DNwFbEAABWAJiAe8BAAGeAcUB/wFXAlwB3wNZAb8ByQHHAcYB/wHH - AcUBwwH/AcQBwgHBAf8BgQHGAdYB/wEQAbwB1gH/AQABogHDAf8BAAGuAc0B/wEAAbgB1QH/AQABugHX - Af8BAAG6AdcB/wEAAboB1wH/AQABtQHVAf8BAAGhAccB/wEIAYsBrQH/AasBqAGmAf8BoQGeAZwB/wGp + AcUBwwH/AcQBwgHBAf8BgQHGAdYB/wEPAbwB1gH/AQABogHDAf8BAAGuAc0B/wEAAbgB1QH/AQABugHX + Af8BAAG6AdcB/wEAAboB1wH/AQABtQHVAf8BAAGhAccB/wEHAYsBrQH/AasBqAGmAf8BoQGeAZwB/wGp AaYBpAH/AaMBoAGeAf8BnAGZAZcB/wGbAZgBlgH/AZwBmQGXAf8BjwGMAYsB/wGJAYYBhAH/AYcBhAGC Af8BhAGBAYAB/wGRAY4BjQH/AbABrQGrAf8DIQEwAY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEA Af8BjgGLAQAB/wGcAZoBAAH/Ad8B3gG2Af8B4wHiAb8B/wHjAeIBvwH/Ad8B3gG2Af8BvwG9AQAB/wHj @@ -339,9 +339,9 @@ Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/A9UB/xwAA/MB/wMAAf8DAAH/AwAB/wMAAf8DAAH/ AwAB/wMAAf8DAAH/AwAB/wMAAf8DhQH/AwAB/xAAAzMBUwP0Af8D8wH/A/IB/wPyAf8D8gH/A/IB/wPy Af8D8gH/A/IB/wPyAf8D8gH/A/IB/wPyAf8D8gH/A/IB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPz - Af8DNwFbEAADUQGgAQsBqQHOAf8BWgJdAdMDMgFQAcsByQHIAf8ByAHGAcQB/wHFAcMBwgH/AZgBwgHL - Af8BKAHIAeAB/wEAAbsB2QH/AQABuwHYAf8BAAG7AdgB/wEAAbwB2QH/AQABwAHbAf8BCQHFAd8B/wEN - AcEB3QH/AQABlQG2Af8BCQE2AYsB/wGeAZsBmQH/AZsBmAGWAf8BoAGdAZsB/wGWAZMBkQH/AZQBkQGP + Af8DNwFbEAADUQGgAQoBqQHOAf8BWgJdAdMDMgFQAcsByQHIAf8ByAHGAcQB/wHFAcMBwgH/AZgBwgHL + Af8BJwHIAeAB/wEAAbsB2QH/AQABuwHYAf8BAAG7AdgB/wEAAbwB2QH/AQABwAHbAf8BCAHFAd8B/wEM + AcEB3QH/AQABlQG2Af8BCAE1AYsB/wGeAZsBmQH/AZsBmAGWAf8BoAGdAZsB/wGWAZMBkQH/AZQBkQGP Af8BkgGPAY0B/wGQAY0BiwH/AY0BigGJAf8BiwGIAYcB/wGJAYYBhAH/AYcBhAGCAf8BoQGeAZwB/wNc Ad8EAAGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGdAZoBAAH/ AaUBowEAAf8BpQGjAQAB/wGlAaMBAAH/AZwBmQEAAf8BowGhAQAB/wGlAaMBAAH/AaUBowEAAf8BpQGj @@ -350,9 +350,9 @@ AYsBAAH/AY4BiwEAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/A5gB/yQA A74B/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/EAADMwFTA/IB/wPx Af8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8QH/A/EB/wPxAf8D8AH/A+0B/wPq - Af8D6AH/A+gB/wPnAf8D5gH/A+cB/wM4AVwQAAM6AWABJAG0AdcB/wEAAZYBugH/AxwBJwNcAd8BygHI - AccB/wHGAcQBwwH/AbsBwgHDAf8BJwHKAeEB/wEAAb4B2gH/AQABwQHdAf8BFgHHAeAB/wEYAcgB4QH/ - ASEBwgHXAf8BGwGbAagB/wIAAQIB/wMAAf8BhAGCAYAB/wGlAaIBoAH/AaoBpwGlAf8BqgGnAaUB/wGg + Af8D6AH/A+gB/wPnAf8D5gH/A+cB/wM4AVwQAAM6AWABIwG0AdcB/wEAAZYBugH/AxwBJwNcAd8BygHI + AccB/wHGAcQBwwH/AbsBwgHDAf8BJgHKAeEB/wEAAb4B2gH/AQABwQHdAf8BFQHHAeAB/wEXAcgB4QH/ + ASABwgHXAf8BGgGbAagB/wIAAQEB/wMAAf8BhAGCAYAB/wGlAaIBoAH/AaoBpwGlAf8BqgGnAaUB/wGg AZ0BmwH/AZYBkwGRAf8BlAGRAY8B/wGSAY8BjQH/AZABjQGLAf8BjQGKAYkB/wGLAYgBhwH/AZEBjgGM Af8BswGwAa4B/wNHAYAEAAGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGL AQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/ @@ -361,8 +361,8 @@ Af8BjgGLAQAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8D2gH/KwAB/wMA Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8QAAMzAVMD8QH/A/EB/wPwAf8D8AH/ A/AB/wPwAf8D8AH/A/AB/wPwAf8D8AH/A/AB/wPwAf8D8AH/A+8B/wPsAf8D5AH/A9gB/wPQAf8DzwH/ - A9AB/wPMAf8DyAH/AzUBVxAAAwwBEAEuAbcB2gH/AQMBoQHFAf8DQwF3AzIBUAHLAckByAH/AckBxwHF - Af8BxQHDAcIB/wE8AcYB1wH/AQIBvwHbAf8BEQGyAcwB/wGOAb4BxwH/AakBuQG8Af8BuQG3AbUB/wG3 + A9AB/wPMAf8DyAH/AzUBVxAAAwwBEAEtAbcB2gH/AQIBoQHFAf8DQwF3AzIBUAHLAckByAH/AckBxwHF + Af8BxQHDAcIB/wE7AcYB1wH/AQEBvwHbAf8BEAGyAcwB/wGOAb4BxwH/AakBuQG8Af8BuQG3AbUB/wG3 AbQBsgH/AaQBogGgAf8BqwGoAaYB/wGxAa8BrQH/Aa8BrAGqAf8BrQGqAagB/wGrAagBpgH/AaIBnwGd Af8BmAGVAZMB/wGWAZMBkQH/AZQBkQGPAf8BkgGPAY0B/wGQAY0BiwH/AY0BigGJAf8BrQGqAagB/wNc Ad8DDAEQBAABjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGL @@ -372,7 +372,7 @@ AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8vAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/ AwAB/wMAAf8DAAH/AwAB/xAAAzMBUwPwAf8D7wH/A+4B/wPuAf8D7gH/A+4B/wPuAf8D7gH/A+4B/wPu Af8D7gH/A+4B/wPuAf8D7QH/A+gB/wPWAf8DuAH/A6cB/wOiAf8DngH/A54B/wNhAeYDFAEbFAADVAGv - AR4BsAHTAf8BWgJdAdMEAANUAa8BywHJAcgB/wHHAcUBxAH/AZMBwwHMAf8BCgHDAd4B/wEAAZoBugH/ + AR0BsAHTAf8BWgJdAdMEAANUAa8BywHJAcgB/wHHAcUBxAH/AZMBwwHMAf8BCQHDAd4B/wEAAZoBugH/ Ab0BuwG6Af8BvAG6AbgB/wG6AbcBtgH/AbgBtgG0Af8BtgGzAbIB/wG0AbIBsAH/AbIBrwGtAf8BsAGt AasB/wGuAasBqQH/AasBqAGmAf8BngGbAZkB/wGbAZgBlgH/AZgBlQGTAf8BlgGTAZEB/wGUAZEBjwH/ AZIBjwGNAf8BqAGlAaMB/wG1AbMBsQH/AyoBQAgAAY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEA @@ -383,7 +383,7 @@ AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/ AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/EAADMwFTA+4B/wPtAf8D7QH/A+0B/wPtAf8D7QH/A+0B/wPt Af8D7QH/A+0B/wPtAf8D7QH/A+0B/wPsAf8D4wH/A8oB/wOdAf8DgwH/A4YB/wOYAf8DYgHvAycBOxgA - AzoBYAE0AboB3QH/AQIBkwG6Af8DGgEkAwwBEANcAc8BjQG4AcQB/wEJAaUBwAH/AQABuQHWAf8BAAGe + AzoBYAEzAboB3QH/AQEBkwG6Af8DGgEkAwwBEANcAc8BjQG4AcQB/wEIAaUBwAH/AQABuQHWAf8BAAGe Ab4B/wGYAbYBvQH/Ab0BuwG5Af8BvQG6AbkB/wG5AbcBtQH/AbcBtAGyAf8BtQGyAbEB/wGzAbABrgH/ AbEBrwGtAf8BrQGqAagB/wGiAZ8BnQH/AZ8BnAGaAf8BnQGaAZgB/wGbAZgBlgH/AZgBlQGTAf8BlgGT AZEB/wGkAaEBnwH/AbgBtQGzAf8DRwGADAABjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGO @@ -393,7 +393,7 @@ Af8BjgGLAQAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8vAAH/AwAB/wMA Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/xAAAzMBUwPtAf8D7QH/A+wB/wPsAf8D7AH/ A+wB/wPsAf8D7AH/A+wB/wPsAf8D7AH/A+wB/wPsAf8D6wH/A98B/wPJAf8D7QH/A/AB/wPxAf8DZwHy - AysBQhwAAwwBEAE/AcEB4gH/AREBngHHAf8BWAJaAcADUQGiAQABmAG7Af8BAAGjAcQB/wEAAbUB0wH/ + AysBQhwAAwwBEAE+AcEB4gH/ARABngHHAf8BWAJaAcADUQGiAQABmAG7Af8BAAGjAcQB/wEAAbUB0wH/ AQABwgHeAf8BAAGxAdAB/wGhAbcBvQH/Ab4BvAG6Af8BvQG7AbkB/wG9AboBuQH/AboBtwG1Af8BtgGz AbEB/wGyAa8BrQH/Aa4BqwGpAf8BpgGjAaEB/wGkAaEBnwH/AaIBnwGdAf8BnwGcAZoB/wGdAZoBmAH/ AZ0BmgGYAf8BrgGrAakB/wG5AbcBtQH/A1EBnxAAAY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEA @@ -403,8 +403,8 @@ AYsBAAH/AY4BiwEAAf8BjgGLAQAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMA Af8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/EAADMwFTA+wB/wPsAf8D6wH/A+sB/wPrAf8D6wH/ - A+sB/wPrAf8D6wH/A+sB/wPrAf8D6wH/A+sB/wPpAf8D3AH/A8cB/wP+Bf8DZwHyAywBRCQAA1wBzwEs - AbYB2wH/AQsBlwHCAf8BCQGeAcYB/wESAbEB1AH/AR4BvQHcAf8BJQHAAdsB/wFAAcIB1AH/AaMBwgHJ + A+sB/wPrAf8D6wH/A+sB/wPrAf8D6wH/A+sB/wPpAf8D3AH/A8cB/wP+Bf8DZwHyAywBRCQAA1wBzwEr + AbYB2wH/AQoBlwHCAf8BCAGeAcYB/wERAbEB1AH/AR0BvQHcAf8BJAHAAdsB/wE/AcIB1AH/AaMBwgHJ Af8BwgHAAb4B/wG/AbwBuwH/Ab0BuwG5Af8BuwG4AbcB/wG6AbcBtQH/AbQBsQGvAf8BrQGqAagB/wGr AagBpgH/AakBpgGkAf8BpgGjAaEB/wGkAaEBnwH/AaIBnwGdAf8BpwGkAaIB/wG4AbYBtAH/AbwBuQG4 Af8DQAFwFAABjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGL @@ -415,7 +415,7 @@ AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/ AwAB/wMAAf8DAAH/AwAB/wMAAf8DAAH/EAADMwFTA+oB/wPqAf8D6QH/A+kB/wPpAf8D6QH/A+kB/wPp Af8D6QH/A+kB/wPpAf8D6QH/A+kB/wPmAf8D2AH/A8YB/wP4Af8DZwHyAy0BRSgAA0ABcAGLAcoB6AH/ - ATsBvwHhAf8BNwG7Ad4B/wNUAa8DOgFgAwwBEANHAYADYgHvAcsByQHIAf8BxgHEAcMB/wHBAb8BvQH/ + AToBvwHhAf8BNgG7Ad4B/wNUAa8DOgFgAwwBEANHAYADYgHvAcsByQHIAf8BxgHEAcMB/wHBAb8BvQH/ AbwBuQG4Af8BugG3AbYB/wG5AbYBtAH/Aa8BrAGqAf8BrQGqAagB/wGrAagBpgH/AawBqQGnAf8BsAGt AawB/wG7AbgBtgH/Ab8BvAG7Af8DXAHPAyEBMBgAAY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEA Af8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGOAYsBAAH/AY4BiwEAAf8BjgGLAQAB/wGO @@ -1150,6 +1150,9 @@ True + + The seb(s):// link to the config file can contain an additional query string, separated from the main URL by '?' or '??' (if the URL itself doesn't contain a query). SEB will then append this query string to the Start URL. + 17, 17