{"javascript":"$(document).ready(function() {\n\n /////Translate interface\n /////List of localization keys, feel free to extend it.\n InitTranslations({})\n\n $(\".TranslateEn\").on(\"click\", function(event) {\n Translate(\"en\")\n })\n\n $(\".TranslateRu\").on(\"click\", function(event) {\n Translate(\"ru\")\n })\n\n /////Init manual captcha solving interface\n InitManualCaptchaSolver()\n\n /////Show dialogs when clicked on buttons of LinesFromFile or FilesFromDirectory resource types. \n InitFileAndFolderChooserButtons()\n\n /////Hide main global tab header on start\n $(\"#GlobalTabsHeader\").hide()\n\n /////Init dialogs to edit random strings\n InitRandomStringModals()\n\n /////Init validation and resource visibility\n InitResourcesValidationAndVisibility()\n\n\n\n /////Init browser viewer\n InitBrowserViewer()\n\n /////Api event handler\n Api.SetEventHandler(function(EventType, EventData) {\n\n /////Script started, need to switch tabs and update interface\n if (EventType == \"start\") {\n UIkit.tab($(\"#GlobalTabsHeader\")[0]).show(1);\n $(\"#CardStatusRunning\").show()\n $(\"#CardStatusStopped\").hide()\n $(\"#ThreadsRunning\").html(\"0\")\n $(\"#Success\").html(\"0\")\n $(\"#Failures\").html(\"0\")\n $(\"#BrowserNumber\").html(\"0\")\n $(\"#Logs\").css(\"max-height\", \"400px\")\n $(\"#ExpandLog\").show()\n $(\"#HideLog\").hide()\n\n /////Clear captchas controls\n ClearCaptchas()\n\n /////Refresh result downloaded number\n $(\".ResultNumber\").html(\"0\")\n\n ClearBrowserViewer()\n\n\n /////Clear logs\n $('#Logs').html(\"\")\n }\n\n /////Script stopped, need to update interface\n if (EventType == \"stop\") {\n UIkit.tab($(\"#GlobalTabsHeader\")[0]).show(1);\n $(\"#CardStatusRunning\").hide()\n $(\"#CardStatusStopped\").show()\n $(\"#ThreadsRunning\").html(\"0\")\n $(\"#BrowserNumber\").html(\"0\")\n\n }\n\n /////Update result number counter\n if (EventType == \"result\") {\n let ResultNumberElement = $(\".ResultNumber[data-index=\" + EventData[\"number\"] + \"]\")\n let CurrentValue = parseInt(ResultNumberElement.html())\n ResultNumberElement.html((CurrentValue + 1).toString())\n }\n\n /////Process captcha\n if (EventType == \"captcha\") {\n AddCaptcha(EventData[\"id\"], EventData[\"is_image\"], EventData[\"data\"])\n }\n\n /////Script restarted, need to switch tabs\n if (EventType == \"restart\") {\n UIkit.tab($(\"#GlobalTabsHeader\")[0]).show(0);\n $(\"#RunScript\").removeAttr(\"disabled\")\n }\n\n\n\n /////Display log\n if (EventType == \"log\") {\n if (EventData[\"type\"] == \"success\") {\n return\n }\n let Logs = $('#Logs');\n let LogLine = $(\"
\").addClass(\"log-line\").attr(\"data-log-type\", EventData[\"type\"])\n let Text = $(\"\").text(EventData[\"text\"])\n\n /////Add action id\n if (EventData[\"action_id\"]) {\n LogLine.append($(\"\").text(\"[\" + EventData[\"action_id\"] + \"] \").addClass(\"uk-text-muted\"))\n }\n\n /////Set color\n if (EventData[\"type\"] == \"success\") {\n Text.addClass(\"uk-text-success\")\n } else if (EventData[\"type\"] == \"info\") {\n Text.addClass(\"uk-text-muted\")\n } else if (EventData[\"type\"] == \"fail\") {\n Text.addClass(\"uk-text-danger\")\n }\n\n /////Remove old lines\n $('#Logs .log-line').slice(500).remove();\n\n\n /////Append text\n LogLine.append(Text)\n Logs.prepend(LogLine)\n }\n\n /////Browser started, need to update running browser label\n if (EventType == \"browser_add\") {\n let CurrentValue = parseInt($(\"#BrowserNumber\").html())\n $(\"#BrowserNumber\").html((CurrentValue + 1).toString())\n\n /////Add browser to viewer\n AddBrowser(EventData[\"browser_id\"], EventData[\"thread_number\"])\n }\n /////Browser finished, need to update running browser label\n if (EventType == \"browser_remove\") {\n let CurrentValue = parseInt($(\"#BrowserNumber\").html())\n $(\"#BrowserNumber\").html((CurrentValue - 1).toString())\n\n /////Remove browser from viewer\n RemoveBrowser(EventData[\"browser_id\"], EventData[\"thread_number\"])\n }\n\n /////Thread started, need to update running threads label\n if (EventType == \"thread_start\") {\n let CurrentValue = parseInt($(\"#ThreadsRunning\").html())\n $(\"#ThreadsRunning\").html((CurrentValue + 1).toString())\n }\n\n /////Thread ended, need to update running threads label and success or failures\n if (EventType == \"thread_end\") {\n let CurrentValue = parseInt($(\"#ThreadsRunning\").html())\n $(\"#ThreadsRunning\").html((CurrentValue - 1).toString())\n\n if (EventData[\"success\"]) {\n CurrentValue = parseInt($(\"#Success\").html())\n $(\"#Success\").html((CurrentValue + 1).toString())\n\n } else {\n CurrentValue = parseInt($(\"#Failures\").html())\n $(\"#Failures\").html((CurrentValue + 1).toString())\n\n\n }\n }\n\n /////Database structure changed, need to update database resources\n if (EventType == \"database_structure_changed\") {\n UpdateDatabaseResources()\n }\n\n })\n\n /////Start script after run button is clicked\n $(\"#RunScript\").on(\"click\", function() {\n\n /////Disable run button immediately\n $(\"#RunScript\").attr(\"disabled\", \"disabled\")\n /////Start script\n Api.AcceptResources()\n\n });\n\n /////Show all log\n $(\"#ExpandLog\").on(\"click\", function() {\n $(\"#Logs\").css(\"max-height\", \"100000px\")\n $(\"#ExpandLog\").hide()\n $(\"#HideLog\").show()\n });\n\n /////Hide log partly\n $(\"#HideLog\").on(\"click\", function() {\n $(\"#Logs\").css(\"max-height\", \"400px\")\n $(\"#ExpandLog\").show()\n $(\"#HideLog\").hide()\n });\n\n $(\"#NumberOfClicks\").change(function() {\n var value = $(\"#NumberOfClicks\").val()\n Api.SetGlobalVariable(\"CLICK_NUMBER\", value)\n });\n\n\n\n /////Stop script after run button is clicked\n $(\"#StopScript\").on(\"click\", function() {\n /////Ask user if he wants to stop thread instantly\n UIkit.modal.dialog(`
\n
\n
${tr(\"Please select script stop type. If \\\"Wait each thread\\\" option is selected, script won't be stopped until all threads will finish its work and therefore this method will take some time. \\\"Stop instant\\\" will interrupt script at same second, but all thread data will be lost.\")}
\n
\n
\n
\n
\n
\n \n
`);\n\n });\n\n /////Restart script after restart button is clicked\n $(\".RestartScript\").on(\"click\", function() {\n Api.Restart()\n });\n\n /////Show script report\n $(\"#ShowScriptReport\").on(\"click\", function() {\n\n\n ///// Show modal\n let dialog = UIkit.modal(`
\n
\n \n
\n
\n

${tr('Script report')}

\n
\n
Loading ...
\n
\n
\n
`)\n\n dialog.show()\n\n let IsDialogOpen = true\n\n /////Destroy report when hidden \n UIkit.util.on(\"#ReportModal\", 'hidden', function() {\n dialog.$destroy(true);\n IsDialogOpen = false\n });\n\n let ShowScriptReport = function() {\n /////Set script report data\n Api.GetScriptReport().then((res) => {\n\n if (!IsDialogOpen)\n return\n\n $(\"#ScriptReportResult\").html(res)\n /////Autoupdate\n setTimeout(ShowScriptReport, 3000)\n })\n }\n\n ShowScriptReport()\n\n });\n\n /////Show resources report\n $(\"#ResourcesReport\").on(\"click\", function() {\n\n ///// Show modal\n let dialog = UIkit.modal(`
\n
\n \n
\n
\n

${tr('Resources report')}

\n
\n
Loading ...
\n
\n
\n
`)\n\n dialog.show()\n\n let IsDialogOpen = true\n\n /////Destroy report when hidden \n UIkit.util.on(\"#ReportModal\", 'hidden', function() {\n dialog.$destroy(true);\n IsDialogOpen = false\n\n });\n\n let ShowResourcesReport = function() {\n /////Set script report data\n Api.GetResourcesReport().then((res) => {\n\n if (!IsDialogOpen)\n return\n\n $(\"#ResourcesReportResult\").html(res)\n /////Autoupdate\n setTimeout(ShowResourcesReport, 3000)\n })\n }\n\n ShowResourcesReport()\n\n });\n\n /////Initialize menus\n $(\"#Menu1\").attr(\"uk-offcanvas\", \"overlay: true\")\n $(\"#Menu1Content\").addClass(\"uk-offcanvas-bar\")\n\n $(\"#Menu2\").attr(\"uk-offcanvas\", \"overlay: true\")\n $(\"#Menu2Content\").addClass(\"uk-offcanvas-bar\")\n\n $(\"#Menu1Button\").on(\"click\", function() {\n UIkit.offcanvas(\"#Menu1\").show();\n });\n\n $(\"#Menu2Button\").on(\"click\", function() {\n UIkit.offcanvas(\"#Menu2\").show();\n });\n\n /////Close menu after click on any link\n $(\"#Menu1 a\").click(function() {\n UIkit.offcanvas(\"#Menu1\").hide();\n })\n\n $(\"#Menu2 a\").click(function() {\n UIkit.offcanvas(\"#Menu2\").hide();\n })\n\n /////Show about window\n $(\".About\").on(\"click\", function() {\n UIkit.modal.alert(`\n
${tr('Script name')}:
\n
SiteVisitorWithInterface *
\n
${tr('Version')}:
\n
4.0.0
\n
* ${tr('Made with')} BrowserAutomationStudio.
\n `)\n });\n\n /////Download log\n $(\"#DownloadLog\").on(\"click\", function() {\n Api.DownloadLog().then((res) => {\n var blob = new Blob([res], {\n type: \"text/plain;charset=utf-8\"\n });\n saveAs(blob, \"SiteVisitorWithInterface.log.txt\");\n })\n });\n\n /////Download results\n $(\".DownloadResult\").on(\"click\", function(event) {\n let el = $(event.target.closest(\".DownloadResult\"))\n let index = parseInt(el.attr(\"data-index\"))\n Api.DownloadResult(index).then((res) => {\n var blob = new Blob([res], {\n type: \"text/plain;charset=utf-8\"\n });\n saveAs(blob, \"SiteVisitorWithInterface.results.\" + index + \".txt\");\n })\n });\n\n /////Restore default resources values\n $(\"#RestoreDefaults\").on(\"click\", function(event) {\n /////Find all resources with default values\n $(\"[data-default-value]\").each(function(index, el) {\n /////SetValue is function, that sets resource value\n SetValue($(el).attr(\"data-resource-name\"), $(el).attr(\"data-default-value\"))\n })\n });\n\n\n /////Show database manager\n $(\".ShowDatabase\").click(function() {\n Api.ShowDatadaseManager()\n })\n\n\n /////Update resources with type \"database\" with correct values\n UpdateDatabaseResources()\n\n /////Autoload resources, which was entered last time, may be removed.\n Api.AutoLoadResources()\n\n $(\"#RunScript\").click()\n\n /////After everything is initialized may show body\n $(\"body\").fadeIn()\n\n /////Events\n\n});\n\n/////Resource values are obtained through this function when hitting run button, you can change it.\n/////For example, you can edit value entered by user, make custom validation, or replace resource system compleatelly\nfunction GetResourceValue(ResourceName) {\n return GetValue(ResourceName)\n}","cssFiles":["https://bablosoft.com/buildinterface/uikit/css/uikit.css"],"jsFiles":["https://bablosoft.com/buildinterface/jquery/jquery.min.js?v=2","https://bablosoft.com/buildinterface/uikit/js/uikit.js?v=2","https://bablosoft.com/buildinterface/uikit/js/uikit-icons.js?v=2","https://bablosoft.com/buildinterface/charts/utils.js?v=2","https://bablosoft.com/buildinterface/charts/charts.js?v=2","https://bablosoft.com/buildinterface/filesaver/FileSaver.min.js?v=2","https://bablosoft.com/buildinterface/interface-extensions/extensions.js?v=2","https://bablosoft.com/buildinterface/bas-api/bas-api.js?v=2"],"css":".file-item {\n width: 150px;\n height: 130px;\n padding-top: 10px;\n padding-right: 10px;\n padding-bottom: 10px;\n padding-left: 10px;\n font-size: small;\n overflow-x: hidden;\n overflow-y: hidden;\n margin-right: 20px;\n cursor: pointer;\n}\n\n#Menu1Content li {\n margin-bottom: 20px;\n}\n\n#Menu2Content li {\n margin-bottom: 15px;\n}\n\npre {\n white-space: pre-wrap;\n overflow-wrap: break-word;\n}\n\n#Logs {\n margin-left: 10px;\n font-size: small;\n max-height: 400px;\n overflow-x: hidden;\n overflow-y: hidden;\n}\n\n.ui-panel {\n display: flex;\n flex-direction: column;\n}\n\n#ScriptHeaderResources {\n border-bottom-width: 1px;\n border-bottom-style: solid;\n border-bottom-color: rgb(221, 221, 221);\n background-color: rgb(255, 255, 255);\n display: flex;\n padding-top: 10px;\n padding-right: 10px;\n padding-bottom: 10px;\n padding-left: 10px;\n}\n\n#ScriptHeaderProgress {\n border-bottom-width: 1px;\n border-bottom-style: solid;\n border-bottom-color: rgb(221, 221, 221);\n background-color: rgb(255, 255, 255);\n display: flex;\n padding-top: 10px;\n padding-right: 10px;\n padding-bottom: 10px;\n padding-left: 10px;\n}\n\n.table-row {\n display: flex;\n justify-content: flex-start;\n align-items: stretch;\n flex-wrap: nowrap;\n padding-top: 0px;\n padding-bottom: 10px;\n}\n\n.table-cell {\n min-height: 25px;\n flex-grow: 1;\n flex-basis: 100%;\n}\n\n#ResourcesTabsHeader {\n display: flex;\n margin-bottom: 0px;\n}\n\n#TabResources {\n margin-left: 0px;\n}\n\n#ResourcesTabsContent {\n margin-top: 0px;\n}\n\n#GlobalTabsHeader {\n margin-bottom: 0px;\n margin-top: 0px;\n}\n\n#ResourcesTabsContent {\n padding-top: 0px;\n}\n\n[uk-alert] {\n font-size: small;\n}\n\n.row {\n display: flex;\n justify-content: flex-start;\n align-items: stretch;\n flex-wrap: nowrap;\n padding-top: 10px;\n padding-right: 10px;\n padding-bottom: 10px;\n padding-left: 10px;\n}\n\n.cell {\n min-height: 25px;\n flex-grow: 1;\n flex-basis: 100%;\n}\n\n.tab-not-valid {\n border-left-color: red;\n border-left-style: solid;\n border-left-width: 2px;\n}\n\n.uk-tab-left>*,\n.uk-tab-right>* {\n margin-bottom: 5px;\n}\n\n.tab-not-visible {\n display: none;\n}\n\n.resource-not-visible {\n display: none;\n}\n\n#i4msw {\n justify-content: flex-start;\n width: 100%;\n line-height: 30px;\n}\n\n#iq6h2 {\n font-weight: bold;\n}\n\n#ixo3f {\n min-width: 40px;\n}\n\n#Menu1Button {\n padding-top: 4px;\n padding-right: 4px;\n padding-bottom: 4px;\n padding-left: 4px;\n}\n\n#iz7vf {\n border-top-width: 1px;\n border-top-style: solid;\n border-top-color: rgb(221, 221, 221);\n border-bottom-width: 1px;\n border-bottom-style: solid;\n border-bottom-color: rgb(221, 221, 221);\n}\n\n#i772z {\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n}\n\n#iknag {\n justify-content: flex-start;\n width: 100%;\n line-height: 30px;\n}\n\n#initc {\n font-weight: bold;\n}\n\n#ipkkb {\n min-width: 40px;\n}\n\n#Menu2Button {\n padding-top: 4px;\n padding-right: 4px;\n padding-bottom: 4px;\n padding-left: 4px;\n}\n\n#i7rms {\n font-size: small;\n}\n\n#i8efq {\n font-size: small;\n}\n\n#CardBrowsers {\n font-size: small;\n}\n\n#CardProgress {\n font-size: small;\n}\n\n#iwb0bj {\n margin-top: 30px;\n margin-bottom: 20px;\n}\n\n#iqyixk {\n margin-left: 10px;\n margin-top: 10px;\n}\n\n#iy0dqq {\n margin-left: 10px;\n margin-top: 10px;\n}","html":"
\n\t\n\t\n
\n\n
\n\t
\n\t\t\n\t
\n
\n
\n\t
\n\t\t\n\t
\n
\n"}