├── MyPinTool.cpp ├── MyPinTool.sln ├── MyPinTool.vcxproj ├── MyPinTool.vcxproj.filters ├── README.md ├── makefile ├── makefile.rules ├── py ├── bbl_manager.py ├── block.py ├── config.py ├── handler.py ├── instruction.py ├── main.py ├── program.py ├── pyh.py ├── report.py ├── report │ ├── css │ │ └── common.css │ ├── index.html │ ├── js │ │ └── common.js │ ├── semantic │ │ ├── components │ │ │ ├── accordion.css │ │ │ ├── accordion.js │ │ │ ├── accordion.min.css │ │ │ ├── accordion.min.js │ │ │ ├── ad.css │ │ │ ├── ad.min.css │ │ │ ├── api.js │ │ │ ├── api.min.js │ │ │ ├── breadcrumb.css │ │ │ ├── breadcrumb.min.css │ │ │ ├── button.css │ │ │ ├── button.min.css │ │ │ ├── card.css │ │ │ ├── card.min.css │ │ │ ├── checkbox.css │ │ │ ├── checkbox.js │ │ │ ├── checkbox.min.css │ │ │ ├── checkbox.min.js │ │ │ ├── comment.css │ │ │ ├── comment.min.css │ │ │ ├── dimmer.css │ │ │ ├── dimmer.js │ │ │ ├── dimmer.min.css │ │ │ ├── dimmer.min.js │ │ │ ├── divider.css │ │ │ ├── divider.min.css │ │ │ ├── dropdown.css │ │ │ ├── dropdown.js │ │ │ ├── dropdown.min.css │ │ │ ├── dropdown.min.js │ │ │ ├── feed.css │ │ │ ├── feed.min.css │ │ │ ├── flag.css │ │ │ ├── flag.min.css │ │ │ ├── form.css │ │ │ ├── form.js │ │ │ ├── form.min.css │ │ │ ├── form.min.js │ │ │ ├── grid.css │ │ │ ├── grid.min.css │ │ │ ├── header.css │ │ │ ├── header.min.css │ │ │ ├── icon.css │ │ │ ├── icon.min.css │ │ │ ├── image.css │ │ │ ├── image.min.css │ │ │ ├── input.css │ │ │ ├── input.min.css │ │ │ ├── item.css │ │ │ ├── item.min.css │ │ │ ├── label.css │ │ │ ├── label.min.css │ │ │ ├── list.css │ │ │ ├── list.min.css │ │ │ ├── loader.css │ │ │ ├── loader.min.css │ │ │ ├── menu.css │ │ │ ├── menu.min.css │ │ │ ├── message.css │ │ │ ├── message.min.css │ │ │ ├── modal.css │ │ │ ├── modal.js │ │ │ ├── modal.min.css │ │ │ ├── modal.min.js │ │ │ ├── nag.css │ │ │ ├── nag.js │ │ │ ├── nag.min.css │ │ │ ├── nag.min.js │ │ │ ├── popup.css │ │ │ ├── popup.js │ │ │ ├── popup.min.css │ │ │ ├── popup.min.js │ │ │ ├── progress.css │ │ │ ├── progress.js │ │ │ ├── progress.min.css │ │ │ ├── progress.min.js │ │ │ ├── rail.css │ │ │ ├── rail.min.css │ │ │ ├── rating.css │ │ │ ├── rating.js │ │ │ ├── rating.min.css │ │ │ ├── rating.min.js │ │ │ ├── reset.css │ │ │ ├── reset.min.css │ │ │ ├── reveal.css │ │ │ ├── reveal.min.css │ │ │ ├── search.css │ │ │ ├── search.js │ │ │ ├── search.min.css │ │ │ ├── search.min.js │ │ │ ├── segment.css │ │ │ ├── segment.min.css │ │ │ ├── shape.css │ │ │ ├── shape.js │ │ │ ├── shape.min.css │ │ │ ├── shape.min.js │ │ │ ├── sidebar.css │ │ │ ├── sidebar.js │ │ │ ├── sidebar.min.css │ │ │ ├── sidebar.min.js │ │ │ ├── site.css │ │ │ ├── site.js │ │ │ ├── site.min.css │ │ │ ├── site.min.js │ │ │ ├── state.js │ │ │ ├── state.min.js │ │ │ ├── statistic.css │ │ │ ├── statistic.min.css │ │ │ ├── step.css │ │ │ ├── step.min.css │ │ │ ├── sticky.css │ │ │ ├── sticky.js │ │ │ ├── sticky.min.css │ │ │ ├── sticky.min.js │ │ │ ├── tab.css │ │ │ ├── tab.js │ │ │ ├── tab.min.css │ │ │ ├── tab.min.js │ │ │ ├── table.css │ │ │ ├── table.min.css │ │ │ ├── transition.css │ │ │ ├── transition.js │ │ │ ├── transition.min.css │ │ │ ├── transition.min.js │ │ │ ├── video.css │ │ │ ├── video.js │ │ │ ├── video.min.css │ │ │ ├── video.min.js │ │ │ ├── visibility.js │ │ │ └── visibility.min.js │ │ ├── jquery.address.js │ │ ├── jquery.js │ │ ├── semantic.css │ │ ├── semantic.js │ │ ├── semantic.min.css │ │ ├── semantic.min.js │ │ └── themes │ │ │ ├── basic │ │ │ └── assets │ │ │ │ └── fonts │ │ │ │ ├── icons.eot │ │ │ │ ├── icons.ttf │ │ │ │ └── icons.woff │ │ │ └── default │ │ │ └── assets │ │ │ ├── fonts │ │ │ ├── icons.eot │ │ │ ├── icons.otf │ │ │ ├── icons.ttf │ │ │ ├── icons.woff │ │ │ └── icons.woff2 │ │ │ └── images │ │ │ └── flags.png │ └── template.html ├── runtimeblock.py ├── symexec.py └── trace.py ├── r.sh └── report.png /MyPinTool.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MyPinTool", "MyPinTool.vcxproj", "{639EF517-FCFC-408E-9500-71F0DC0458DB}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {639EF517-FCFC-408E-9500-71F0DC0458DB}.Debug|x64.ActiveCfg = Debug|x64 17 | {639EF517-FCFC-408E-9500-71F0DC0458DB}.Debug|x64.Build.0 = Debug|x64 18 | {639EF517-FCFC-408E-9500-71F0DC0458DB}.Debug|x86.ActiveCfg = Debug|Win32 19 | {639EF517-FCFC-408E-9500-71F0DC0458DB}.Debug|x86.Build.0 = Debug|Win32 20 | {639EF517-FCFC-408E-9500-71F0DC0458DB}.Release|x64.ActiveCfg = Release|x64 21 | {639EF517-FCFC-408E-9500-71F0DC0458DB}.Release|x64.Build.0 = Release|x64 22 | {639EF517-FCFC-408E-9500-71F0DC0458DB}.Release|x86.ActiveCfg = Release|Win32 23 | {639EF517-FCFC-408E-9500-71F0DC0458DB}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /MyPinTool.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {b8dd2600-7302-4aa7-a99d-1607cd3cd4fb} 14 | txt;doc;html 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Documents 25 | 26 | 27 | -------------------------------------------------------------------------------- /makefile: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | # 3 | # DO NOT EDIT THIS FILE! 4 | # 5 | ############################################################## 6 | 7 | # If the tool is built out of the kit, PIN_ROOT must be specified in the make invocation and point to the kit root. 8 | ifdef PIN_ROOT 9 | CONFIG_ROOT := $(PIN_ROOT)/source/tools/Config 10 | else 11 | CONFIG_ROOT := ../Config 12 | endif 13 | include $(CONFIG_ROOT)/makefile.config 14 | include makefile.rules 15 | include $(TOOLS_ROOT)/Config/makefile.default.rules 16 | 17 | ############################################################## 18 | # 19 | # DO NOT EDIT THIS FILE! 20 | # 21 | ############################################################## 22 | -------------------------------------------------------------------------------- /makefile.rules: -------------------------------------------------------------------------------- 1 | ############################################################## 2 | # 3 | # This file includes all the test targets as well as all the 4 | # non-default build rules and test recipes. 5 | # 6 | ############################################################## 7 | 8 | 9 | ############################################################## 10 | # 11 | # Test targets 12 | # 13 | ############################################################## 14 | 15 | ###### Place all generic definitions here ###### 16 | 17 | # This defines tests which run tools of the same name. This is simply for convenience to avoid 18 | # defining the test name twice (once in TOOL_ROOTS and again in TEST_ROOTS). 19 | # Tests defined here should not be defined in TOOL_ROOTS and TEST_ROOTS. 20 | TEST_TOOL_ROOTS := MyPinTool 21 | 22 | # This defines the tests to be run that were not already defined in TEST_TOOL_ROOTS. 23 | TEST_ROOTS := 24 | 25 | # This defines the tools which will be run during the the tests, and were not already defined in 26 | # TEST_TOOL_ROOTS. 27 | TOOL_ROOTS := 28 | 29 | # This defines the static analysis tools which will be run during the the tests. They should not 30 | # be defined in TEST_TOOL_ROOTS. If a test with the same name exists, it should be defined in 31 | # TEST_ROOTS. 32 | # Note: Static analysis tools are in fact executables linked with the Pin Static Analysis Library. 33 | # This library provides a subset of the Pin APIs which allows the tool to perform static analysis 34 | # of an application or dll. Pin itself is not used when this tool runs. 35 | SA_TOOL_ROOTS := 36 | 37 | # This defines all the applications that will be run during the tests. 38 | APP_ROOTS := 39 | 40 | # This defines any additional object files that need to be compiled. 41 | OBJECT_ROOTS := 42 | 43 | # This defines any additional dlls (shared objects), other than the pintools, that need to be compiled. 44 | DLL_ROOTS := 45 | 46 | # This defines any static libraries (archives), that need to be built. 47 | LIB_ROOTS := 48 | 49 | ###### Define the sanity subset ###### 50 | 51 | # This defines the list of tests that should run in sanity. It should include all the tests listed in 52 | # TEST_TOOL_ROOTS and TEST_ROOTS excluding only unstable tests. 53 | SANITY_SUBSET := $(TEST_TOOL_ROOTS) $(TEST_ROOTS) 54 | 55 | 56 | ############################################################## 57 | # 58 | # Test recipes 59 | # 60 | ############################################################## 61 | 62 | # This section contains recipes for tests other than the default. 63 | # See makefile.default.rules for the default test rules. 64 | # All tests in this section should adhere to the naming convention: .test 65 | 66 | 67 | ############################################################## 68 | # 69 | # Build rules 70 | # 71 | ############################################################## 72 | 73 | # This section contains the build rules for all binaries that have special build rules. 74 | # See makefile.default.rules for the default build rules. 75 | -------------------------------------------------------------------------------- /py/config.py: -------------------------------------------------------------------------------- 1 | EXE_PATH = r"C:\Users\Moon\Desktop\VMP\vmp3.09\test.vmp.exe" 2 | # EXE_PATH = "C:\\Users\\Moon\\Desktop\\vmp1.81\\test.vmp_2.13.8_pro.exe" 3 | # EXE_PATH = "C:\\Users\\Moon\\Desktop\\vmp1.81\\test.vmp_1.81_demo.exe" 4 | # EXE_PATH = "D:\\papers\\test_asm\\test_pin\\base64_vmp\\base64.vmp_2.13.8.exe" 5 | # EXE_PATH = "D:\\papers\\pin\\pin-3.2-81205-msvc-windows\source\\tools\\MyPinTool\\py\\work\\bin_op.vmp_2.exe" 6 | START_ADDR = 0x401000 7 | END_ADDR = 0x040101A #0x0401169 #0x40127C 8 | VM = 'vmp3' # vmp/cv/vmp3 9 | 10 | # File Path 11 | PIN_PATH = 'D:\\papers\\pin\\pin-3.2-81205-msvc-windows\\pin.exe' 12 | PIN_TOOL_PATH = 'D:\\papers\\pin\\pin-3.2-81205-msvc-windows\\source\\tools\\MyPinTool\\obj-ia32\\MyPinTool.dll' 13 | PIN_CMD = '%s -t %s -- %s' % (PIN_PATH, PIN_TOOL_PATH, EXE_PATH) 14 | 15 | 16 | BASE_PATH = 'D:\\papers\\pin\\pin-3.2-81205-msvc-windows\\source\\tools\\MyPinTool\\py\\' 17 | WORK_PATH = BASE_PATH + 'work\\' 18 | 19 | INS_PATH = WORK_PATH + 'bin.ins' 20 | TRACE_PATH = WORK_PATH + 'bin.trace' 21 | 22 | REPORT_PATH = BASE_PATH + "report\\index.html" 23 | BROWSER_PATH = '"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"' 24 | IMAGE_FOLDER = BASE_PATH + 'report\\image\\' 25 | 26 | # Report 27 | MAX_ROW = 300 28 | 29 | -------------------------------------------------------------------------------- /py/handler.py: -------------------------------------------------------------------------------- 1 | 2 | import config 3 | 4 | from symexec import SymExecObject 5 | 6 | class Handler(SymExecObject): 7 | 8 | DEFAULT_NAME = 'Handler' 9 | 10 | def __init__(self): 11 | self.blocks = [] 12 | self.head = None 13 | self.tail = None 14 | 15 | self.copy = [] # same handler 16 | 17 | self._name = None 18 | 19 | @property 20 | def name(self): 21 | if self._name: 22 | return self._name 23 | else: 24 | return 'Handler_%x' % self.addr 25 | 26 | def __repr__(self): 27 | return '<%s>' % self.name 28 | 29 | def add_block(self, block): 30 | if not self.head: 31 | self.head = block 32 | 33 | if self.tail: 34 | if block.addr not in self.tail.nexts: 35 | return False 36 | 37 | self.blocks.append(block) 38 | self.tail = block 39 | 40 | return True 41 | 42 | def add_copy(self, handler): 43 | self.copy.append(handler) 44 | 45 | 46 | @property 47 | def is_valid(self): 48 | return self.head is not None 49 | 50 | @property 51 | def addr(self): 52 | return self.head.addr 53 | 54 | 55 | @property 56 | def bytes(self): 57 | return ''.join(b.bytes for b in self.blocks) 58 | 59 | @property 60 | def instructions(self): 61 | ins = [] 62 | for b in self.blocks: 63 | ins += b.instructions 64 | return ins 65 | 66 | @property 67 | def ins_str(self): 68 | return '\n'.join(b.ins_str for b in self.blocks) 69 | 70 | 71 | def __str__(self): 72 | buf = self.name 73 | buf += '(%#x) %d blocks' % (self.addr, len(self.blocks)) 74 | for b in self.blocks: 75 | buf += '\n\t' + repr(b) 76 | 77 | if len(self.copy) > 0: 78 | buf += '\n[COPY] '+ '\n'.join(str(i) for i in self.copy) 79 | 80 | return buf 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /py/instruction.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Instruction(object): 4 | 5 | def __init__(self, addr, disasm, bytes): 6 | self.addr = addr 7 | self.disasm = disasm 8 | self.bytes = bytes 9 | self.traces = [] 10 | 11 | def __str__(self): 12 | # return '%#x\t%s\t%s' % (self.addr, 13 | # self.bytes.encode('hex').upper(), 14 | # self.disasm) 15 | return '%#x\t%s' % (self.addr, self.disasm) 16 | 17 | def __repr__(self): 18 | return '' % (self.addr, self.disasm) 19 | 20 | @property 21 | def size(self): 22 | return len(self.bytes) 23 | 24 | def add_trace(self, trace): 25 | self.traces.append(trace) 26 | 27 | def print_trace(self, i=0): 28 | if len(self.traces) == 0: 29 | print '[!] No Trace at %s' % self 30 | if i >= len(self.traces): 31 | print self.traces[-1] 32 | else: 33 | print self.traces[i] 34 | 35 | def parse_file(filepath): 36 | for line in open(filepath, 'rb').read().splitlines(): 37 | addr, diasm, hexbytes = line.split('\t') 38 | yield Instruction(int(addr, 16), diasm, hexbytes.decode('hex')) 39 | 40 | 41 | if __name__ == '__main__': 42 | for ins in parse_file('../bin.ins'): 43 | print ins -------------------------------------------------------------------------------- /py/main.py: -------------------------------------------------------------------------------- 1 | 2 | import bbl_manager 3 | import config 4 | import report 5 | 6 | import os 7 | 8 | def main(): 9 | # Change work folder. 10 | os.chdir(config.WORK_PATH) 11 | 12 | print '[*] Target: %s' % config.EXE_PATH 13 | print '----- STEP 1 -----' 14 | print '[*] Running PinTool ...' 15 | print '#'*80 16 | 17 | os.system(config.PIN_CMD) 18 | 19 | print '#'*80 20 | 21 | print '[*] Pin instrument finished.' 22 | 23 | global bm 24 | bm = bbl_manager.BBLManager() 25 | 26 | 27 | print '----- STEP 2 -----' 28 | # Load instructions. 29 | bm.load_ins_info(config.INS_PATH) 30 | 31 | print '----- STEP 3 -----' 32 | # Load trace. 33 | bm.load_trace(config.TRACE_PATH, config.START_ADDR, config.END_ADDR) 34 | 35 | print '----- STEP 4 -----' 36 | # Generate execution graph. 37 | bm.consolidate_blocks() 38 | 39 | print '----- STEP 5 -----' 40 | bm.detect_handlers() 41 | 42 | print '----- STEP 6 -----' 43 | print '[*] Generating report ....' 44 | report.gen_report(bm) 45 | print '[*] Report generated.' 46 | 47 | # report.open_report() 48 | 49 | 50 | if __name__ == '__main__': 51 | # try: 52 | main() 53 | # except Exception, e: 54 | # print '[!] Fatal Error %s' % e 55 | 56 | # global bm 57 | # bm = bbl_manager.BBLManager() 58 | # bm.load_ins_info(r'D:\papers\pin\pin-3.2-81205-msvc-windows\source\tools\MyPinTool\bin.ins') 59 | # bm.load_trace(r'D:\papers\pin\pin-3.2-81205-msvc-windows\source\tools\MyPinTool\bin.trace', 60 | # # start_addr=0x401000, end_addr=0x40127C) # allop 61 | # start_addr=0x401000, end_addr=0x0040101A ) # base64 62 | # # bm.load_trace('../bin.block') 63 | # bm.consolidate_blocks() 64 | # # cPickle.dump(bm, open('test.dump','wb')) 65 | # bm.display_bbl_graph() 66 | # # bm.display_bbl_graph_ida() 67 | 68 | # bm.detect_handlers() 69 | # bm.dump_handlers() 70 | 71 | 72 | # report.gen_report(bm) 73 | # report.open_report() -------------------------------------------------------------------------------- /py/program.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | import instructions 5 | import trace 6 | import runtimeblock 7 | 8 | class Program(object): 9 | """docstring for Program""" 10 | def __init__(self, arg): 11 | 12 | self.instructions = {} # addr, instructions 13 | self.runtimeblocks = {} 14 | 15 | 16 | 17 | def load_instructions(self, filepath): 18 | for ins in instructions.parsefile(filepath): 19 | self.instructions[ins.addr] = ins 20 | 21 | def load_trace(self, filepath): 22 | current_block = RuntimeBlock() 23 | coverred_addr = set() 24 | 25 | for t in trace.parsefile(filepath): 26 | if t.addr not in self.instructions: 27 | raise Exception("Unknown address at %#x" % t.addr) 28 | inst = self.instructions[addr] 29 | if t.addr not in coverred_addr: 30 | current_block. 31 | 32 | 33 | -------------------------------------------------------------------------------- /py/pyh.py: -------------------------------------------------------------------------------- 1 | # @file: pyh.py 2 | # @purpose: a HTML tag generator 3 | # @author: Emmanuel Turlay 4 | 5 | __doc__ = """The pyh.py module is the core of the PyH package. PyH lets you 6 | generate HTML tags from within your python code. 7 | See http://code.google.com/p/pyh/ for documentation. 8 | """ 9 | __author__ = "Emmanuel Turlay " 10 | __version__ = '$Revision: 63 $' 11 | __date__ = '$Date: 2010-05-21 03:09:03 +0200 (Fri, 21 May 2010) $' 12 | 13 | from sys import _getframe, stdout, modules, version 14 | nOpen={} 15 | 16 | nl = '\n' 17 | doctype = '\n' 18 | charset = '\n' 19 | 20 | tags = ['html', 'body', 'head', 'link', 'meta', 'div', 'p', 'form', 'legend', 21 | 'input', 'select', 'span', 'b', 'i', 'option', 'img', 'script', 22 | 'table', 'tr', 'td', 'th', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 23 | 'fieldset', 'a', 'title', 'body', 'head', 'title', 'script', 'br', 'table', 24 | 'ul', 'li', 'ol'] 25 | 26 | # by Moon 2015/04/17 27 | tags += ["thead","tbody"] 28 | 29 | selfClose = ['input', 'img', 'link', 'br'] 30 | 31 | class Tag(list): 32 | tagname = '' 33 | 34 | def __init__(self, *arg, **kw): 35 | self.attributes = kw 36 | if self.tagname : 37 | name = self.tagname 38 | self.isSeq = False 39 | else: 40 | name = 'sequence' 41 | self.isSeq = True 42 | self.id = kw.get('id', name) 43 | #self.extend(arg) 44 | for a in arg: self.addObj(a) 45 | 46 | def __iadd__(self, obj): 47 | if isinstance(obj, Tag) and obj.isSeq: 48 | for o in obj: self.addObj(o) 49 | else: self.addObj(obj) 50 | return self 51 | 52 | def addObj(self, obj): 53 | if not isinstance(obj, Tag): obj = str(obj) 54 | id=self.setID(obj) 55 | setattr(self, id, obj) 56 | self.append(obj) 57 | 58 | def setID(self, obj): 59 | if isinstance(obj, Tag): 60 | id = obj.id 61 | n = len([t for t in self if isinstance(t, Tag) and t.id.startswith(id)]) 62 | else: 63 | id = 'content' 64 | n = len([t for t in self if not isinstance(t, Tag)]) 65 | if n: id = '%s_%03i' % (id, n) 66 | if isinstance(obj, Tag): obj.id = id 67 | return id 68 | 69 | def __add__(self, obj): 70 | if self.tagname: return Tag(self, obj) 71 | self.addObj(obj) 72 | return self 73 | 74 | def __lshift__(self, obj): 75 | self += obj 76 | if isinstance(obj, Tag): return obj 77 | 78 | def render(self): 79 | result = '' 80 | if self.tagname: 81 | result = '<%s%s%s>' % (self.tagname, self.renderAtt(), self.selfClose()*' /') 82 | if not self.selfClose(): 83 | for c in self: 84 | if isinstance(c, Tag): 85 | result += c.render() 86 | else: result += c 87 | if self.tagname: 88 | result += '' % self.tagname 89 | result += '\n' 90 | return result 91 | 92 | def renderAtt(self): 93 | result = '' 94 | for n, v in self.attributes.iteritems(): 95 | if n != 'txt' and n != 'open': 96 | if n == 'cl': n = 'class' 97 | result += ' %s="%s"' % (n, v) 98 | return result 99 | 100 | def selfClose(self): 101 | return self.tagname in selfClose 102 | 103 | def TagFactory(name): 104 | class f(Tag): 105 | tagname = name 106 | f.__name__ = name 107 | return f 108 | 109 | thisModule = modules[__name__] 110 | 111 | for t in tags: setattr(thisModule, t, TagFactory(t)) 112 | 113 | def ValidW3C(): 114 | out = a(img(src='http://www.w3.org/Icons/valid-xhtml10', alt='Valid XHTML 1.0 Strict'), href='http://validator.w3.org/check?uri=referer') 115 | return out 116 | 117 | class PyH(Tag): 118 | tagname = 'html' 119 | 120 | def __init__(self, name='MyPyHPage'): 121 | self += head() 122 | self += body() 123 | self.attributes = dict(xmlns='http://www.w3.org/1999/xhtml', lang='en') 124 | self.head += title(name) 125 | 126 | def __iadd__(self, obj): 127 | if isinstance(obj, head) or isinstance(obj, body): self.addObj(obj) 128 | elif isinstance(obj, meta) or isinstance(obj, link): self.head += obj 129 | else: 130 | self.body += obj 131 | id=self.setID(obj) 132 | setattr(self, id, obj) 133 | return self 134 | 135 | def addJS(self, *arg): 136 | for f in arg: self.head += script(type='text/javascript', src=f) 137 | 138 | def addCSS(self, *arg): 139 | for f in arg: self.head += link(rel='stylesheet', type='text/css', href=f) 140 | 141 | def printOut(self,file=''): 142 | if file: f = open(file, 'w') 143 | else: f = stdout 144 | f.write(doctype) 145 | f.write(self.render()) 146 | f.flush() 147 | if file: f.close() 148 | 149 | -------------------------------------------------------------------------------- /py/report/css/common.css: -------------------------------------------------------------------------------- 1 | /* 2 | *{ 3 | font-family: Consolas, "微软雅黑", "Liberation Mono", Menlo, Courier, monospace !important; 4 | } 5 | */ 6 | *{ 7 | font-family: Consolas, "微软雅黑", "Liberation Mono", Menlo, Courier, monospace ; 8 | } 9 | 10 | #report .ui.left.sidebar { 11 | overflow: visible; 12 | width: 350px; 13 | } 14 | 15 | #report .ui.styled.accordion{ 16 | width: 100%; 17 | } 18 | 19 | #report .ui.page { 20 | margin-left: 10%; 21 | margin-right: 10%; 22 | margin-top: 80px; 23 | padding: auto; 24 | } 25 | 26 | .ui.toggle.checkbox label { 27 | color: white; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /py/report/js/common.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function function_name (argument) { 2 | 3 | $('.ui.dropdown') 4 | .dropdown({ 5 | on: 'hover' 6 | }) 7 | ; 8 | 9 | // For side bar button. 10 | $('.ui.sidebar') 11 | .sidebar('attach events', '.launch.button') 12 | ; 13 | 14 | $('.ui.accordion') 15 | .accordion() 16 | ; 17 | $('.ui.checkbox') 18 | .checkbox(); 19 | 20 | // Check all checkbox. 21 | //$('.ui.checkbox').click() 22 | // toggle all back. 23 | var arr = $('.ui.checkbox') 24 | for(var i= 0; i.dropdown.icon{float:right;margin:.165em 0 0 1em;-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.ui.accordion .ui.header .dropdown.icon{font-size:1em;margin:0 .25rem 0 0}.ui.accordion .accordion .active.title .dropdown.icon,.ui.accordion .active.title .dropdown.icon,.ui.accordion.menu .item .active.title>.dropdown.icon{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.ui.styled.accordion{width:600px}.ui.styled.accordion,.ui.styled.accordion .accordion{border-radius:.2857rem;background:#fff;box-shadow:0 1px 2px 0 rgba(0,0,0,.05),0 0 0 1px rgba(39,41,43,.15)}.ui.styled.accordion .accordion .title,.ui.styled.accordion .title{margin:0;padding:.75em 1em;color:rgba(0,0,0,.4);font-weight:700;border-top:1px solid rgba(39,41,43,.15);-webkit-transition:background .2s ease,color .2s ease;transition:background .2s ease,color .2s ease}.ui.styled.accordion .accordion .title:first-child,.ui.styled.accordion>.title:first-child{border-top:none}.ui.styled.accordion .accordion .content,.ui.styled.accordion .content{margin:0;padding:.5em 1em 1.5em}.ui.styled.accordion .accordion .content{padding:.5em 1em 1.5em}.ui.styled.accordion .accordion .active.title,.ui.styled.accordion .accordion .title:hover,.ui.styled.accordion .active.title,.ui.styled.accordion .title:hover{background:0 0;color:rgba(0,0,0,.8)}.ui.accordion .accordion .active.content,.ui.accordion .active.content{display:block}.ui.fluid.accordion,.ui.fluid.accordion .accordion{width:100%}.ui.inverted.accordion .title:not(.ui){color:#fff}@font-face{font-family:Accordion;src:url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMggjB5AAAAC8AAAAYGNtYXAPfOIKAAABHAAAAExnYXNwAAAAEAAAAWgAAAAIZ2x5Zryj6HgAAAFwAAAAyGhlYWT/0IhHAAACOAAAADZoaGVhApkB5wAAAnAAAAAkaG10eAJuABIAAAKUAAAAGGxvY2EAjABWAAACrAAAAA5tYXhwAAgAFgAAArwAAAAgbmFtZfC1n04AAALcAAABPHBvc3QAAwAAAAAEGAAAACAAAwIAAZAABQAAAUwBZgAAAEcBTAFmAAAA9QAZAIQAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADw2gHg/+D/4AHgACAAAAABAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEADgAAAAKAAgAAgACAAEAIPDa//3//wAAAAAAIPDZ//3//wAB/+MPKwADAAEAAAAAAAAAAAAAAAEAAf//AA8AAQAAAAAAAAAAAAIAADc5AQAAAAABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQASAEkAtwFuABMAADc0PwE2FzYXFh0BFAcGJwYvASY1EgaABQgHBQYGBQcIBYAG2wcGfwcBAQcECf8IBAcBAQd/BgYAAAAAAQAAAEkApQFuABMAADcRNDc2MzIfARYVFA8BBiMiJyY1AAUGBwgFgAYGgAUIBwYFWwEACAUGBoAFCAcFgAYGBQcAAAABAAAAAQAAqWYls18PPPUACwIAAAAAAM/9o+4AAAAAz/2j7gAAAAAAtwFuAAAACAACAAAAAAAAAAEAAAHg/+AAAAIAAAAAAAC3AAEAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAQAAAAC3ABIAtwAAAAAAAAAKABQAHgBCAGQAAAABAAAABgAUAAEAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADAAAAAEAAAAAAAIADgBAAAEAAAAAAAMADAAiAAEAAAAAAAQADABOAAEAAAAAAAUAFgAMAAEAAAAAAAYABgAuAAEAAAAAAAoANABaAAMAAQQJAAEADAAAAAMAAQQJAAIADgBAAAMAAQQJAAMADAAiAAMAAQQJAAQADABOAAMAAQQJAAUAFgAMAAMAAQQJAAYADAA0AAMAAQQJAAoANABaAHIAYQB0AGkAbgBnAFYAZQByAHMAaQBvAG4AIAAxAC4AMAByAGEAdABpAG4AZ3JhdGluZwByAGEAdABpAG4AZwBSAGUAZwB1AGwAYQByAHIAYQB0AGkAbgBnAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)format('truetype'),url(data:application/font-woff;charset=utf-8;base64,d09GRk9UVE8AAASwAAoAAAAABGgAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAAA9AAAAS0AAAEtFpovuE9TLzIAAAIkAAAAYAAAAGAIIweQY21hcAAAAoQAAABMAAAATA984gpnYXNwAAAC0AAAAAgAAAAIAAAAEGhlYWQAAALYAAAANgAAADb/0IhHaGhlYQAAAxAAAAAkAAAAJAKZAedobXR4AAADNAAAABgAAAAYAm4AEm1heHAAAANMAAAABgAAAAYABlAAbmFtZQAAA1QAAAE8AAABPPC1n05wb3N0AAAEkAAAACAAAAAgAAMAAAEABAQAAQEBB3JhdGluZwABAgABADr4HAL4GwP4GAQeCgAZU/+Lix4KABlT/4uLDAeLa/iU+HQFHQAAAHkPHQAAAH4RHQAAAAkdAAABJBIABwEBBw0PERQZHnJhdGluZ3JhdGluZ3UwdTF1MjB1RjBEOXVGMERBAAACAYkABAAGAQEEBwoNVp38lA78lA78lA77lA773Z33bxWLkI2Qj44I9xT3FAWOj5CNkIuQi4+JjoePiI2Gi4YIi/uUBYuGiYeHiIiHh4mGi4aLho2Ijwj7FPcUBYeOiY+LkAgO+92L5hWL95QFi5CNkI6Oj4+PjZCLkIuQiY6HCPcU+xQFj4iNhouGi4aJh4eICPsU+xQFiIeGiYaLhouHjYePiI6Jj4uQCA74lBT4lBWLDAoAAAAAAwIAAZAABQAAAUwBZgAAAEcBTAFmAAAA9QAZAIQAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADw2gHg/+D/4AHgACAAAAABAAAAAAAAAAAAAAAgAAAAAAACAAAAAwAAABQAAwABAAAAFAAEADgAAAAKAAgAAgACAAEAIPDa//3//wAAAAAAIPDZ//3//wAB/+MPKwADAAEAAAAAAAAAAAAAAAEAAf//AA8AAQAAAAEAADfYOJZfDzz1AAsCAAAAAADP/aPuAAAAAM/9o+4AAAAAALcBbgAAAAgAAgAAAAAAAAABAAAB4P/gAAACAAAAAAAAtwABAAAAAAAAAAAAAAAAAAAABgAAAAAAAAAAAAAAAAEAAAAAtwASALcAAAAAUAAABgAAAAAADgCuAAEAAAAAAAEADAAAAAEAAAAAAAIADgBAAAEAAAAAAAMADAAiAAEAAAAAAAQADABOAAEAAAAAAAUAFgAMAAEAAAAAAAYABgAuAAEAAAAAAAoANABaAAMAAQQJAAEADAAAAAMAAQQJAAIADgBAAAMAAQQJAAMADAAiAAMAAQQJAAQADABOAAMAAQQJAAUAFgAMAAMAAQQJAAYADAA0AAMAAQQJAAoANABaAHIAYQB0AGkAbgBnAFYAZQByAHMAaQBvAG4AIAAxAC4AMAByAGEAdABpAG4AZ3JhdGluZwByAGEAdABpAG4AZwBSAGUAZwB1AGwAYQByAHIAYQB0AGkAbgBnAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA)format('woff');font-weight:400;font-style:normal}.ui.accordion .accordion .title .dropdown.icon,.ui.accordion .title .dropdown.icon{font-family:Accordion;line-height:1;-webkit-backface-visibility:hidden;backface-visibility:hidden;font-weight:400;font-style:normal;text-align:center}.ui.accordion .accordion .title .dropdown.icon:before,.ui.accordion .title .dropdown.icon:before{content:'\f0da'} -------------------------------------------------------------------------------- /py/report/semantic/components/accordion.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * # Semantic UI 1.11.6 - Accordion 3 | * http://github.com/semantic-org/semantic-ui/ 4 | * 5 | * 6 | * Copyright 2014 Contributors 7 | * Released under the MIT license 8 | * http://opensource.org/licenses/MIT 9 | * 10 | */ 11 | !function(e,n,t,i){"use strict";e.fn.accordion=function(t){{var o,a=e(this),s=(new Date).getTime(),r=[],c=arguments[0],l="string"==typeof c,u=[].slice.call(arguments,1);n.requestAnimationFrame||n.mozRequestAnimationFrame||n.webkitRequestAnimationFrame||n.msRequestAnimationFrame||function(e){setTimeout(e,0)}}return a.each(function(){var d,m,g=e.isPlainObject(t)?e.extend(!0,{},e.fn.accordion.settings,t):e.extend({},e.fn.accordion.settings),f=g.className,p=g.namespace,v=g.selector,h=g.error,b="."+p,y="module-"+p,C=a.selector||"",O=e(this),x=O.find(v.title),F=O.find(v.content),T=this,q=O.data(y);m={initialize:function(){m.debug("Initializing",O),m.bind.events(),m.observeChanges(),m.instantiate()},instantiate:function(){q=m,O.data(y,m)},destroy:function(){m.debug("Destroying previous instance",O),O.off(b).removeData(y)},refresh:function(){x=O.find(v.title),F=O.find(v.content)},observeChanges:function(){"MutationObserver"in n&&(d=new MutationObserver(function(){m.debug("DOM tree modified, updating selector cache"),m.refresh()}),d.observe(T,{childList:!0,subtree:!0}),m.debug("Setting up mutation observer",d))},bind:{events:function(){m.debug("Binding delegated events"),O.on("click"+b,v.trigger,m.event.click)}},event:{click:function(){m.toggle.call(this)}},toggle:function(n){var t=n!==i?"number"==typeof n?x.eq(n):e(n).closest(v.title):e(this).closest(v.title),o=t.next(F),a=o.hasClass(f.animating),s=o.hasClass(f.active),r=s&&!a,c=!s&&a;m.debug("Toggling visibility of content",t),r||c?g.collapsible?m.close.call(t):m.debug("Cannot close accordion content collapsing is disabled"):m.open.call(t)},open:function(n){var t=n!==i?"number"==typeof n?x.eq(n):e(n).closest(v.title):e(this).closest(v.title),o=t.next(F),a=o.hasClass(f.animating),s=o.hasClass(f.active),r=!s&&!a;r&&(m.debug("Opening accordion content",t),g.exclusive&&m.closeOthers.call(t),t.addClass(f.active),o.addClass(f.animating),g.animateChildren&&(e.fn.transition!==i&&O.transition("is supported")?o.children().transition({animation:"fade in",queue:!1,useFailSafe:!0,debug:g.debug,verbose:g.verbose,duration:g.duration}):o.children().stop(!0).animate({opacity:1},g.duration,m.resetOpacity)),o.stop(!0).slideDown(g.duration,g.easing,function(){o.removeClass(f.animating).addClass(f.active),m.reset.display.call(this),g.onOpen.call(this),g.onChange.call(this)}))},close:function(n){var t=n!==i?"number"==typeof n?x.eq(n):e(n).closest(v.title):e(this).closest(v.title),o=t.next(F),a=o.hasClass(f.animating),s=o.hasClass(f.active),r=!s&&a,c=s&&a;!s&&!r||c||(m.debug("Closing accordion content",o),t.removeClass(f.active),o.addClass(f.animating),g.animateChildren&&(e.fn.transition!==i&&O.transition("is supported")?o.children().transition({animation:"fade out",queue:!1,useFailSafe:!0,debug:g.debug,verbose:g.verbose,duration:g.duration}):o.children().stop(!0).animate({opacity:0},g.duration,m.resetOpacity)),o.stop(!0).slideUp(g.duration,g.easing,function(){o.removeClass(f.animating).removeClass(f.active),m.reset.display.call(this),g.onClose.call(this),g.onChange.call(this)}))},closeOthers:function(n){var t,o,a,s=n!==i?x.eq(n):e(this).closest(v.title),r=s.parents(v.content).prev(v.title),c=s.closest(v.accordion),l=v.title+"."+f.active+":visible",u=v.content+"."+f.active+":visible";g.closeNested?(t=c.find(l).not(r),a=t.next(F)):(t=c.find(l).not(r),o=c.find(u).find(l).not(r),t=t.not(o),a=t.next(F)),t.length>0&&(m.debug("Exclusive enabled, closing other content",t),t.removeClass(f.active),g.animateChildren&&(e.fn.transition!==i&&O.transition("is supported")?a.children().transition({animation:"fade out",useFailSafe:!0,debug:g.debug,verbose:g.verbose,duration:g.duration}):a.children().stop().animate({opacity:0},g.duration,m.resetOpacity)),a.stop().slideUp(g.duration,g.easing,function(){e(this).removeClass(f.active),m.reset.display.call(this)}))},reset:{display:function(){m.verbose("Removing inline display from element",this),e(this).css("display",""),""===e(this).attr("style")&&e(this).attr("style","").removeAttr("style")},opacity:function(){m.verbose("Removing inline opacity from element",this),e(this).css("opacity",""),""===e(this).attr("style")&&e(this).attr("style","").removeAttr("style")}},setting:function(n,t){if(m.debug("Changing setting",n,t),e.isPlainObject(n))e.extend(!0,g,n);else{if(t===i)return g[n];g[n]=t}},internal:function(n,t){return m.debug("Changing internal",n,t),t===i?m[n]:void(e.isPlainObject(n)?e.extend(!0,m,n):m[n]=t)},debug:function(){g.debug&&(g.performance?m.performance.log(arguments):(m.debug=Function.prototype.bind.call(console.info,console,g.name+":"),m.debug.apply(console,arguments)))},verbose:function(){g.verbose&&g.debug&&(g.performance?m.performance.log(arguments):(m.verbose=Function.prototype.bind.call(console.info,console,g.name+":"),m.verbose.apply(console,arguments)))},error:function(){m.error=Function.prototype.bind.call(console.error,console,g.name+":"),m.error.apply(console,arguments)},performance:{log:function(e){var n,t,i;g.performance&&(n=(new Date).getTime(),i=s||n,t=n-i,s=n,r.push({Name:e[0],Arguments:[].slice.call(e,1)||"",Element:T,"Execution Time":t})),clearTimeout(m.performance.timer),m.performance.timer=setTimeout(m.performance.display,100)},display:function(){var n=g.name+":",t=0;s=!1,clearTimeout(m.performance.timer),e.each(r,function(e,n){t+=n["Execution Time"]}),n+=" "+t+"ms",C&&(n+=" '"+C+"'"),(console.group!==i||console.table!==i)&&r.length>0&&(console.groupCollapsed(n),console.table?console.table(r):e.each(r,function(e,n){console.log(n.Name+": "+n["Execution Time"]+"ms")}),console.groupEnd()),r=[]}},invoke:function(n,t,a){var s,r,c,l=q;return t=t||u,a=T||a,"string"==typeof n&&l!==i&&(n=n.split(/[\. ]/),s=n.length-1,e.each(n,function(t,o){var a=t!=s?o+n[t+1].charAt(0).toUpperCase()+n[t+1].slice(1):n;if(e.isPlainObject(l[a])&&t!=s)l=l[a];else{if(l[a]!==i)return r=l[a],!1;if(!e.isPlainObject(l[o])||t==s)return l[o]!==i?(r=l[o],!1):(m.error(h.method,n),!1);l=l[o]}})),e.isFunction(r)?c=r.apply(a,t):r!==i&&(c=r),e.isArray(o)?o.push(c):o!==i?o=[o,c]:c!==i&&(o=c),r}},l?(q===i&&m.initialize(),m.invoke(c)):(q!==i&&q.invoke("destroy"),m.initialize())}),o!==i?o:this},e.fn.accordion.settings={name:"Accordion",namespace:"accordion",debug:!1,verbose:!0,performance:!0,exclusive:!0,collapsible:!0,closeNested:!1,animateChildren:!0,duration:350,easing:"easeOutQuad",onOpen:function(){},onClose:function(){},onChange:function(){},error:{method:"The method you called is not defined"},className:{active:"active",animating:"animating"},selector:{accordion:".accordion",title:".title",trigger:".title",content:".content"}},e.extend(e.easing,{easeOutQuad:function(e,n,t,i,o){return-i*(n/=o)*(n-2)+t}})}(jQuery,window,document); -------------------------------------------------------------------------------- /py/report/semantic/components/ad.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * # Semantic UI 1.11.6 - Ad 3 | * http://github.com/semantic-org/semantic-ui/ 4 | * 5 | * 6 | * Copyright 2013 Contributors 7 | * Released under the MIT license 8 | * http://opensource.org/licenses/MIT 9 | * 10 | */ 11 | 12 | 13 | /******************************* 14 | Advertisement 15 | *******************************/ 16 | 17 | .ui.ad { 18 | display: block; 19 | overflow: hidden; 20 | margin: 1em 0em; 21 | } 22 | .ui.ad:first-child { 23 | margin: 0em; 24 | } 25 | .ui.ad:last-child { 26 | margin: 0em; 27 | } 28 | .ui.ad iframe { 29 | margin: 0em; 30 | padding: 0em; 31 | border: none; 32 | overflow: hidden; 33 | } 34 | 35 | /*-------------- 36 | Common 37 | ---------------*/ 38 | 39 | 40 | /* Leaderboard */ 41 | .ui.leaderboard.ad { 42 | width: 728px; 43 | height: 90px; 44 | } 45 | 46 | /* Medium Rectangle */ 47 | .ui[class*="medium rectangle"].ad { 48 | width: 300px; 49 | height: 250px; 50 | } 51 | 52 | /* Large Rectangle */ 53 | .ui[class*="large rectangle"].ad { 54 | width: 336px; 55 | height: 280px; 56 | } 57 | 58 | /* Half Page */ 59 | .ui[class*="half page"].ad { 60 | width: 300px; 61 | height: 600px; 62 | } 63 | 64 | /*-------------- 65 | Square 66 | ---------------*/ 67 | 68 | 69 | /* Square */ 70 | .ui.square.ad { 71 | width: 250px; 72 | height: 250px; 73 | } 74 | 75 | /* Small Square */ 76 | .ui[class*="small square"].ad { 77 | width: 200px; 78 | height: 200px; 79 | } 80 | 81 | /*-------------- 82 | Rectangle 83 | ---------------*/ 84 | 85 | 86 | /* Small Rectangle */ 87 | .ui[class*="small rectangle"].ad { 88 | width: 180px; 89 | height: 150px; 90 | } 91 | 92 | /* Vertical Rectangle */ 93 | .ui[class*="vertical rectangle"].ad { 94 | width: 240px; 95 | height: 400px; 96 | } 97 | 98 | /*-------------- 99 | Button 100 | ---------------*/ 101 | 102 | .ui.button.ad { 103 | width: 120px; 104 | height: 90px; 105 | } 106 | .ui[class*="square button"].ad { 107 | width: 125px; 108 | height: 125px; 109 | } 110 | .ui[class*="small button"].ad { 111 | width: 120px; 112 | height: 60px; 113 | } 114 | 115 | /*-------------- 116 | Skyscrapers 117 | ---------------*/ 118 | 119 | 120 | /* Skyscraper */ 121 | .ui.skyscraper.ad { 122 | width: 120px; 123 | height: 600px; 124 | } 125 | 126 | /* Wide Skyscraper */ 127 | .ui[class*="wide skyscraper"].ad { 128 | width: 160px; 129 | } 130 | 131 | /*-------------- 132 | Banners 133 | ---------------*/ 134 | 135 | 136 | /* Banner */ 137 | .ui.banner.ad { 138 | width: 468px; 139 | height: 60px; 140 | } 141 | 142 | /* Vertical Banner */ 143 | .ui[class*="vertical banner"].ad { 144 | width: 120px; 145 | height: 240px; 146 | } 147 | 148 | /* Top Banner */ 149 | .ui[class*="top banner"].ad { 150 | width: 930px; 151 | height: 180px; 152 | } 153 | 154 | /* Half Banner */ 155 | .ui[class*="half banner"].ad { 156 | width: 234px; 157 | height: 60px; 158 | } 159 | 160 | /*-------------- 161 | Boards 162 | ---------------*/ 163 | 164 | 165 | /* Leaderboard */ 166 | .ui[class*="large leaderboard"].ad { 167 | width: 970px; 168 | height: 90px; 169 | } 170 | 171 | /* Billboard */ 172 | .ui.billboard.ad { 173 | width: 970px; 174 | height: 250px; 175 | } 176 | 177 | /*-------------- 178 | Panorama 179 | ---------------*/ 180 | 181 | 182 | /* Panorama */ 183 | .ui.panorama.ad { 184 | width: 980px; 185 | height: 120px; 186 | } 187 | 188 | /*-------------- 189 | Netboard 190 | ---------------*/ 191 | 192 | 193 | /* Netboard */ 194 | .ui.netboard.ad { 195 | width: 580px; 196 | height: 400px; 197 | } 198 | 199 | /*-------------- 200 | Mobile 201 | ---------------*/ 202 | 203 | 204 | /* Large Mobile Banner */ 205 | .ui[class*="large mobile banner"].ad { 206 | width: 320px; 207 | height: 100px; 208 | } 209 | 210 | /* Mobile Leaderboard */ 211 | .ui[class*="mobile leaderboard"].ad { 212 | width: 320px; 213 | height: 50px; 214 | } 215 | 216 | 217 | /******************************* 218 | Types 219 | *******************************/ 220 | 221 | 222 | /* Mobile Sizes */ 223 | .ui.mobile.ad { 224 | display: none; 225 | } 226 | @media only screen and (max-width: 767px) { 227 | .ui.mobile.ad { 228 | display: block; 229 | } 230 | } 231 | 232 | 233 | /******************************* 234 | Variations 235 | *******************************/ 236 | 237 | .ui.centered.ad { 238 | margin-left: auto; 239 | margin-right: auto; 240 | } 241 | .ui.test.ad { 242 | position: relative; 243 | background: #333333; 244 | } 245 | .ui.test.ad:after { 246 | position: absolute; 247 | top: 50%; 248 | left: 50%; 249 | width: 100%; 250 | text-align: center; 251 | -webkit-transform: translateX(-50%) translateY(-50%); 252 | -ms-transform: translateX(-50%) translateY(-50%); 253 | transform: translateX(-50%) translateY(-50%); 254 | content: 'Ad'; 255 | color: #ffffff; 256 | font-size: 1em; 257 | font-weight: bold; 258 | } 259 | .ui.mobile.test.ad:after { 260 | font-size: 0.85714em; 261 | } 262 | .ui.test.ad[data-text]:after { 263 | content: attr(data-text); 264 | } 265 | 266 | 267 | /******************************* 268 | Theme Overrides 269 | *******************************/ 270 | 271 | 272 | 273 | /******************************* 274 | User Variable Overrides 275 | *******************************/ 276 | 277 | -------------------------------------------------------------------------------- /py/report/semantic/components/ad.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * # Semantic UI 1.11.6 - Ad 3 | * http://github.com/semantic-org/semantic-ui/ 4 | * 5 | * 6 | * Copyright 2013 Contributors 7 | * Released under the MIT license 8 | * http://opensource.org/licenses/MIT 9 | * 10 | */.ui.ad{display:block;overflow:hidden;margin:1em 0}.ui.ad:first-child,.ui.ad:last-child{margin:0}.ui.ad iframe{margin:0;padding:0;border:none;overflow:hidden}.ui.leaderboard.ad{width:728px;height:90px}.ui[class*="medium rectangle"].ad{width:300px;height:250px}.ui[class*="large rectangle"].ad{width:336px;height:280px}.ui[class*="half page"].ad{width:300px;height:600px}.ui.square.ad{width:250px;height:250px}.ui[class*="small square"].ad{width:200px;height:200px}.ui[class*="small rectangle"].ad{width:180px;height:150px}.ui[class*="vertical rectangle"].ad{width:240px;height:400px}.ui.button.ad{width:120px;height:90px}.ui[class*="square button"].ad{width:125px;height:125px}.ui[class*="small button"].ad{width:120px;height:60px}.ui.skyscraper.ad{width:120px;height:600px}.ui[class*="wide skyscraper"].ad{width:160px}.ui.banner.ad{width:468px;height:60px}.ui[class*="vertical banner"].ad{width:120px;height:240px}.ui[class*="top banner"].ad{width:930px;height:180px}.ui[class*="half banner"].ad{width:234px;height:60px}.ui[class*="large leaderboard"].ad{width:970px;height:90px}.ui.billboard.ad{width:970px;height:250px}.ui.panorama.ad{width:980px;height:120px}.ui.netboard.ad{width:580px;height:400px}.ui[class*="large mobile banner"].ad{width:320px;height:100px}.ui[class*="mobile leaderboard"].ad{width:320px;height:50px}.ui.mobile.ad{display:none}@media only screen and (max-width:767px){.ui.mobile.ad{display:block}}.ui.centered.ad{margin-left:auto;margin-right:auto}.ui.test.ad{position:relative;background:#333}.ui.test.ad:after{position:absolute;top:50%;left:50%;width:100%;text-align:center;-webkit-transform:translateX(-50%)translateY(-50%);-ms-transform:translateX(-50%)translateY(-50%);transform:translateX(-50%)translateY(-50%);content:'Ad';color:#fff;font-size:1em;font-weight:700}.ui.mobile.test.ad:after{font-size:.85714em}.ui.test.ad[data-text]:after{content:attr(data-text)} -------------------------------------------------------------------------------- /py/report/semantic/components/breadcrumb.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * # Semantic UI 1.11.6 - Breadcrumb 3 | * http://github.com/semantic-org/semantic-ui/ 4 | * 5 | * 6 | * Copyright 2014 Contributors 7 | * Released under the MIT license 8 | * http://opensource.org/licenses/MIT 9 | * 10 | */ 11 | 12 | 13 | /******************************* 14 | Breadcrumb 15 | *******************************/ 16 | 17 | .ui.breadcrumb { 18 | margin: 1em 0em; 19 | display: inline-block; 20 | vertical-align: middle; 21 | } 22 | .ui.breadcrumb:first-child { 23 | margin-top: 0em; 24 | } 25 | .ui.breadcrumb:last-child { 26 | margin-bottom: 0em; 27 | } 28 | 29 | 30 | /******************************* 31 | Content 32 | *******************************/ 33 | 34 | 35 | /* Divider */ 36 | .ui.breadcrumb .divider { 37 | display: inline-block; 38 | opacity: 0.5; 39 | margin: 0em 0.2rem 0em; 40 | font-size: 0.9em; 41 | color: rgba(0, 0, 0, 0.4); 42 | vertical-align: baseline; 43 | } 44 | 45 | /* Link */ 46 | .ui.breadcrumb a { 47 | color: #009fda; 48 | } 49 | .ui.breadcrumb a:hover { 50 | color: #00b2f3; 51 | } 52 | 53 | /* Icon Divider */ 54 | .ui.breadcrumb .icon.divider { 55 | font-size: 0.85714286em; 56 | vertical-align: baseline; 57 | } 58 | 59 | /* Section */ 60 | .ui.breadcrumb a.section { 61 | cursor: pointer; 62 | } 63 | .ui.breadcrumb .section { 64 | display: inline-block; 65 | margin: 0em; 66 | padding: 0em; 67 | } 68 | 69 | /* Loose Coupling */ 70 | .ui.breadcrumb.segment { 71 | display: inline-block; 72 | padding: 0.5em 1em; 73 | } 74 | 75 | 76 | /******************************* 77 | States 78 | *******************************/ 79 | 80 | .ui.breadcrumb .active.section { 81 | font-weight: bold; 82 | } 83 | 84 | 85 | /******************************* 86 | Variations 87 | *******************************/ 88 | 89 | .ui.mini.breadcrumb { 90 | font-size: 0.65em; 91 | } 92 | .ui.tiny.breadcrumb { 93 | font-size: 0.7em; 94 | } 95 | .ui.small.breadcrumb { 96 | font-size: 0.75em; 97 | } 98 | .ui.breadcrumb { 99 | font-size: 1em; 100 | } 101 | .ui.large.breadcrumb { 102 | font-size: 1.1em; 103 | } 104 | .ui.big.breadcrumb { 105 | font-size: 1.05em; 106 | } 107 | .ui.huge.breadcrumb { 108 | font-size: 1.3em; 109 | } 110 | .ui.massive.breadcrumb { 111 | font-size: 1.5em; 112 | } 113 | 114 | 115 | /******************************* 116 | Theme Overrides 117 | *******************************/ 118 | 119 | 120 | 121 | /******************************* 122 | Site Overrides 123 | *******************************/ 124 | 125 | -------------------------------------------------------------------------------- /py/report/semantic/components/breadcrumb.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * # Semantic UI 1.11.6 - Breadcrumb 3 | * http://github.com/semantic-org/semantic-ui/ 4 | * 5 | * 6 | * Copyright 2014 Contributors 7 | * Released under the MIT license 8 | * http://opensource.org/licenses/MIT 9 | * 10 | */.ui.breadcrumb{margin:1em 0;display:inline-block;vertical-align:middle}.ui.breadcrumb:first-child{margin-top:0}.ui.breadcrumb:last-child{margin-bottom:0}.ui.breadcrumb .divider{display:inline-block;opacity:.5;margin:0 .2rem;font-size:.9em;color:rgba(0,0,0,.4);vertical-align:baseline}.ui.breadcrumb a{color:#009fda}.ui.breadcrumb a:hover{color:#00b2f3}.ui.breadcrumb .icon.divider{font-size:.85714286em;vertical-align:baseline}.ui.breadcrumb a.section{cursor:pointer}.ui.breadcrumb .section{display:inline-block;margin:0;padding:0}.ui.breadcrumb.segment{display:inline-block;padding:.5em 1em}.ui.breadcrumb .active.section{font-weight:700}.ui.mini.breadcrumb{font-size:.65em}.ui.tiny.breadcrumb{font-size:.7em}.ui.small.breadcrumb{font-size:.75em}.ui.breadcrumb{font-size:1em}.ui.large.breadcrumb{font-size:1.1em}.ui.big.breadcrumb{font-size:1.05em}.ui.huge.breadcrumb{font-size:1.3em}.ui.massive.breadcrumb{font-size:1.5em} -------------------------------------------------------------------------------- /py/report/semantic/components/checkbox.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * # Semantic UI 1.11.6 - Checkbox 3 | * http://github.com/semantic-org/semantic-ui/ 4 | * 5 | * 6 | * Copyright 2014 Contributors 7 | * Released under the MIT license 8 | * http://opensource.org/licenses/MIT 9 | * 10 | */ 11 | !function(e,n,t,o){"use strict";e.fn.checkbox=function(t){var c,i=e(this),r=i.selector||"",a=(new Date).getTime(),l=[],s=arguments[0],u="string"==typeof s,d=[].slice.call(arguments,1);return i.each(function(){var i,b,g=e.extend(!0,{},e.fn.checkbox.settings,t),h=g.className,f=g.namespace,p=g.selector,m=g.error,k="."+f,v="module-"+f,y=e(this),x=e(this).find(p.label).first(),C=e(this).find(p.input),D=y.data(v),E=this;b={initialize:function(){b.verbose("Initializing checkbox",g),b.create.label(),b.add.events(),b.is.checked()?(b.set.checked(),g.fireOnInit&&g.onChecked.call(C.get())):(b.remove.checked(),g.fireOnInit&&g.onUnchecked.call(C.get())),b.observeChanges(),b.instantiate()},instantiate:function(){b.verbose("Storing instance of module",b),D=b,y.data(v,b)},destroy:function(){b.verbose("Destroying module"),b.remove.events(),y.removeData(v)},refresh:function(){y=e(this),x=e(this).find(p.label).first(),C=e(this).find(p.input)},observeChanges:function(){"MutationObserver"in n&&(i=new MutationObserver(function(){b.debug("DOM tree modified, updating selector cache"),b.refresh()}),i.observe(E,{childList:!0,subtree:!0}),b.debug("Setting up mutation observer",i))},attachEvents:function(n,t){var o=e(n);t=e.isFunction(b[t])?b[t]:b.toggle,o.length>0?(b.debug("Attaching checkbox events to element",n,t),o.on("click"+k,t)):b.error(m.notFound)},event:{keydown:function(e){var n=e.which,t={enter:13,space:32,escape:27};n==t.escape&&(b.verbose("Escape key pressed blurring field"),y.blur()),e.ctrlKey||n!=t.enter&&n!=t.space||(b.verbose("Enter key pressed, toggling checkbox"),b.toggle.call(this),e.preventDefault())}},is:{radio:function(){return y.hasClass(h.radio)},checked:function(){return C.prop("checked")!==o&&C.prop("checked")},unchecked:function(){return!b.is.checked()}},can:{change:function(){return!(y.hasClass(h.disabled)||y.hasClass(h.readOnly)||C.prop("disabled"))},uncheck:function(){return"boolean"==typeof g.uncheckable?g.uncheckable:!b.is.radio()}},set:{checked:function(){y.addClass(h.checked)},tab:function(){C.attr("tabindex")===o&&C.attr("tabindex",0)}},create:{label:function(){C.prevAll(p.label).length>0?(C.prev(p.label).detach().insertAfter(C),b.debug("Moving existing label",x)):b.has.label()||(x=e("