#AutoIt3Wrapper_Run_Obfuscator=y
#Obfuscator_Parameters=/sf /sv /om /cs=0 /cn=0
#AutoIt3Wrapper_UseX64=n
#AutoIt3Wrapper_Res_Description=AD User-Computer to Group is a tool to add an user or computer object to a group in AD where the information is provided in a text file
#AutoIt3Wrapper_Res_Fileversion=0.9.1.0
#AutoIt3Wrapper_Res_Language=1033
#AutoIt3Wrapper_Res_Field=ProductName|AD User-Computer to Group
#AutoIt3Wrapper_Res_Field=Version|0.91
#AutoIt3Wrapper_Res_Field=Build|2012-01-06 beta
#AutoIt3Wrapper_Res_Field=Coded by|UEZ
#AutoIt3Wrapper_Res_Field=CompanyName|UEZ Software Production
#AutoIt3Wrapper_Res_Field=Compile date|%longdate% %time%
#AutoIt3Wrapper_Res_Field=AutoIt Version|%AutoItVer%
#AutoIt3Wrapper_UseUpx=n
#AutoIt3Wrapper_UPX_Parameters=--ultra-brute --crp-ms=999999 --all-methods --all-filters
#AutoIt3Wrapper_Run_After=..\..\..\ResourceHacker\ResHacker.exe -delete %out%, %out%, ICON, 1,
#AutoIt3Wrapper_Run_After=..\..\..\ResourceHacker\ResHacker.exe -delete %out%, %out%, ICON, 2,
#AutoIt3Wrapper_Run_After=..\..\..\ResourceHacker\ResHacker.exe -delete %out%, %out%, ICON, 3,
#AutoIt3Wrapper_Run_After=..\..\..\ResourceHacker\ResHacker.exe -delete %out%, %out%, MENU, 166,
#AutoIt3Wrapper_Run_After=..\..\..\ResourceHacker\ResHacker.exe -delete %out%, %out%, DIALOG, 1000,
#AutoIt3Wrapper_Run_After=..\..\..\ResourceHacker\ResHacker.exe -delete %out%, %out%, ICONGROUP, 162,
#AutoIt3Wrapper_Run_After=..\..\..\ResourceHacker\ResHacker.exe -delete %out%, %out%, ICONGROUP, 164,
#AutoIt3Wrapper_Run_After=..\..\..\ResourceHacker\ResHacker.exe -delete %out%, %out%, ICONGROUP, 169,
#AutoIt3Wrapper_Run_After=del /f /q "%scriptdir%\%scriptfile%_Obfuscated.au3"
;~ #AutoIt3Wrapper_Run_After=upx.exe --ultra-brute --crp-ms=999999 --all-methods --all-filters "%out%"
#AutoIt3Wrapper_Run_After=upx.exe --best --lzma "%out%"
;~ #AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6


#include <AD.au3>
#include <Array.au3>
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>
#include <GuiImageList.au3>
#include <GUIListView.au3>
#include <GuiStatusBar.au3>
#include <ListViewConstants.au3>
#include <ProgressConstants.au3>
#include <WindowsConstants.au3>

#NoTrayIcon
#RequireAdmin

Opt("MustDeclareVars", 1)


Global Const $ver = "v0.91 "
Global Const $build = "Build 2012-01-06 Beta"
If $CmdLine[0] And ($CmdLine[1] = "/debug" Or $CmdLine[1] = "-debug") Then $iAD_Debug = 2
SplashTextOn("Information", "Please be patient - trying to connect to Active Directory!", 680, 60, -1, -1, 1 + 16 + 32, "Arial", 18, 800)
Global Const $AD_UDF = _AD_Open()
Global $AD_UDF_err = @error
Global $AD_UDF_err_code
SplashOff()

Switch $AD_UDF_err
	Case 1
		$AD_UDF_err_code = "Installation of the custom error handler failed"
	Case 2
		$AD_UDF_err_code = "Creation of the COM object to the AD failed"
	Case 3
		$AD_UDF_err_code = "Open the connection to AD failed (among others generated if the user doesn't has query / modify access)"
	Case 4
		$AD_UDF_err_code = "Creation of the RootDSE object failed (generated when connection to the domain isn't successful)"
	Case 5
		$AD_UDF_err_code = "Creation of the DS object failed"
	Case 6
		$AD_UDF_err_code = "Parameter $sAD_HostServerParam and $sAD_ConfigurationParam are required when $sAD_DNSDomainParam is specified"
	Case 7
		$AD_UDF_err_code = "Parameter $sAD_PasswordParam is required when $sAD_UserIdParam is specified"
	Case 8
		$AD_UDF_err_code = "OpenDSObject method failed (on Windows XP or lower this shows that $sAD_UserIdParam and/or $sAD_PasswordParam are invalid)"
	Case Else
		$AD_UDF_err_code = "Undefined error has occured"
EndSwitch

Global Const $logfile = "AD User-Computer to Group.log"
If FileExists($logfile) And FileGetSize($logfile) > 10 * 1024 ^ 2 Then FileMove($logfile, FileGetTime($logfile, 0, 1) & "_" & $logfile)
WriteLog("Started by user: " & @LogonDomain & "\" & @UserName)

If Not $AD_UDF Then
	WriteLog("An unexpected error has occured! Error code is: " & $AD_UDF_err & " (" & @extended & ") - " & $AD_UDF_err_code)
	WriteLog("Ended." & @CRLF & @CRLF)
	_AD_Close()
	Exit MsgBox(16, "Error", "An unexpected error has occured! Error code is: " & $AD_UDF_err & " ->" & @CRLF & @CRLF & $AD_UDF_err_code, 30)
EndIf

If @LogonDNSDomain = "" Then
	WriteLog("Script aborted! Not logged in to a domain!")
	WriteLog("Ended." & @CRLF & @CRLF)
	_AD_Close()
	Exit MsgBox(16, "Error", "You must be logged on to the domain!", 30)
EndIf

Global $domain = @LogonDNSDomain
If $domain = "" Then $domain = @LogonDomain

Global Const $width = 505, $height = 600
Global Const $hGUI = GUICreate("AD User-Computer to Group " & $ver & $build, $width, $height, -1, -1, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_TABSTOP))
GUISetBkColor(0xB0C0D0)

Global Const $MenuItem = GUICtrlCreateMenu("&?")
Global Const $mAbout = GUICtrlCreateMenuItem("About", $MenuItem)

Global Const $StatusBar = _GUICtrlStatusBar_Create($hGUI)
Global $StatusBar_PartsWidth[4] = [72, 132, 172, 250]
_GUICtrlStatusBar_SetParts($StatusBar, $StatusBar_PartsWidth)
_GUICtrlStatusBar_SetText($StatusBar, "Items found:", 0)
_GUICtrlStatusBar_SetText($StatusBar, 0, 1)
_GUICtrlStatusBar_SetText($StatusBar, "Errors:", 2)
_GUICtrlStatusBar_SetText($StatusBar, "none", 3)

Global Const $Progressbar = GUICtrlCreateProgress(8, 536, 489, 17, $PBS_SMOOTH)

Global Const $Group = GUICtrlCreateGroup("Domain: " & $domain, 4, 8, 497, 489)
GUICtrlSetFont(-1, 8, 800, 0, "MS Sans Serif")

Global Const $ListView = GUICtrlCreateListView("User/Group Name (sAMAccountName)|Add to Groups|Status", 16, 32, 474, 454, _
		BitOR($GUI_SS_DEFAULT_LISTVIEW, $LVS_AUTOARRANGE, $LVS_NOSORTHEADER, $WS_VSCROLL), _
		BitOR($WS_EX_CLIENTEDGE, $LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES, $LVS_EX_DOUBLEBUFFER))
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 175)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 215)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 2, 55)
GUICtrlSetBkColor(-1, $GUI_BKCOLOR_LV_ALTERNATE)
;~ _GUICtrlListView_JustifyColumn(GUICtrlGetHandle($ListView), 1, 2)

GUICtrlCreateGroup("", -99, -99, 1, 1)

Global Const $bLoad = GUICtrlCreateButton("Load", 8, 504, 75, 25)
Global Const $bMove = GUICtrlCreateButton("Add Groups", 96, 504, 75, 25)
GUICtrlSetState(-1, $GUI_DISABLE)
Global Const $bExit = GUICtrlCreateButton("Exit", 422, 504, 75, 25)

_GDIPlus_Startup()

Global $hImage_ok = Load_BMP_From_Mem(OK())
Global $hImage_nok = Load_BMP_From_Mem(NOK())

Local $hBmp_ok = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage_ok)
Local $hBmp_nok = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage_nok)

Global $hIcons = _GUIImageList_Create(16, 16, 5, 3)
_GUIImageList_Add($hIcons, $hBmp_nok)
_GUIImageList_Add($hIcons, $hBmp_ok)
_GUICtrlListView_SetImageList($ListView, $hIcons, 1)

_GDIPlus_ImageDispose($hImage_nok)
_GDIPlus_ImageDispose($hImage_ok)
_WinAPI_DeleteObject($hBmp_nok)
_WinAPI_DeleteObject($hBmp_ok)
_GDIPlus_Shutdown()

GUISetState(@SW_SHOW)

Global $aFileContent, $ad, $error = 0, $nMsg, $file, $msg, $mcursor_old

Global Const $aWS = WinGetPos($hGUI)
Global Const $minwidth = $aWS[2]
Global Const $minheight = $aWS[3]

GUIRegisterMsg($WM_SIZE, "WM_SIZE")
GUIRegisterMsg($WM_GETMINMAXINFO, "WM_GETMINMAXINFO")

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE, $bExit
			GUIRegisterMsg($WM_SIZE, "")
			GUIRegisterMsg($WM_GETMINMAXINFO, "")
			_AD_Close()
			WriteLog("Ended." & @CRLF & @CRLF)
			GUIDelete($hGUI)
			Exit
		Case $MenuItem
		Case $mAbout
			MsgBox(64, "About", "AD User-Computer to Group" & @CRLF & $ver & $build & @CRLF & @CRLF & _
					"Coded by UEZ" & @CRLF & @CRLF & @CRLF & _
					"Thanks to Water for the great AD UDF ;-)" & @CRLF & @CRLF, 60, $hGUI)

		Case $bLoad
			$file = FileOpenDialog("Select a file with appropriate information", "", "Text File (*.txt;*.csv)")
			If Not @error Then
				WriteLog($file & " loaded properly")
				_GUICtrlStatusBar_SetText($StatusBar, 0, 1)
				_GUICtrlStatusBar_SetText($StatusBar, "none", 3)
				_GUICtrlListView_DeleteAllItems(GUICtrlGetHandle($ListView))
				$mcursor_old = MouseGetCursor()
				GUISetCursor(15, 1, $hGUI)
				GUISetState(@SW_DISABLE, $hGUI)
				$error = ParseFile($file)
				GUISetState(@SW_ENABLE, $hGUI)
				GUISetCursor($mcursor_old)
			Else
				WriteLog($file & " could not be loaded!")
				MsgBox(16, "Error", $file & " could not be loaded!", 30, $hGUI)
			EndIf
		Case $bMove
			$msg = MsgBox(32 + 4 + 256, "Question", "Proceed with adding user/computer to groups in AD?", 0, $hGUI)
			If $msg = 6 Then
				$ad = Add2Group()
				If $error Or $ad Then
					MsgBox(48, "Warning", "One or more errors have occured. Please check log file for more details!", 60, $hGUI)
				Else
					MsgBox(64, "Information", "No errors have occured!", 60, $hGUI)
				EndIf
				GUICtrlSetData($Progressbar, 0)
			EndIf
	EndSwitch
WEnd

Func ParseFile($file)
	Local $j, $sFile, $chk = 0, $sData
	$sFile = FileRead($file)
	$aFileContent = StringRegExp($sFile, "(.*)\|(.*)", 3)
	If @error Then
		WriteLog("Error: Content of " & $file & " is wrong!")
		_GUICtrlStatusBar_SetText($StatusBar, " Wrong content of file " & $file & " has been detected!", 3)
		GUISetState(@SW_ENABLE, $hGUI)
		Return MsgBox(16, "Error", "Wrong content of text file has been detected!", 30, $hGUI)
	EndIf
	$chk = PlausibilityCheck($aFileContent)
	If $chk Then _GUICtrlStatusBar_SetText($StatusBar, " some warrning/errors occured during file check. Check logfile for details!", 3)


	If Not UBound($aFileContent) Then
		WriteLog("Warning: File list is empty after plausibility check!")
		GUISetState(@SW_ENABLE, $hGUI)
		Return MsgBox(48, "Information", "Warning: List is empty because wrong entries were ignored!", 30, $hGUI)
	EndIf

	_GUICtrlStatusBar_SetText($StatusBar, UBound($aFileContent) / 2, 1)
	GUICtrlSetState($ListView, $GUI_HIDE)
	For $j = 0 To UBound($aFileContent) - 1 Step 2
		$sData = $aFileContent[$j] & "|" & $aFileContent[$j + 1]
		GUICtrlCreateListViewItem($sData, $ListView)
		GUICtrlSetBkColor(-1, 0xE8E8FF) ;RGB
	Next
	GUICtrlSetState($ListView, $GUI_SHOW)
	GUICtrlSetState($bMove, $GUI_ENABLE)
	Return $chk
EndFunc   ;==>ParseFile

Func PlausibilityCheck(ByRef $array)
	Local $i = 0, $err = False

	$i = 0
	While $i < UBound($array) ;search for empty entries and strip leading / trailing white space
		$array[$i + 1] = StringStripCR($array[$i + 1])
		$array[$i] = StringStripWS($array[$i], 3)
		$array[$i + 1] = StringStripWS($array[$i + 1], 7)
		If StringRight($array[$i + 1] , 1)  = "," Then $array[$i + 1] = StringReplace($array[$i + 1], "," , "", -1)
		If $array[$i] = "" Then
			WriteLog("Warning: Empty entry found. Whole line will be ignored!")
			_ArrayDelete($array, $i)
			_ArrayDelete($array, $i)
			$err = True
			$i -= 2
		EndIf
		$i += 2
	WEnd

	Return $err
EndFunc   ;==>PlausibilityCheck

Func Add2Group()
	Local $add, $index, $j, $k, $ec, $aSplit, $err_occured = False
	Local $om = MouseGetCursor()
	GUISetCursor(15, 1, $hGUI)
	GUISetState(@SW_DISABLE, $hGUI)
	_GUICtrlListView_Scroll($ListView, 0, -0xFFFF)
	$index = UBound($aFileContent) / 2
	$j = 1
	For $i = 0 To UBound($aFileContent) - 2 Step 2
		$aSplit = StringSplit($aFileContent[$i + 1], ",", 2)
		For $k = 0 To UBound($aSplit) - 1
			$add = _AD_AddUserToGroup($aSplit[$k], $aFileContent[$i])
			$ec = @error
			If $ec Then
				$err_occured = $ec
				Switch $ec
					Case 1
						WriteLog("Error: AD group " & $aSplit[$k] & " does not exist.")
					Case 2
						WriteLog("Error: AD user / computer '" & $aFileContent[$i] & "' does not exist")
					Case 3
						WriteLog("Error: AD user / computer '" & $aFileContent[$i] & "'  is already a member of " & $aSplit[$k])
					Case Else
						WriteLog("Error: An unexpected error " & $ec & " has accoured!")
				EndSwitch
			EndIf
			If Not $ec Then
				WriteLog("Groups " & $aFileContent[$i + 1] & " added to user / computer " & $aFileContent[$i] & " successfully")
				_GUICtrlListView_AddSubItem($ListView, $j - 1, "OK", 2, 1)
			Else
				_GUICtrlListView_AddSubItem($ListView, $j - 1, "Error", 2, 0)
				_GUICtrlStatusBar_SetText($StatusBar, " problems occured during creation! Check log file for details!", 3)
			EndIf
		Next

		If $i > 15 Then _GUICtrlListView_Scroll($ListView, 0, 16)
		GUICtrlSetData($Progressbar, $j / $index * 100)
		$j += 1
	Next
	GUISetState(@SW_ENABLE, $hGUI)
	GUICtrlSetState($bMove, $GUI_DISABLE)
	GUISetCursor($om)
	Return $err_occured
EndFunc   ;==>MoveObj

Func WriteLog($text)
	Local $hFile = FileOpen($logfile, 1)
	If $hFile = -1 Then Return MsgBox(16, "Error", "Unable to create log file!", 30, $hGUI)
	Local $TimeStamp = @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & @TAB
	FileWriteLine($hFile, $TimeStamp & $text)
	FileClose($hFile)
EndFunc   ;==>WriteLog

Func WM_SIZE($hWnd, $iMsg, $iwParam, $ilParam)
    _GUICtrlStatusBar_Resize($StatusBar)
    Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_SIZE

Func WM_GETMINMAXINFO($hWnd, $Msg, $wParam, $lParam)
    Local $minmaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam)
    DllStructSetData($minmaxinfo, 7, $minwidth) ;min width
    DllStructSetData($minmaxinfo, 8, $minheight) ;min height
    Return "GUI_RUNDEFMSG"
EndFunc   ;==>WM_GETMINMAXINFO

Func Load_BMP_From_Mem($mem_image) ;coded by UEZ - thanks to progandy for the MemGlobalAlloc and tVARIANT lines
	Local $memBitmap, $len, $tMem, $hImage, $hData, $pData, $hStream, $hBitmapFromStream
	$memBitmap = Binary($mem_image) ;load image  saved in variable (memory) and convert it to binary
    $len = BinaryLen($memBitmap) ;get length of image
    $hData = _MemGlobalAlloc($len, $GMEM_MOVEABLE) ;allocates movable memory  ($GMEM_MOVEABLE = 0x0002)
    $pData = _MemGlobalLock($hData)  ;translate the handle into a pointer
    $tMem = DllStructCreate("byte[" & $len & "]", $pData) ;create struct
     DllStructSetData($tMem, 1, $memBitmap) ;fill struct with image data
    _MemGlobalUnlock($hData) ;decrements the lock count  associated with a memory object that was allocated with GMEM_MOVEABLE
	$hStream = _WinAPI_CreateStreamOnHGlobal($pData) ;Creates a stream object that uses an HGLOBAL memory handle to store the stream contents
	$hBitmapFromStream = _GDIPlus_BitmapCreateFromStream($hStream) ;Creates a Bitmap object based on an IStream COM interface
	Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    Local $aCall = DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT))
	$tMem = 0
	Return $hBitmapFromStream
EndFunc

Func _WinAPI_CreateStreamOnHGlobal($hGlobal = 0, $fDeleteOnRelease = True)
	Local $aResult = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "hwnd", $hGlobal, "int", $fDeleteOnRelease, "ptr*", 0)
	If @error Then Return SetError(@error, @extended, 0)
	Return $aResult[3]
EndFunc   ;==>_WinAPI_CreateStreamOnHGlobal

Func _GDIPlus_BitmapCreateFromStream($pStream)
	Local $aResult = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $pStream, "int*", 0)
	If @error Then Return SetError(@error, @extended, 0)
	Return $aResult[2]
EndFunc   ;==>_GDIPlus_BitmapCreateFromStream

Func OK()
	Local _
	$OK = '0x89504E470D0A1A0A0000000D49484452000000100000001008060000001FF3FF61000002624944415478DA63FCFFFF3F032940B94D8AF9EFBBBF820F7A5EBE01F11949314038988F43CD477615AF00B7D9C589B74B5F1DFCB08624034C266ACC50D2914D67E36361D85F7776C1B31DAF7B893640BB4D31DEC85E7B01271F1BC399C557CE9FEFBEDD0B14E624CA00992C610DDB28E3135C22ECFCF7CF3F7DBD3FEE7C07C31F0656A0143F41030422B958CC63B4F6C8EB48DA7FFBFEE3FF5A97437D3F9EFE7A0A0A1220FE48D000B3396AE59681061D6CDCAC0CEB120E6CBDB7F2D956A0B008107F06E26B780D902B12D6F12B753C2124CECF7D76F5B547DB224EF401857981F81B10DF00E22B60035CB6984EE36267D73A5E7FA5F5CDF18F0780127F81E2FF824ED8EDD03454767FF7F6C3FF05C65BFB7EBCF8FD0A28C702C47780F822103F021B90F130F0BF84BC30C3BB379F7EAD09D95FFAFCE09BC55ABD322EAE0996AB18D8181876141F3B7073D6D375400D8240FC0CAAF936107F021B206E2514E23BDF7AAE989210DFFB579FFE6D483DD8615AA1E123A52EA6F7F0FCD30F3B7CCE7430FC0519C5F015E46C20BE0CC4AF817AFF800D60646464E79466F3F65E63394F489E8FFFCBD76F0C7FBEFF61F8CDF48B615FCC85C51F2F7CBF00D4C005C47781F83C103F04EAFB0E4FCA400398816C210E69D6708715BA3D4C6C'
    $OK &= '4CEC3FFFFD6478B4EDE5B3DBCDAF6600E59880F815D4E9A0C0FB000A23B80160062323C889A2BCFAEC599AFD52553FBFFD64B812FB7CFBDFF7FF6F02C5DF409D0D32E03950CF2F584CA14423D01050EA12E5D4622964F8CFA0F7FDFA9FFB403E48F175203E090DB82FFF913461A403A84BA440790788F58118E4D4B3407C06885F02D5FF45560F0094401C0EBF687F2D0000000049454E44AE426082'
	Return Binary($OK)
EndFunc

Func NOK()
	Local _
	$NOK = '0x89504E470D0A1A0A0000000D49484452000000100000001008060000001FF3FF61000003314944415478DAA5926B48536118C7DFF7B4CD4DE7DC20AFA9790953038B301925445214857EB014BA2B59A41F824A4A29342A52D2AE1059505452B42E445F4A29C42EA2ADBC2C74F3522E9D9BBA8B9B73677ACECECE7ADE710AFBDC81DF87F3BECFF37F9FE7F93F381008A0FFF9F0A747F78B72161CD75DD393717EB9D2D6AE3334B568BB6F3ED20FBBE0DE1F58F482B1A25CA654CA4B788A3FD2DCF661EEA14E7F0D9FD8B6E5F0DEE4A88655ABB322289E479C670E75F7E83AABDABE567758ADDD90E7050D7EBCF4C086A8C8D08621379D75FE4DDB953726CBFD0584784CAAC85BB932BB2023A56A577A7241A4DB2AE21C76D4FFCB34D968A22B9F5BA65A8C45F9E591F691DAD733ECAFAB8689CA6E9635405E18200D0A003220215BA5DC7F28397A5F3E9E5D1EE271A27E4E6A655431A3B1D671B5CE87BE7D66F98B771D8C5948A60006931631C622F85101CBC5186794C6C7EE3C2C766E5722245E60596414C98D5D0BBEC64B53DE11880921890099910DFF9911888805E5A55736E616655806CE24602E4C21C6A8CB4B99CA273C77667CDC14DCDB810901175E6C2388E01FBB0B2B687D4743842C4476D74CF7F9FC9CB42646927E799A315C30BBEF40583FA027AF432EF78F80F968699955DB7A4BC9CD4B34B4EC4BF5E8E4'
    $NOK &= '6D384E3A9518595C1523C9CC1F743577B8E97B703600CC1077FE0AB4EE29DE9A621D7C816C66790FBD64FCE04F7B2D8302A4DF700954762935BA24571A88DF6CB0977BFCFEAFA405C89D0F0A68D4EA8454157A1F6E35A6B959C4958ECCD60F308C85D8444A25C1326A89A2354DD5F4C446773639E61BC95E91790405A677E4D5D3D4DC69649B425A273BFE6A867EF9CC4E3B20605A287714E0D78787ED3A17157AB6D0E838E9E1F9EF4418EB37E52AA4518A77126A3E8771B850D798455B67726AFBBDEC2404F4013A4188F4AAAC4F8CBBDDEBF2D8356EF703F837E11BEBD644A85397B5A78A7C6B260C06BE6ECCF95863F790D789E79DC03054490B2E8952E461EA1C91A8E8A96BB6990C32D8424DE68AE3659989F51F8786C7CAF496B70C1F60E1B207E81286E55B6475482845257A799EEC8D3F28B0562A8D4E0A951E6B737BD0ACDF4F96C9097400BD825D81C5BB22ACBE0290FF065C149BF6DD07A3F30000000049454E44AE426082'
	Return Binary($NOK)
EndFunc