├── 0_index.php ├── 1_upload_file.php ├── 1_upload_file_ed.php ├── 2_getface.php ├── 2_getface.py ├── 2_getface_ed.php ├── 3_facepoint.php ├── 3_facepoint.py ├── 3_facepoint_ed.php ├── 4_onchain.php ├── FaceDetect.exe ├── FacePointDetect.exe ├── Input ├── Connect_20_40_0.6.txt ├── Connect_20_40_1.0.txt ├── Connect_40_60_0.8.txt ├── Net_EN0.txt ├── Net_F0.txt ├── Net_LE1.txt ├── Net_LM1.txt ├── Net_N1.txt ├── Net_NM0.txt ├── Net_RE1.txt ├── Net_RM1.txt ├── Patch_EN0.txt ├── Patch_F0.txt ├── Patch_LE1_13.txt ├── Patch_LE1_15.txt ├── Patch_LE2_10.txt ├── Patch_LE2_9.txt ├── Patch_LM1_13.txt ├── Patch_LM1_15.txt ├── Patch_LM2_10.txt ├── Patch_LM2_9.txt ├── Patch_N1_13.txt ├── Patch_N1_15.txt ├── Patch_N2_10.txt ├── Patch_N2_9.txt ├── Patch_NM0.txt ├── Patch_RE1_13.txt ├── Patch_RE1_15.txt ├── Patch_RE2_10.txt ├── Patch_RE2_9.txt ├── Patch_RM1_13.txt ├── Patch_RM1_15.txt ├── Patch_RM2_10.txt ├── Patch_RM2_9.txt ├── Weight_EN0.bin ├── Weight_F0.bin ├── Weight_LE1_13.bin ├── Weight_LE1_15.bin ├── Weight_LE2_10.bin ├── Weight_LE2_9.bin ├── Weight_LM1_13.bin ├── Weight_LM1_15.bin ├── Weight_LM2_10.bin ├── Weight_LM2_9.bin ├── Weight_N1_13.bin ├── Weight_N1_15.bin ├── Weight_N2_10.bin ├── Weight_N2_9.bin ├── Weight_NM0.bin ├── Weight_RE1_13.bin ├── Weight_RE1_15.bin ├── Weight_RE2_10.bin ├── Weight_RE2_9.bin ├── Weight_RM1_13.bin ├── Weight_RM1_15.bin ├── Weight_RM2_10.bin └── Weight_RM2_9.bin ├── Output ├── imagebbox.list ├── imagebbox__recover.list ├── imagebbox_detect.list ├── imagebbox_detect_recover_replace.list ├── imagebbox_detect_replace.list ├── imagebbox_miss.list ├── imagebbox_recover_detect.list ├── imagebbox_recover_miss.list ├── imagelist.list ├── imagelist_point.list ├── imagelist_recover.list ├── readme.md └── result.bin ├── README.md ├── aligment.py ├── blank.htm ├── cleanBoxFile.py ├── data ├── detector_lfp.dat └── svmpostfilter_lfp.dat ├── demo0.JPG ├── demo1.JPG ├── facecrop.py ├── facepoint.py ├── img ├── bg.jpg └── logo.png ├── imresize.py ├── index.css ├── index.htm ├── lib ├── bootstrap-4.0.0-dist │ ├── css │ │ ├── bootstrap-grid.css │ │ ├── bootstrap-grid.css.map │ │ ├── bootstrap-grid.min.css │ │ ├── bootstrap-grid.min.css.map │ │ ├── bootstrap-reboot.css │ │ ├── bootstrap-reboot.css.map │ │ ├── bootstrap-reboot.min.css │ │ ├── bootstrap-reboot.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ └── js │ │ ├── bootstrap.bundle.js │ │ ├── bootstrap.bundle.js.map │ │ ├── bootstrap.bundle.min.js │ │ ├── bootstrap.bundle.min.js.map │ │ ├── bootstrap.js │ │ ├── bootstrap.js.map │ │ ├── bootstrap.min.js │ │ └── bootstrap.min.js.map ├── jquery-3.3.1.min.js ├── nebPay.js └── nebulas.js ├── main.py ├── makeImageFileList.py ├── makeimagelist.py ├── opencv_core231.dll ├── opencv_highgui231.dll ├── opencv_imgproc231.dll ├── retain_max_face.py ├── skimagetest.py ├── smartContract └── nasface.js ├── tbb.dll ├── test.py └── textutil.py /0_index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NasFace 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

人脸识别on区块链NasFace

14 | 15 |
16 | Step 1 →
17 | 请上传一张包含人脸的图片 18 |
19 | ◆单张不超过2M 20 |
21 | ◆支持jpg、png格式文件 22 |
23 |
24 | 25 |

26 |      27 | 28 |
29 | 30 |
31 |
32 | 33 | 34 | 作品介绍 35 |

36 | ◆本作品提供一套完整的【人脸识别】解决方案,并使用【区块链】存储和查询人脸特征数据,可广泛应用于各种场景,如【人脸锁】。 37 |

38 | ◆本作品区块链方案采用【星云链Nebulas】,请在开始使用前安装好WebExtensionWallet并创建账户后刷新本页,再开始操作。否则一系列的前期操作结果最终将无法与区块链交互,以至体验不到本作品运用区块链的核心意义。 39 |

40 | ◆【开源代码&演示文档】【区块链合约 41 |
42 |
43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /1_upload_file.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NasFace 6 | 7 | 8 | 9 | 10 | 不成功,请返回!"; 37 | exit(); 38 | } 39 | 40 | //echo $file["size"]; 41 | if(2000000 < $file["size"]) 42 | //检查文件大小 43 | { 44 | echo "错误_单张图片不要超过2M!不成功,请返回!"; 45 | exit(); 46 | } 47 | 48 | //判断是否是通过HTTP POST上传的 49 | if(!is_uploaded_file($file['tmp_name'])){ 50 | //如果不是通过HTTP POST上传的 51 | echo "错误_图片存在异常!不成功,请返回!"; 52 | exit(); 53 | } 54 | 55 | // $upload_path = "D:/phpStudy/WWW/2017bqp/uploadpic/"; //上传文件的存放路径 56 | 57 | $thetime = time(); 58 | $upload_path = "faces/uploadpic_".$thetime.""; //上传文件的存放路径 相对地址 59 | //开始移动文件到相应的文件夹 60 | mkdir($upload_path); 61 | $file['name_time'] = $upload_path."/face.".$type; 62 | 63 | if(move_uploaded_file($file['tmp_name'],$file['name_time'])){ 64 | //echo "Successfully!"; 65 | //echo "uploadpic/".$file['name_time']; 66 | 67 | //RETURN "uploadpic/".$file['name_time']; 68 | RETURN $file['name_time']; 69 | 70 | }else{ 71 | echo "错误_图片存在异常情况!不成功,请返回!"; 72 | exit(); 73 | } 74 | 75 | } 76 | 77 | 78 | $picurl = fileupload($picfile); 79 | 80 | 81 | if($picurl!=NULL) 82 | { 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | echo " 91 | 92 | 93 | 94 | 95 | "; 96 | 97 | 98 | //echo "

"; 99 | //echo "

下一步 人脸提取并对齐

"; 100 | 101 | } 102 | 103 | ?> 104 | 105 | 106 |
107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /1_upload_file_ed.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NasFace 6 | 7 | 8 | 9 | 10 | "; 26 | echo "
"; 27 | echo "
Step 2 →
"; 28 | 29 | echo "

"; 30 | echo "

下一步 人脸提取并对齐 →

"; 31 | echo "

点击后请耐心等待,计算过程大约一分钟,期间请不要再次点击,直到右边出现结果

"; 32 | 33 | 34 | ?> 35 | 36 | 37 |
38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /2_getface.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NasFace 6 | 7 | 8 | 9 | 10 | 11 | 46 | 47 | 48 | 49 | "; 50 | 51 | 52 | 53 | 54 | ?> 55 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /2_getface.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Apr 22 21:20:45 2015 4 | 5 | @author: Chenriwei 6 | 7 | @function: 8 | 主要实现人脸检测、关键点检测、人脸对齐、归一化等操作。 9 | 将各个步骤衔接起来,实现一键操作。 10 | 11 | @attention: 12 | 1,只适合在windows下使用; 13 | 2,人脸检测器和关键点检测器利用了香港中文大学提供的二进制文件,版权归他们所有; 14 | 3,可以用更好的人脸检测器和关键点检测器来替换掉默认的检测器。 15 | """ 16 | import makeimagelist 17 | import os 18 | import aligment 19 | import facecrop 20 | import textutil 21 | 22 | import sys 23 | 24 | def test(ImagePath,savePathDetect,savePathAligned,savePathCroped,fileformat=['png','jpg'],tag_recover=False,savesize=[128,128]): 25 | ''' 26 | 必须提供的参数: 27 | 1,@ImagePath:待检测和对齐的图像路径 28 | 2,@savePathDetect:保存检测到的人脸的文件夹路径 29 | 3,@savePathAligned:保存对其后的人脸文件夹路径 30 | 可选的参数(有默认值): 31 | 4,@fileformat:图像的格式列表,默认为png和jpg格式 32 | 5,@tag_recover: 是否先裁剪处人脸图像之后再做归一化,默认为False 33 | 6, @savesize: 检测后保留的人脸图像的大小,当tag_recover=True 的时候,才会生效,默认大小为64*64 34 | 35 | ''' 36 | 37 | if not os.path.exists(savePathDetect): 38 | os.makedirs(savePathDetect) 39 | if not os.path.exists(savePathAligned): 40 | os.makedirs(savePathAligned) 41 | if not os.path.exists(savePathCroped): 42 | os.makedirs(savePathCroped) 43 | 44 | 45 | print ('Begin making filelist. step (1/6) ') 46 | #创建imagelist.list 文件,用来保存文件图像文件列表 47 | imagelist = './Output/imagelist.list' 48 | fid=open(imagelist,'w') 49 | makeimagelist.makeImageFileList(ImagePath,fid,fileformat) 50 | fid.close() 51 | #统计有多少个图像文件 52 | count=textutil.count_text_line(imagelist) 53 | textutil.insertLine(imagelist,1,str(count)) 54 | 55 | print ('Done make file list. step(1/6)') 56 | 57 | #人脸检测,生成imageBbox.list 文件, 58 | print ('Begin Face Detection task. step(2/6)') 59 | bboxlist='./Output/imagebbox.list' 60 | os.system('FaceDetect.exe data '+imagelist+' '+bboxlist) 61 | print ('Done Face Detection task.step(2/6)') 62 | 63 | #清除检测不到的图像,或者检测到多个的文件,以便于后面的人脸关键点检测。 64 | print ('Begin Box file Clean and Replace. step(3/6)') 65 | detectlist='./Output/imagebbox_detect.list' 66 | misslist='./Output/imagebbox_miss.list' 67 | textutil.cleanbox(fileinput=bboxlist,detectlistfile=detectlist,misslistfile=misslist) 68 | replacelist='./Output/imagebbox_detect_replace.list' 69 | textutil.replace_file(detectlist,replacelist,ImagePath) 70 | print ('Done Box file Clean and Replace. step(3/6)' ) 71 | 72 | if tag_recover==True: 73 | #人脸先裁剪 74 | # 保留检测到的人脸图像,可选, 75 | print ('Begin Save Detected Face Image. step(4/4) optional') 76 | facecrop.face_cropout(ImagePath,savePathDetect,replacelist,w=savesize[0],h=savesize[1]) 77 | print ('Done Save Detected Face Image. step(4/4) optional') 78 | ImagePath=savePathDetect 79 | 80 | print ('Begin making filelist. step (1/6) ') 81 | #创建imagelist.list 文件,用来保存文件图像文件列表 82 | imagelist = './Output/imagelist_recover.list' 83 | fid=open(imagelist,'w') 84 | makeimagelist.makeImageFileList(ImagePath,fid,fileformat) 85 | fid.close() 86 | #统计有多少个图像文件 87 | count=textutil.count_text_line(imagelist) 88 | textutil.insertLine(imagelist,1,str(count)) 89 | 90 | print ('Done make file list. step(1/6)') 91 | 92 | #人脸检测,生成imageBbox.list 文件, 93 | print ('Begin Face Detection task. step(2/6)') 94 | bboxlist='./Output/imagebbox__recover.list' 95 | os.system('FaceDetect.exe data '+imagelist+' '+bboxlist) 96 | print ('Done Face Detection task.step(2/6)') 97 | 98 | #清除检测不到的图像,或者检测到多个的文件,以便于后面的人脸关键点检测。 99 | print ('Begin Box file Clean and Replace. step(3/6)') 100 | detectlist='./Output/imagebbox_recover_detect.list' 101 | misslist='./Output/imagebbox_recover_miss.list' 102 | textutil.cleanbox(fileinput=bboxlist,detectlistfile=detectlist,misslistfile=misslist) 103 | replacelist='./Output/imagebbox_detect_recover_replace.list' 104 | textutil.replace_file(detectlist,replacelist,ImagePath) 105 | print ('Done Box file Clean and Replace. step(3/6)') 106 | 107 | #人脸关键点检测 108 | print ('Begin Face Point Detection. step(4/6)' ) 109 | resultpath='./Output/result.bin' 110 | command_='FacePointDetect.exe '+replacelist+' '+ImagePath+' Input '+resultpath 111 | os.system(command_) 112 | print ('Done Face Point Detection. step(4/6)') 113 | 114 | print ('Begin write Points files. step(5/6)') 115 | points=textutil.take_out_point(resultpath) 116 | imagepointlist='./Output/imagelist_point.list' 117 | textutil.writePoint2File(replacelist,imagepointlist,points) 118 | print ('Done write Points files. step(5/6)') 119 | 120 | print ('Begin Alignment Face. step(6/6)') 121 | aligment.align_all(imagepointlist,ImagePath,savePathAligned) 122 | print ('Done Alignment Face. step(6/6)') 123 | 124 | print ('Begin Face croped in') 125 | facecrop.face_crop_in(savePathAligned,savePathCroped,replacelist,savesize[0],savesize[1]) 126 | print ('Done Face croped in ') 127 | print ('All work is done!') 128 | 129 | 130 | if __name__ == "__main__" : 131 | ''' 132 | @param: 提供的参数:1,图像的文件名位置,2,需要保留的文件位置,3,图像的格式列表 133 | ''' 134 | #ImagePath=r'./faces/uploadpic_1528272773' #原始的图像路径 135 | #savePathDetect=r'./faces/uploadpic_1528272773/1detect'#保存中间检测到的图像的路径 136 | #savePathAligned=r'./faces/uploadpic_1528272773/2align'#对齐后的人脸图像的保存路径 137 | #savePathCroped=r'./faces/uploadpic_1528272773/3croped' 138 | 139 | Ps = sys.argv[1] 140 | ImagePath=r'./'+Ps+'' #原始的图像路径 141 | savePathDetect=r'./'+Ps+'/1detect'#保存中间检测到的图像的路径 142 | savePathAligned=r'./'+Ps+'/2align'#对齐后的人脸图像的保存路径 143 | savePathCroped=r'./'+Ps+'/3croped' 144 | 145 | test(ImagePath,savePathDetect,savePathAligned,savePathCroped,tag_recover=True,savesize=[256,256]) 146 | -------------------------------------------------------------------------------- /2_getface_ed.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NasFace 6 | 7 | 8 | 9 | 10 | "; 28 | echo "
"; 29 | echo "
Step 3 →
"; 30 | 31 | //$picurl 32 | 33 | 34 | $picurl_1 = $picurl."/3croped/face.jpg"; 35 | $picurl_2 = $picurl."/3croped/face.png"; 36 | 37 | if(file_exists($picurl_1)) 38 | { 39 | //echo "

"; 40 | //echo "

"; 41 | echo "

"; 42 | echo "

下一步 人脸特征点提取 →

"; 43 | echo "

点击后请耐心等待,计算过程大约10秒,期间请不要再次点击,直到右边出现结果

"; 44 | } 45 | elseif(file_exists($picurl_2)) 46 | { 47 | echo "

"; 48 | echo "

下一步 人脸特征点提取 →

"; 49 | echo "

点击后请耐心等待,计算过程大约10秒,期间请不要再次点击,直到右边出现结果

"; 50 | } 51 | else 52 | { 53 | echo "没有提取出有效人脸!请回到第一步重新上传包含人脸的图片!"; 54 | } 55 | 56 | 57 | 58 | ?> 59 | 60 | 61 |
62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /3_facepoint.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NasFace 6 | 7 | 8 | 9 | 41 | 42 | 43 | 44 | "; 45 | 46 | 47 | 48 | 49 | ?> 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /3_facepoint.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | import cv2 4 | import dlib 5 | 6 | import sys 7 | 8 | oldpic = sys.argv[1] 9 | 10 | detector = dlib.get_frontal_face_detector() 11 | landmark_predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat') 12 | img = cv2.imread(oldpic) 13 | faces = detector(img,1) 14 | dx = [] 15 | dy = [] 16 | if (len(faces) > 0): 17 | for k,d in enumerate(faces): 18 | cv2.rectangle(img,(d.left(),d.top()),(d.right(),d.bottom()),(255,255,255)) 19 | shape = landmark_predictor(img,d) 20 | for i in range(68): 21 | print(i) 22 | dx.append(shape.part(i).x) 23 | dy.append(shape.part(i).y) 24 | cv2.circle(img, (shape.part(i).x, shape.part(i).y),5,(0,255,0), -1, 8) 25 | cv2.putText(img,str(i),(shape.part(i).x,shape.part(i).y),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,255,255)) 26 | #cv2.imshow('Frame',img) 27 | #cv2.waitKey(0) 28 | 29 | 30 | newpic = oldpic.replace('face.', 'face_68points.') 31 | 32 | cv2.imwrite(newpic,img) 33 | 34 | def getlenof2(x1,y1,x2,y2): #计算两点之间的距离 35 | result = math.sqrt(math.pow(x1-x2,2)+math.pow(y1-y2,2)) 36 | return result 37 | 38 | lenof2_36_45 = getlenof2(dx[36],dy[36],dx[45],dy[45]) 39 | lenof2_39_42 = getlenof2(dx[39],dy[39],dx[42],dy[42]) 40 | lenof2_27_33 = getlenof2(dx[27],dy[27],dx[33],dy[33]) 41 | lenof2_31_35 = getlenof2(dx[31],dy[31],dx[35],dy[35]) 42 | lenof2_0_16 = getlenof2(dx[0],dy[0],dx[16],dy[16]) 43 | lenof2_33_51 = getlenof2(dx[33],dy[33],dx[51],dy[51]) 44 | lenof2_57_8 = getlenof2(dx[57],dy[57],dx[8],dy[8]) 45 | lenof2_48_54 = getlenof2(dx[48],dy[48],dx[54],dy[54]) 46 | lenof2_51_57 = getlenof2(dx[51],dy[51],dx[57],dy[57]) 47 | lenof2_66_33 = getlenof2(dx[66],dy[66],dx[33],dy[33]) 48 | lenof2_36_45 = getlenof2(dx[36],dy[36],dx[45],dy[45]) 49 | 50 | Ap1 = int((lenof2_36_45*10)//lenof2_39_42) 51 | Ap2 = int((lenof2_27_33*10)//lenof2_31_35) 52 | #Ap3 = int((lenof2_39_42*10)//lenof2_27_33) 53 | #Ap4 = int((lenof2_0_16*10)//lenof2_39_42) 54 | #Ap5 = int((lenof2_33_51*10)//lenof2_57_8) 55 | #Ap6 = int((lenof2_48_54*10)//lenof2_51_57) 56 | #Ap7 = int((lenof2_66_33*10)//lenof2_36_45) 57 | 58 | #Ap = str(Ap1)+'_'+str(Ap2)+'_'+str(Ap3)+'_'+str(Ap4)+'_'+str(Ap5)+'_'+str(Ap6)+'_'+str(Ap7) 59 | 60 | Ap = str(Ap1)+'_'+str(Ap2) 61 | 62 | print(Ap) 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /3_facepoint_ed.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NasFace 6 | 7 | 8 | 9 | 10 | "; 27 | echo "
"; 28 | echo "
Step 4 →
"; 29 | 30 | //$picurl 31 | 32 | 33 | 34 | if($Ap!=NULL) 35 | { 36 | echo "

"; 37 | $Ap_md5 = md5($Ap); 38 | echo "

下一步 在区块链上查询/记录 →

"; 39 | } 40 | else 41 | { 42 | echo "未识别出人脸特征点,请换照片!"; 43 | echo "返回!"; 44 | } 45 | 46 | 47 | 48 | 49 | ?> 50 | 51 | 52 |
53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /4_onchain.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 21 | 22 | 23 | 24 | 25 | NasFace 26 | 27 | 32 | 33 | 34 | 35 | 36 |
37 |
38 |
Step 5 ↓
39 | 40 |

41 |

42 | 43 |
44 |
系统记录是:
?
45 |
46 |
记录人:
?
47 |
48 | 49 |
50 | 系统尚无该人脸记录,可该人脸信息 51 | 52 |
53 | 54 |
55 | 56 |

57 |
58 | 59 | 60 | 61 | 62 | 63 | 195 | 196 | 197 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /FaceDetect.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/FaceDetect.exe -------------------------------------------------------------------------------- /FacePointDetect.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/FacePointDetect.exe -------------------------------------------------------------------------------- /Input/Connect_20_40_0.6.txt: -------------------------------------------------------------------------------- 1 | 0 1 0 1 1 0 1 1 0 1 0 0 1 1 0 1 1 1 0 0 0 1 0 0 0 1 1 0 1 1 1 1 1 0 1 0 0 0 1 1 2 | 1 1 0 1 1 1 1 0 1 1 1 1 1 0 0 1 0 1 1 1 0 0 0 1 0 0 0 1 1 0 1 1 1 1 0 1 1 0 1 0 3 | 1 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 0 1 1 1 0 1 1 0 0 1 0 1 0 1 1 0 0 0 1 1 0 0 1 1 4 | 0 1 1 1 1 0 1 1 1 1 0 1 0 1 1 1 1 0 0 1 0 0 1 0 0 1 0 1 1 0 0 0 1 0 1 1 1 1 1 0 5 | 0 1 1 1 0 1 0 1 0 0 1 0 0 1 0 0 1 1 1 1 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 0 1 1 1 6 | 0 1 1 1 0 0 1 1 0 1 1 0 0 0 1 0 1 0 0 1 1 0 0 1 1 1 1 1 0 1 1 0 1 1 1 1 0 1 0 1 7 | 1 1 0 0 1 1 0 1 0 0 1 1 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 1 1 1 1 1 0 0 0 1 1 0 8 | 1 0 1 1 0 0 1 0 1 0 1 1 0 0 0 1 1 1 1 0 0 1 0 0 1 1 1 0 1 1 1 0 1 0 0 1 1 1 1 0 9 | 0 1 0 0 1 1 1 0 0 1 1 1 1 1 1 0 0 1 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 0 1 1 1 0 1 10 | 1 0 0 1 1 0 0 0 1 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 0 1 1 0 1 0 0 1 1 1 0 1 1 0 0 11 | 0 0 0 0 1 1 0 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 1 1 0 1 0 1 0 1 0 0 1 0 0 1 1 12 | 1 1 0 1 0 0 0 1 0 1 1 0 1 1 0 0 1 0 1 0 1 1 0 1 1 1 1 1 1 0 1 1 0 0 1 0 1 1 0 1 13 | 1 1 1 0 1 1 0 1 1 0 0 0 1 0 1 1 0 1 0 1 1 1 0 1 1 0 1 1 1 0 0 0 1 1 1 0 1 0 0 0 14 | 0 1 1 0 1 1 1 0 1 0 0 0 0 1 1 1 1 0 1 1 1 1 1 0 1 1 0 0 1 0 0 1 0 0 1 1 1 1 0 1 15 | 1 0 0 1 0 0 0 1 1 1 1 0 1 1 1 1 1 0 0 0 1 0 1 0 1 1 0 1 1 1 1 0 0 1 0 1 0 0 1 1 16 | 0 0 1 0 0 1 1 1 0 1 1 1 1 1 0 1 1 1 1 0 1 0 1 0 0 1 1 1 0 1 0 1 1 1 1 1 1 0 1 0 17 | 1 0 1 1 0 0 0 1 0 1 0 1 0 1 1 1 0 1 1 1 1 1 1 0 0 0 1 0 1 1 0 1 0 1 1 1 0 1 1 1 18 | 1 1 1 1 0 1 1 0 1 0 0 0 1 0 0 0 1 1 0 1 1 1 1 1 0 1 0 0 1 0 1 1 1 1 0 0 1 1 1 0 19 | 0 0 1 1 1 1 1 0 1 1 0 1 1 0 1 1 0 0 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 0 1 1 0 1 20 | 1 1 1 0 1 1 1 1 1 1 0 1 0 0 1 0 1 0 1 0 0 1 1 1 1 0 0 1 0 1 1 1 0 0 1 0 0 0 0 0 21 | -------------------------------------------------------------------------------- /Input/Connect_20_40_1.0.txt: -------------------------------------------------------------------------------- 1 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 5 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 6 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 7 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 9 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 12 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 13 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 15 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 17 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 18 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 19 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 20 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 21 | -------------------------------------------------------------------------------- /Input/Connect_40_60_0.8.txt: -------------------------------------------------------------------------------- 1 | 1 1 0 0 1 1 0 0 1 1 1 1 1 1 1 1 0 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 1 0 1 1 0 1 1 1 1 1 0 1 1 0 0 1 1 1 1 1 1 2 | 1 1 0 0 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 0 0 1 1 1 1 0 1 1 1 1 0 1 0 1 1 1 1 0 1 1 0 0 0 1 1 1 1 1 1 0 1 1 0 1 1 1 0 1 3 | 0 1 1 1 1 1 1 0 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 0 1 0 0 0 0 1 1 1 1 4 | 1 1 1 1 1 0 1 1 1 0 1 1 0 0 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 0 1 1 0 1 1 1 0 1 1 1 1 1 0 1 5 | 1 1 0 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 1 0 1 1 1 1 1 1 1 0 1 0 1 1 0 1 0 1 1 1 1 1 1 0 1 1 1 1 1 6 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 1 0 1 1 1 1 0 0 0 1 1 1 1 1 1 1 0 1 1 0 1 1 1 0 1 1 1 0 0 0 1 1 0 0 1 7 | 1 0 0 1 1 0 1 1 1 1 1 1 0 1 1 0 0 1 1 1 1 0 1 1 1 0 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 1 1 1 1 0 1 8 | 1 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 0 1 1 0 0 1 1 1 1 0 0 1 1 1 1 1 1 0 1 0 1 1 1 0 1 1 0 1 1 1 0 9 | 0 1 1 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 0 1 0 1 1 1 0 0 1 0 0 1 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 10 | 0 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 0 0 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 11 | 0 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 1 1 0 1 1 1 0 1 0 1 0 1 1 0 1 1 0 1 0 1 0 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 12 | 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 1 1 0 1 1 0 0 0 1 1 1 1 0 1 1 13 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 14 | 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1 1 0 0 1 1 1 0 1 0 1 1 1 1 0 1 0 1 1 1 15 | 1 1 0 1 1 0 1 1 1 0 1 1 0 1 0 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 0 1 0 1 1 1 0 1 16 | 1 0 1 1 1 1 1 0 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 0 0 1 1 1 1 1 1 1 1 0 1 1 1 17 | 1 1 1 1 1 0 0 1 1 1 0 1 0 1 1 0 1 1 1 0 0 1 1 1 1 1 1 1 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 1 1 0 0 1 0 18 | 1 1 1 1 0 1 1 1 1 1 0 0 1 1 1 1 0 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0 0 0 1 1 0 19 | 1 0 1 1 1 1 1 1 1 1 1 0 1 1 0 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 0 0 0 1 1 1 1 1 1 1 20 | 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 0 1 0 0 1 0 0 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 0 1 1 1 21 | 1 0 0 1 1 1 1 0 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 0 1 0 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 0 0 0 0 1 22 | 1 0 1 1 0 1 1 1 0 1 0 1 1 0 0 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 1 0 23 | 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 0 1 1 1 0 1 1 1 1 0 0 1 0 1 1 1 1 1 0 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0 24 | 1 1 1 0 1 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 0 0 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 25 | 1 1 1 0 0 1 1 1 1 1 1 1 1 1 0 1 0 1 0 0 0 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 1 26 | 1 1 1 1 1 1 0 1 0 0 1 1 1 1 1 1 1 1 0 1 1 0 1 0 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 0 1 0 27 | 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 0 1 0 1 1 1 0 1 0 0 0 1 1 1 1 1 1 0 1 1 1 0 1 0 1 1 0 0 28 | 0 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 29 | 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 0 1 1 0 1 0 1 1 1 1 0 0 0 1 1 1 0 1 1 1 0 1 1 0 0 1 1 0 1 1 1 1 1 1 1 1 1 30 | 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 0 0 0 1 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 0 0 0 0 1 31 | 1 1 1 0 0 0 0 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 0 1 0 0 1 1 1 1 1 1 1 0 1 32 | 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 0 0 1 1 0 0 1 0 1 1 0 0 1 1 1 1 1 1 1 1 1 0 0 1 0 1 1 0 0 1 1 1 1 1 1 1 0 33 | 1 0 1 1 1 1 1 0 0 1 1 1 0 0 0 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 0 1 1 1 1 0 1 1 1 1 1 1 0 1 0 0 1 1 1 34 | 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 0 0 1 0 35 | 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 0 1 1 1 0 1 1 0 1 1 0 1 0 1 0 1 1 1 1 1 0 0 1 1 1 1 1 1 1 0 1 0 1 0 1 1 1 1 0 1 1 1 36 | 1 1 1 0 0 1 1 1 1 1 1 0 1 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 1 0 1 1 1 0 0 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 1 1 0 1 0 37 | 1 1 1 1 0 0 1 1 0 1 1 1 1 0 1 1 1 1 1 1 0 1 1 0 1 0 1 1 1 0 0 1 0 1 1 0 1 1 1 1 1 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 38 | 1 1 0 1 1 1 0 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 0 1 1 0 1 0 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 39 | 0 1 1 1 0 1 0 0 1 1 1 0 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1 1 0 1 1 1 1 1 40 | 1 1 1 1 0 1 1 0 1 1 1 1 0 1 1 0 1 1 0 0 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 41 | -------------------------------------------------------------------------------- /Input/Net_EN0.txt: -------------------------------------------------------------------------------- 1 | 31 39 2 | 2 3 | 4 4 | 20 5 | 2 6 | 3 7 | 40 8 | 2 9 | 3 10 | 60 11 | 2 12 | 80 13 | 100 14 | 6 15 | 1 1 2 2 3 2 2 1 16 | -------------------------------------------------------------------------------- /Input/Net_F0.txt: -------------------------------------------------------------------------------- 1 | 39 39 2 | 2 3 | 4 4 | 20 5 | 2 6 | 3 7 | 40 8 | 2 9 | 3 10 | 60 11 | 2 12 | 80 13 | 120 14 | 10 15 | 2 2 2 2 3 3 2 2 16 | -------------------------------------------------------------------------------- /Input/Net_LE1.txt: -------------------------------------------------------------------------------- 1 | 15 15 2 | 2 3 | 4 4 | 20 5 | 2 6 | 3 7 | 40 8 | 60 9 | 2 10 | 1 1 1 1 11 | -------------------------------------------------------------------------------- /Input/Net_LM1.txt: -------------------------------------------------------------------------------- 1 | 15 15 2 | 2 3 | 4 4 | 20 5 | 2 6 | 3 7 | 40 8 | 60 9 | 2 10 | 1 1 1 1 11 | -------------------------------------------------------------------------------- /Input/Net_N1.txt: -------------------------------------------------------------------------------- 1 | 15 15 2 | 2 3 | 4 4 | 20 5 | 2 6 | 3 7 | 40 8 | 60 9 | 2 10 | 1 1 1 1 11 | -------------------------------------------------------------------------------- /Input/Net_NM0.txt: -------------------------------------------------------------------------------- 1 | 31 39 2 | 2 3 | 4 4 | 20 5 | 2 6 | 3 7 | 40 8 | 2 9 | 3 10 | 60 11 | 2 12 | 80 13 | 100 14 | 6 15 | 1 1 2 2 3 2 2 1 16 | -------------------------------------------------------------------------------- /Input/Net_RE1.txt: -------------------------------------------------------------------------------- 1 | 15 15 2 | 2 3 | 4 4 | 20 5 | 2 6 | 3 7 | 40 8 | 60 9 | 2 10 | 1 1 1 1 11 | -------------------------------------------------------------------------------- /Input/Net_RM1.txt: -------------------------------------------------------------------------------- 1 | 15 15 2 | 2 3 | 4 4 | 20 5 | 2 6 | 3 7 | 40 8 | 60 9 | 2 10 | 1 1 1 1 11 | -------------------------------------------------------------------------------- /Input/Patch_EN0.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 0 1 2 3 | -2.5 42.5 -2.0 33.77 4 | -------------------------------------------------------------------------------- /Input/Patch_F0.txt: -------------------------------------------------------------------------------- 1 | 5 2 | 0 1 2 3 4 3 | -2.5 42.5 -2.5 42.5 4 | -------------------------------------------------------------------------------- /Input/Patch_LE1_13.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 0 3 | -6.5 6.5 -6.5 6.5 4 | -------------------------------------------------------------------------------- /Input/Patch_LE1_15.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 0 3 | -7.5 7.5 -7.5 7.5 4 | -------------------------------------------------------------------------------- /Input/Patch_LE2_10.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 0 3 | -5.0 5.0 -5.0 5.0 4 | -------------------------------------------------------------------------------- /Input/Patch_LE2_9.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 0 3 | -4.5 4.5 -4.5 4.5 4 | -------------------------------------------------------------------------------- /Input/Patch_LM1_13.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 3 3 | -6.5 6.5 -6.5 6.5 4 | -------------------------------------------------------------------------------- /Input/Patch_LM1_15.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 3 3 | -7.5 7.5 -7.5 7.5 4 | -------------------------------------------------------------------------------- /Input/Patch_LM2_10.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 3 3 | -5.0 5.0 -5.0 5.0 4 | -------------------------------------------------------------------------------- /Input/Patch_LM2_9.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 3 3 | -4.5 4.5 -4.5 4.5 4 | -------------------------------------------------------------------------------- /Input/Patch_N1_13.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | -6.5 6.5 -6.5 6.5 4 | -------------------------------------------------------------------------------- /Input/Patch_N1_15.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | -7.5 7.5 -7.5 7.5 4 | -------------------------------------------------------------------------------- /Input/Patch_N2_10.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | -5.0 5.0 -5.0 5.0 4 | -------------------------------------------------------------------------------- /Input/Patch_N2_9.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 2 3 | -4.5 4.5 -4.5 4.5 4 | -------------------------------------------------------------------------------- /Input/Patch_NM0.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 2 3 4 3 | -2.5 42.5 6.73 42.5 4 | -------------------------------------------------------------------------------- /Input/Patch_RE1_13.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -6.5 6.5 -6.5 6.5 4 | -------------------------------------------------------------------------------- /Input/Patch_RE1_15.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -7.5 7.5 -7.5 7.5 4 | -------------------------------------------------------------------------------- /Input/Patch_RE2_10.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -5.0 5.0 -5.0 5.0 4 | -------------------------------------------------------------------------------- /Input/Patch_RE2_9.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | -4.5 4.5 -4.5 4.5 4 | -------------------------------------------------------------------------------- /Input/Patch_RM1_13.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 4 3 | -6.5 6.5 -6.5 6.5 4 | -------------------------------------------------------------------------------- /Input/Patch_RM1_15.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 4 3 | -7.5 7.5 -7.5 7.5 4 | -------------------------------------------------------------------------------- /Input/Patch_RM2_10.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 4 3 | -5.0 5.0 -5.0 5.0 4 | -------------------------------------------------------------------------------- /Input/Patch_RM2_9.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 4 3 | -4.5 4.5 -4.5 4.5 4 | -------------------------------------------------------------------------------- /Input/Weight_EN0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_EN0.bin -------------------------------------------------------------------------------- /Input/Weight_F0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_F0.bin -------------------------------------------------------------------------------- /Input/Weight_LE1_13.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_LE1_13.bin -------------------------------------------------------------------------------- /Input/Weight_LE1_15.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_LE1_15.bin -------------------------------------------------------------------------------- /Input/Weight_LE2_10.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_LE2_10.bin -------------------------------------------------------------------------------- /Input/Weight_LE2_9.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_LE2_9.bin -------------------------------------------------------------------------------- /Input/Weight_LM1_13.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_LM1_13.bin -------------------------------------------------------------------------------- /Input/Weight_LM1_15.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_LM1_15.bin -------------------------------------------------------------------------------- /Input/Weight_LM2_10.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_LM2_10.bin -------------------------------------------------------------------------------- /Input/Weight_LM2_9.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_LM2_9.bin -------------------------------------------------------------------------------- /Input/Weight_N1_13.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_N1_13.bin -------------------------------------------------------------------------------- /Input/Weight_N1_15.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_N1_15.bin -------------------------------------------------------------------------------- /Input/Weight_N2_10.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_N2_10.bin -------------------------------------------------------------------------------- /Input/Weight_N2_9.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_N2_9.bin -------------------------------------------------------------------------------- /Input/Weight_NM0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_NM0.bin -------------------------------------------------------------------------------- /Input/Weight_RE1_13.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_RE1_13.bin -------------------------------------------------------------------------------- /Input/Weight_RE1_15.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_RE1_15.bin -------------------------------------------------------------------------------- /Input/Weight_RE2_10.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_RE2_10.bin -------------------------------------------------------------------------------- /Input/Weight_RE2_9.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_RE2_9.bin -------------------------------------------------------------------------------- /Input/Weight_RM1_13.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_RM1_13.bin -------------------------------------------------------------------------------- /Input/Weight_RM1_15.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_RM1_15.bin -------------------------------------------------------------------------------- /Input/Weight_RM2_10.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_RM2_10.bin -------------------------------------------------------------------------------- /Input/Weight_RM2_9.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Input/Weight_RM2_9.bin -------------------------------------------------------------------------------- /Output/imagebbox.list: -------------------------------------------------------------------------------- 1 | ./faces/uploadpic_1528644489\face.jpg 53 202 108 258 2 | -------------------------------------------------------------------------------- /Output/imagebbox__recover.list: -------------------------------------------------------------------------------- 1 | ./faces/uploadpic_1528644489/1detect\face.jpg 58 191 60 193 2 | -------------------------------------------------------------------------------- /Output/imagebbox_detect.list: -------------------------------------------------------------------------------- 1 | ./faces/uploadpic_1528644489\face.jpg 53 202 108 258 2 | -------------------------------------------------------------------------------- /Output/imagebbox_detect_recover_replace.list: -------------------------------------------------------------------------------- 1 | \face.jpg 58 191 60 193 2 | -------------------------------------------------------------------------------- /Output/imagebbox_detect_replace.list: -------------------------------------------------------------------------------- 1 | \face.jpg 53 202 108 258 2 | -------------------------------------------------------------------------------- /Output/imagebbox_miss.list: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Output/imagebbox_miss.list -------------------------------------------------------------------------------- /Output/imagebbox_recover_detect.list: -------------------------------------------------------------------------------- 1 | ./faces/uploadpic_1528644489/1detect\face.jpg 58 191 60 193 2 | -------------------------------------------------------------------------------- /Output/imagebbox_recover_miss.list: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Output/imagebbox_recover_miss.list -------------------------------------------------------------------------------- /Output/imagelist.list: -------------------------------------------------------------------------------- 1 | 1 2 | ./faces/uploadpic_1528644489\face.jpg 3 | -------------------------------------------------------------------------------- /Output/imagelist_point.list: -------------------------------------------------------------------------------- 1 | \face.jpg 88 93 162 93 125 136 95 165 158 164 2 | -------------------------------------------------------------------------------- /Output/imagelist_recover.list: -------------------------------------------------------------------------------- 1 | 1 2 | ./faces/uploadpic_1528644489/1detect\face.jpg 3 | -------------------------------------------------------------------------------- /Output/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Output/readme.md -------------------------------------------------------------------------------- /Output/result.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/Output/result.bin -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 2 | # 人脸识别on区块链 3 | # 4 | # 5 | # 6 | # 7 | ## http://NasFace.com 或 http://180.76.136.150/ 8 | ## 9 | ### 本作品提供一套完整的【人脸识别】解决方案,并使用【区块链】存储和查询人脸特征数据,可广泛应用于各种场景,如【人脸锁】。 10 | ### 本作品区块链方案采用[星云链Nebulas](https://nebulas.io/),请在开始使用前安装好[WebExtensionWallet](https://github.com/ChengOrangeJu/WebExtensionWallet)并创建账户后刷新,再开始操作。否则一系列的前期操作结果最终将无法与区块链交互,以至体验不到本作品运用区块链的核心意义。 11 | ### [开源代码&演示文档](https://github.com/lawup/nasface) 12 | ### [区块链合约](https://explorer.nebulas.io/#/tx/3fb368b822c91506c0a58593e08b5bf9922a84f72c7469c5e36053312e6bc7de) 13 | ## 14 | ## 15 | ## Step1 上传一张图片 16 | ### 选择一张图片,点击【确认上传 → 】 17 | ### 单张不超过2M 支持jpg、png格式文件 18 | ## 19 | ## Step2 人脸提取并对齐 20 | ### 待上传的图片显示出来,点击【下一步 人脸提取并对齐 → 】 21 | ### 点击一次后请耐心等待,计算过程大约一分钟,期间请不要再次点击,直到右边出现结果 22 | ### 后台运行的【人脸检测&对齐&裁剪】等归一化能力由[FaceTools](https://github.com/RiweiChen/FaceTools)提供 23 | ## 24 | ## Step3 人脸特征点提取 25 | ### 待人脸提取并对齐的结果图片显示出来,点击【下一步 人脸特征点提取 → 】 26 | ### 点击后请耐心等待,计算过程大约10秒,期间请不要再次点击,直到右边出现结果 27 | ### 后台运行的【人脸68个特征点的提取】,能力由[dlib](http://dlib.net)提供 28 | ### 提取人脸的68个特征点之后,系统会据此计算7个自定义的特征比例(同一个人脸的不同照片,特征比例将是确定的,因此可作为同一认定的依据。当然在目前的演示中,为了较好的用户体验,仅用了2个特征点比例,这样做降低了识别门槛,但在实际运用中会降低安全性,也有可能造成误识别),据此7项特征比例数据整体生成一个哈希值(为保护隐私,不提倡明文。若在正式应用中,可用pyc文件代替py文件,即可最大限度保护用户隐私) 29 | ## 30 | ## Step4 在区块链上查询/记录 31 | ### 待上一步计算完成,可点击【下一步 在区块链上查询/记录 →】进入Step5 32 | ## 33 | ## Step5-1 查询 34 | ### 点击【查询 看看Ta是谁】按钮,系统会查询区块链网络,将结果反馈: 35 | ### 若已有记录,则反馈【内容(一般是该脸的主人的姓名,如“张三”)】及【记录人(提交内容的区块链钱包账号)】 36 | ## Step5-2 记录 37 | ### 若点击【查询 看看Ta是谁】按钮,系统中没有查到相应记录,则会反馈:系统尚无该人脸记录,可【添加】该人脸信息 38 | ### 那么,点击【添加】,可在得到的输入框中输入脸主人的名字,再点击【提交数据到区块链上】,可调起[WebExtensionWallet](https://github.com/ChengOrangeJu/WebExtensionWallet)(因此事前应将其装好并创建钱包账户,账户中需有少许NAS币,大约0.0001就够,如果没有可微信作者71520977索要),在弹出框中【Unlock】了钱包账户的前提下,依次点击【Confirm】和【Submit】即可,然后等待数秒,数据即成功提交到区块链上了。 39 | ### 之后,再点击【查询 看看Ta是谁】按钮时,系统就会查询到刚刚提交的人脸信息了。(如果这是一个【人脸锁】的应用的话,这一步相当于是注册,而【查询】可以认为是在验证人脸) 40 | ## 41 | ## 42 | ## 运行环境 43 | ### windows10 ([FaceTools](https://github.com/RiweiChen/FaceTools)需要在windows下运行) 44 | ### php5.4 (需要打开exec(),即在PHP.ini中去掉disable_functions行的exec项) 45 | ### python3.5.3 46 | ### dlib19.4.0 (可下载安装编译好的whl文件dlib-19.4.0-cp35-cp35m-win_amd64.whl ,避免繁琐编译,下载链接:https://pan.baidu.com/s/1KSCF2r_Lt71l2aOpKoS0HA 密码:qn54 ) 47 | ### dlib要用到的人脸库 shape_predictor_68_face_landmarks.dat 在[这里下载](http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2) ,下载后放在本程序根目录中即可 48 | ### 49 | ### 50 | ### 需要说明的是,本作品仅是个实验作品,有关人脸识别的准确率和区块链的运行效率及可行性,尚在探讨中。 51 | ### 欢迎与作者联系,微信:71520977 52 | ### 53 | 54 | -------------------------------------------------------------------------------- /aligment.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri May 29 20:01:59 2015 4 | 5 | @author: Chenriwei 6 | @brief: 根据检测到的点,对其人脸图像 7 | """ 8 | import cv2 9 | import os 10 | import numpy as np 11 | import matplotlib.pylab as plt 12 | import skimage 13 | from skimage import transform as tf 14 | from skimage import io 15 | def compute_affine_transform(refpoints, points, w = None): 16 | ''' 17 | 计算仿射变换矩阵 18 | ''' 19 | if w == None:#每个关键点的权重 20 | w = [1] * (len(points) * 2) 21 | assert(len(w) == 2*len(points)) 22 | y = [] 23 | for n, p in enumerate(refpoints): 24 | y += [p[0]/w[n*2], p[1]/w[n*2+1]] 25 | A = [] 26 | for n, p in enumerate(points): 27 | A.extend([ [p[0]/w[n*2], p[1]/w[n*2], 0, 0, 1/w[n*2], 0], [0, 0, p[0]/w[n*2+1], p[1]/w[n*2+1], 0, 1/w[n*2+1]] ]) 28 | 29 | lstsq = cv2.solve(np.array(A), np.array(y), flags=cv2.DECOMP_SVD) 30 | h11, h12, h21, h22, dx, dy = lstsq[1] 31 | #err = 0#lstsq[1] 32 | 33 | #R = np.array([[h11, h12, dx], [h21, h22, dy]]) 34 | # The row above works too - but creates a redundant dimension 35 | R = np.array([[h11[0], h12[0], dx[0]], [h21[0], h22[0], dy[0]]]) 36 | return R#, err 37 | 38 | def alignment(filename,points,ref_points): 39 | ''' 40 | @brief: 根据检测到的点,对其人脸图像 41 | ''' 42 | assert(len(points)==len(ref_points)) 43 | num_point=len(ref_points)//2 44 | #参考图像的点 45 | dst=np.empty((num_point,2),dtype=np.int) 46 | k=0 47 | for i in range(num_point): 48 | for j in range(2): 49 | dst[i][j]=ref_points[k] 50 | k=k+1 51 | #待对齐图像的点 52 | src=np.empty((num_point,2),dtype=np.int) 53 | k=0 54 | for i in range(num_point): 55 | for j in range(2): 56 | src[i][j]=points[k] 57 | k=k+1 58 | #根据检测到的点,求其相应的仿射变换矩阵 59 | tfrom=tf.estimate_transform('affine',dst,src) 60 | #用opencv的试试,其只能采用三个点,计算矩阵M 61 | # pts1 = np.float32([[src[0][0],src[0][1]],[src[1][0],src[1][1]],[src[2][0],src[2][1]]]) 62 | # pts2 = np.float32([[dst[0][0],dst[0][1]],[dst[1][0],dst[1][1]],[dst[2][0],dst[2][1]]]) 63 | # M = cv2.getAffineTransform(pts2,pts1) 64 | #用最小二乘法的方法进行处理 65 | pts3 = np.float32([[src[0][0],src[0][1]],[src[1][0],src[1][1]],[src[2][0],src[2][1]],[src[3][0],src[3][1]],[src[4][0],src[4][1]]]) 66 | pts4 = np.float32([[dst[0][0],dst[0][1]],[dst[1][0],dst[1][1]],[dst[2][0],dst[2][1]],[dst[3][0],dst[3][1]],[dst[4][0],dst[4][1]]]) 67 | N = compute_affine_transform(pts4,pts3) 68 | # 69 | im=skimage.io.imread(filename) 70 | if im.ndim==3: 71 | rows,cols,ch = im.shape 72 | else: 73 | rows,cols = im.shape 74 | warpimage_cv2 = cv2.warpAffine(im,N,(cols,rows)) 75 | warpimage=tf.warp(im,inverse_map=tfrom) 76 | 77 | return warpimage,warpimage_cv2 78 | 79 | def align_all(filelist,imageRootPath,savePath): 80 | ''' 81 | @breif:对其所有的人脸图像,需要选择参考的图像,默认为第一张 82 | ''' 83 | fid=open(filelist) 84 | for i in range(1): 85 | line=fid.readline() 86 | word=line.split() 87 | print ('reference image:'+imageRootPath+word[0]) 88 | fid.close() 89 | #随机选择一个参考图像和参考点 90 | #todo:人工选择一张比较合适的图像作为参考图像,默认情况下,第一张作为参考图像 91 | ref_points=np.empty((10,1),dtype=np.int) 92 | points=np.empty((10,1),dtype=np.int) 93 | filename=word[0] 94 | for i in range(10): 95 | ref_points[i]=int(word[i+1]) 96 | refimage=skimage.io.imread(imageRootPath+word[0]) 97 | if refimage.ndim==3: 98 | rows,cols,ch = refimage.shape 99 | else: 100 | rows,cols = refimage.shape 101 | #rows,cols,ch = refimage.shape 102 | #为保留数据的完整性,重新扫描 103 | fid=open(filelist,'r') 104 | lines=fid.readlines() 105 | for line in lines: 106 | word=line.split() 107 | filename=word[0] 108 | for j in range(10): 109 | points[j]=int(word[j+1]) 110 | #originimage=skimage.io.imread(imageRootPath+filename) 111 | warpimage,warpimage_cv2=alignment(imageRootPath+filename,points,ref_points) 112 | savename=savePath+filename 113 | #处理多层文件,不能写入的问题,新建文件 114 | dirname, basename = os.path.split(savename) 115 | if not os.path.exists(dirname): 116 | os.makedirs(dirname) 117 | if warpimage_cv2.shape== refimage.shape: 118 | skimage.io.imsave(savename,warpimage_cv2) 119 | else: 120 | if warpimage_cv2.ndim==3: 121 | rows,cols,ch = warpimage_cv2.shape 122 | skimage.io.imsave(savename,warpimage_cv2[0:rows,0:cols,:]) 123 | else: 124 | rows,cols = warpimage_cv2.shape 125 | skimage.io.imsave(savename,warpimage_cv2[0:rows,0:cols]) 126 | 127 | fid.close() 128 | if __name__=='__main__': 129 | imageRootPath=r'F:\Dataset\MORPH' 130 | savePath=r'F:\MyDataset\MORPH\face_aligned_5_points' 131 | fid=open('imageListWithPoints.list','r') 132 | for i in range(2): 133 | line=fid.readline() 134 | word=line.split() 135 | print ('reference image:',word) 136 | fid.close() 137 | 138 | #随机选择一个参考图像和参考点 139 | #todo:人工选择一张比较合适的图像作为参考图像,默认情况下,第一张作为参考图像 140 | ref_points=np.empty((10,1),dtype=np.int) 141 | points=np.empty((10,1),dtype=np.int) 142 | filename=word[0] 143 | for i in range(10): 144 | ref_points[i]=int(word[i+1]) 145 | #while fid.readline()== 146 | refimage=skimage.io.imread(imageRootPath+word[0]) 147 | 148 | plt.subplot(1,3,1) 149 | plt.imshow(refimage) 150 | plt.axis('off') 151 | rows,cols,ch = refimage.shape 152 | 153 | fid=open('imageListWithPoints.list','r') 154 | lines=fid.readlines() 155 | for line in lines: 156 | #for i in range(1000): 157 | #word=fid.readline().split() 158 | word=line.split() 159 | filename=word[0] 160 | for j in range(10): 161 | points[j]=int(word[j+1]) 162 | originimage=skimage.io.imread(imageRootPath+filename) 163 | warpimage,warpimage_cv2=alignment(imageRootPath+filename,points,ref_points) 164 | 165 | # plt.subplot(1,3,2) 166 | # plt.imshow(warpimage) 167 | # plt.axis('off') 168 | # plt.subplot(1,3,3) 169 | # plt.imshow(warpimage_cv2) 170 | # plt.axis('off') 171 | #warpimage=tf.resize(warpimage,(200,200)) 172 | #todo: 处理大小不同图像的输出 173 | if warpimage_cv2.shape== refimage.shape: 174 | skimage.io.imsave(savePath+filename,warpimage_cv2) 175 | else: 176 | skimage.io.imsave(savePath+filename,warpimage_cv2[0:rows,0:cols,:]) 177 | fid.close() -------------------------------------------------------------------------------- /blank.htm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/blank.htm -------------------------------------------------------------------------------- /cleanBoxFile.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sat Jan 10 23:41:55 2015 4 | 5 | @author: Chenriwei 6 | 7 | 功能:处理 Box.txt 文件里面的内容 8 | """ 9 | 10 | import numpy as np 11 | 12 | def retain_max_face(line): 13 | ''' 14 | @param:行内容 15 | @return:返回新的行内容 16 | ''' 17 | word=line.split() 18 | num_detect=len(word)/4 19 | areas=np.empty((num_detect,),dtype=np.int32)#保留的是图像的面积 20 | for i in range(num_detect): 21 | #print int(word[4*i+1]),int(word[4*i+2]),int(word[4*i+3]),int(word[4*i+4]) 22 | areas[i]=(int(word[4*i+2])-int(word[4*i+1]))*(int(word[4*i+4])-int(word[4*i+3])) 23 | print areas[i] 24 | m=np.argmax(areas) 25 | newline=word[0]+' '+word[4*m+1]+' '+word[4*m+2]+' '+word[4*m+3]+' '+word[4*m+4]+'\n' 26 | return newline 27 | 28 | def cleanBoxFile(fileinput="imageBbox.list",detectlistfile="imageBbox_detect.list",misslistfile="imageBbox_miss.list"): 29 | ''' 30 | 清除掉没有检测到的人脸图像,或者检测到多个人脸的图像 31 | 因为只需要考虑单个人脸即可 32 | 对于多个人脸的情况,可以后面再补充进来。 33 | ''' 34 | file0_obj=open(file0,'r') 35 | file1_obj=open(file1,'w') 36 | file2_obj=open(file2,'w') 37 | lines=file0_obj.readlines() 38 | for line in lines: 39 | print line 40 | if line.count(" ")==4: 41 | file1_obj.write(line) 42 | else: 43 | if line.count(" ")>4:#表明有多个人脸被检测到 44 | newline=retain_max_face(line) 45 | file1_obj.write(newline) 46 | else: 47 | file2_obj.write(line) 48 | file0_obj.close() 49 | file1_obj.close() 50 | file2_obj.close() 51 | print 'done!' 52 | if __name__ == "__main__" : 53 | cleanBoxFile() -------------------------------------------------------------------------------- /data/detector_lfp.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/data/detector_lfp.dat -------------------------------------------------------------------------------- /data/svmpostfilter_lfp.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/data/svmpostfilter_lfp.dat -------------------------------------------------------------------------------- /demo0.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/demo0.JPG -------------------------------------------------------------------------------- /demo1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/demo1.JPG -------------------------------------------------------------------------------- /facecrop.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sat May 30 10:26:07 2015 4 | 5 | @author: Chenriwei 6 | """ 7 | from skimage import transform as tf 8 | import numpy as np 9 | import skimage 10 | import os 11 | def face_cropout(srcPath,dstPath,filelist='imageBbox_detect_replace.list',enlarge=True,w=256,h=256): 12 | ''' 13 | @enlarge:是否扩大检测到的人脸图像区域,一般都偏小。 14 | 15 | ''' 16 | fid=open(filelist) 17 | lines=fid.readlines() 18 | fid.close() 19 | for line in lines: 20 | word=line.split() 21 | filename=word[0] 22 | x1=int(word[1]) 23 | x2=int(word[2]) 24 | y1=int(word[3]) 25 | y2=int(word[4]) 26 | 27 | a1=x1 28 | a2=x2 29 | b1=y1 30 | b2=y2 31 | im=skimage.io.imread(srcPath+filename) 32 | if im.ndim==3: 33 | rows,cols,ch = im.shape 34 | else: 35 | rows,cols = im.shape 36 | if enlarge==True: 37 | a1= (x1-(x2-x1)//2) if (x1-(x2-x1)//2)>=0 else 0 38 | b1= (y1-(y2-y1)//2) if (y1-(y2-y1)//2)>=0 else 0 39 | a2= (x2+(x2-x1)//2) if (x2+(x2-x1)//2) 2 | 3 | 4 | 5 | NasFace 6 | 7 | 8 | 9 | 10 | 11 | 12 | <body> 13 | 14 | <p>此网页使用了框架,但您的浏览器不支持框架。</p> 15 | 16 | </body> 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /lib/bootstrap-4.0.0-dist/css/bootstrap-grid.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Grid v4.0.0 (https://getbootstrap.com) 3 | * Copyright 2011-2018 The Bootstrap Authors 4 | * Copyright 2011-2018 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | */@-ms-viewport{width:device-width}html{box-sizing:border-box;-ms-overflow-style:scrollbar}*,::after,::before{box-sizing:inherit}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-sm-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-sm-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-sm-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-sm-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-sm-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-sm-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-sm-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-sm-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-sm-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-sm-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-sm-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-sm-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-sm-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-sm-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-md-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-md-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-md-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-md-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-md-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-md-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-md-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-md-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-md-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-md-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-md-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-md-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-md-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-md-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-lg-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-lg-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-lg-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-lg-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-lg-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-lg-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-lg-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-lg-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-lg-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-lg-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-lg-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-lg-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-lg-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-lg-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-xl-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-xl-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-xl-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-xl-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-xl-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-xl-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-xl-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-xl-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-xl-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-xl-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-xl-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-xl-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-xl-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-xl-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}.flex-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-sm-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-md-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-lg-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-xl-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}} 7 | /*# sourceMappingURL=bootstrap-grid.min.css.map */ -------------------------------------------------------------------------------- /lib/bootstrap-4.0.0-dist/css/bootstrap-reboot.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v4.0.0 (https://getbootstrap.com) 3 | * Copyright 2011-2018 The Bootstrap Authors 4 | * Copyright 2011-2018 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */ 8 | *, 9 | *::before, 10 | *::after { 11 | box-sizing: border-box; 12 | } 13 | 14 | html { 15 | font-family: sans-serif; 16 | line-height: 1.15; 17 | -webkit-text-size-adjust: 100%; 18 | -ms-text-size-adjust: 100%; 19 | -ms-overflow-style: scrollbar; 20 | -webkit-tap-highlight-color: transparent; 21 | } 22 | 23 | @-ms-viewport { 24 | width: device-width; 25 | } 26 | 27 | article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section { 28 | display: block; 29 | } 30 | 31 | body { 32 | margin: 0; 33 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; 34 | font-size: 1rem; 35 | font-weight: 400; 36 | line-height: 1.5; 37 | color: #212529; 38 | text-align: left; 39 | background-color: #fff; 40 | } 41 | 42 | [tabindex="-1"]:focus { 43 | outline: 0 !important; 44 | } 45 | 46 | hr { 47 | box-sizing: content-box; 48 | height: 0; 49 | overflow: visible; 50 | } 51 | 52 | h1, h2, h3, h4, h5, h6 { 53 | margin-top: 0; 54 | margin-bottom: 0.5rem; 55 | } 56 | 57 | p { 58 | margin-top: 0; 59 | margin-bottom: 1rem; 60 | } 61 | 62 | abbr[title], 63 | abbr[data-original-title] { 64 | text-decoration: underline; 65 | -webkit-text-decoration: underline dotted; 66 | text-decoration: underline dotted; 67 | cursor: help; 68 | border-bottom: 0; 69 | } 70 | 71 | address { 72 | margin-bottom: 1rem; 73 | font-style: normal; 74 | line-height: inherit; 75 | } 76 | 77 | ol, 78 | ul, 79 | dl { 80 | margin-top: 0; 81 | margin-bottom: 1rem; 82 | } 83 | 84 | ol ol, 85 | ul ul, 86 | ol ul, 87 | ul ol { 88 | margin-bottom: 0; 89 | } 90 | 91 | dt { 92 | font-weight: 700; 93 | } 94 | 95 | dd { 96 | margin-bottom: .5rem; 97 | margin-left: 0; 98 | } 99 | 100 | blockquote { 101 | margin: 0 0 1rem; 102 | } 103 | 104 | dfn { 105 | font-style: italic; 106 | } 107 | 108 | b, 109 | strong { 110 | font-weight: bolder; 111 | } 112 | 113 | small { 114 | font-size: 80%; 115 | } 116 | 117 | sub, 118 | sup { 119 | position: relative; 120 | font-size: 75%; 121 | line-height: 0; 122 | vertical-align: baseline; 123 | } 124 | 125 | sub { 126 | bottom: -.25em; 127 | } 128 | 129 | sup { 130 | top: -.5em; 131 | } 132 | 133 | a { 134 | color: #007bff; 135 | text-decoration: none; 136 | background-color: transparent; 137 | -webkit-text-decoration-skip: objects; 138 | } 139 | 140 | a:hover { 141 | color: #0056b3; 142 | text-decoration: underline; 143 | } 144 | 145 | a:not([href]):not([tabindex]) { 146 | color: inherit; 147 | text-decoration: none; 148 | } 149 | 150 | a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus { 151 | color: inherit; 152 | text-decoration: none; 153 | } 154 | 155 | a:not([href]):not([tabindex]):focus { 156 | outline: 0; 157 | } 158 | 159 | pre, 160 | code, 161 | kbd, 162 | samp { 163 | font-family: monospace, monospace; 164 | font-size: 1em; 165 | } 166 | 167 | pre { 168 | margin-top: 0; 169 | margin-bottom: 1rem; 170 | overflow: auto; 171 | -ms-overflow-style: scrollbar; 172 | } 173 | 174 | figure { 175 | margin: 0 0 1rem; 176 | } 177 | 178 | img { 179 | vertical-align: middle; 180 | border-style: none; 181 | } 182 | 183 | svg:not(:root) { 184 | overflow: hidden; 185 | } 186 | 187 | table { 188 | border-collapse: collapse; 189 | } 190 | 191 | caption { 192 | padding-top: 0.75rem; 193 | padding-bottom: 0.75rem; 194 | color: #6c757d; 195 | text-align: left; 196 | caption-side: bottom; 197 | } 198 | 199 | th { 200 | text-align: inherit; 201 | } 202 | 203 | label { 204 | display: inline-block; 205 | margin-bottom: .5rem; 206 | } 207 | 208 | button { 209 | border-radius: 0; 210 | } 211 | 212 | button:focus { 213 | outline: 1px dotted; 214 | outline: 5px auto -webkit-focus-ring-color; 215 | } 216 | 217 | input, 218 | button, 219 | select, 220 | optgroup, 221 | textarea { 222 | margin: 0; 223 | font-family: inherit; 224 | font-size: inherit; 225 | line-height: inherit; 226 | } 227 | 228 | button, 229 | input { 230 | overflow: visible; 231 | } 232 | 233 | button, 234 | select { 235 | text-transform: none; 236 | } 237 | 238 | button, 239 | html [type="button"], 240 | [type="reset"], 241 | [type="submit"] { 242 | -webkit-appearance: button; 243 | } 244 | 245 | button::-moz-focus-inner, 246 | [type="button"]::-moz-focus-inner, 247 | [type="reset"]::-moz-focus-inner, 248 | [type="submit"]::-moz-focus-inner { 249 | padding: 0; 250 | border-style: none; 251 | } 252 | 253 | input[type="radio"], 254 | input[type="checkbox"] { 255 | box-sizing: border-box; 256 | padding: 0; 257 | } 258 | 259 | input[type="date"], 260 | input[type="time"], 261 | input[type="datetime-local"], 262 | input[type="month"] { 263 | -webkit-appearance: listbox; 264 | } 265 | 266 | textarea { 267 | overflow: auto; 268 | resize: vertical; 269 | } 270 | 271 | fieldset { 272 | min-width: 0; 273 | padding: 0; 274 | margin: 0; 275 | border: 0; 276 | } 277 | 278 | legend { 279 | display: block; 280 | width: 100%; 281 | max-width: 100%; 282 | padding: 0; 283 | margin-bottom: .5rem; 284 | font-size: 1.5rem; 285 | line-height: inherit; 286 | color: inherit; 287 | white-space: normal; 288 | } 289 | 290 | progress { 291 | vertical-align: baseline; 292 | } 293 | 294 | [type="number"]::-webkit-inner-spin-button, 295 | [type="number"]::-webkit-outer-spin-button { 296 | height: auto; 297 | } 298 | 299 | [type="search"] { 300 | outline-offset: -2px; 301 | -webkit-appearance: none; 302 | } 303 | 304 | [type="search"]::-webkit-search-cancel-button, 305 | [type="search"]::-webkit-search-decoration { 306 | -webkit-appearance: none; 307 | } 308 | 309 | ::-webkit-file-upload-button { 310 | font: inherit; 311 | -webkit-appearance: button; 312 | } 313 | 314 | output { 315 | display: inline-block; 316 | } 317 | 318 | summary { 319 | display: list-item; 320 | cursor: pointer; 321 | } 322 | 323 | template { 324 | display: none; 325 | } 326 | 327 | [hidden] { 328 | display: none !important; 329 | } 330 | /*# sourceMappingURL=bootstrap-reboot.css.map */ -------------------------------------------------------------------------------- /lib/bootstrap-4.0.0-dist/css/bootstrap-reboot.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v4.0.0 (https://getbootstrap.com) 3 | * Copyright 2011-2018 The Bootstrap Authors 4 | * Copyright 2011-2018 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important} 8 | /*# sourceMappingURL=bootstrap-reboot.min.css.map */ -------------------------------------------------------------------------------- /lib/bootstrap-4.0.0-dist/css/bootstrap-reboot.min.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../../scss/bootstrap-reboot.scss","../../scss/_reboot.scss","dist/css/bootstrap-reboot.css","bootstrap-reboot.css","../../scss/mixins/_hover.scss"],"names":[],"mappings":"AAAA;;;;;;ACoBA,ECXA,QADA,SDeE,WAAA,WAGF,KACE,YAAA,WACA,YAAA,KACA,yBAAA,KACA,qBAAA,KACA,mBAAA,UACA,4BAAA,YAKA,cACE,MAAA,aAMJ,QAAA,MAAA,OAAA,WAAA,OAAA,OAAA,OAAA,OAAA,KAAA,IAAA,QACE,QAAA,MAWF,KACE,OAAA,EACA,YAAA,aAAA,CAAA,kBAAA,CAAA,UAAA,CAAA,MAAA,CAAA,gBAAA,CAAA,KAAA,CAAA,UAAA,CAAA,mBAAA,CAAA,gBAAA,CAAA,kBACA,UAAA,KACA,YAAA,IACA,YAAA,IACA,MAAA,QACA,WAAA,KACA,iBAAA,KEvBF,sBFgCE,QAAA,YASF,GACE,WAAA,YACA,OAAA,EACA,SAAA,QAaF,GAAA,GAAA,GAAA,GAAA,GAAA,GACE,WAAA,EACA,cAAA,MAQF,EACE,WAAA,EACA,cAAA,KChDF,0BD0DA,YAEE,gBAAA,UACA,wBAAA,UAAA,OAAA,gBAAA,UAAA,OACA,OAAA,KACA,cAAA,EAGF,QACE,cAAA,KACA,WAAA,OACA,YAAA,QCrDF,GDwDA,GCzDA,GD4DE,WAAA,EACA,cAAA,KAGF,MCxDA,MACA,MAFA,MD6DE,cAAA,EAGF,GACE,YAAA,IAGF,GACE,cAAA,MACA,YAAA,EAGF,WACE,OAAA,EAAA,EAAA,KAGF,IACE,WAAA,OAIF,EC1DA,OD4DE,YAAA,OAIF,MACE,UAAA,IAQF,IChEA,IDkEE,SAAA,SACA,UAAA,IACA,YAAA,EACA,eAAA,SAGF,IAAM,OAAA,OACN,IAAM,IAAA,MAON,EACE,MAAA,QACA,gBAAA,KACA,iBAAA,YACA,6BAAA,QG3LA,QH8LE,MAAA,QACA,gBAAA,UAUJ,8BACE,MAAA,QACA,gBAAA,KGvMA,oCAAA,oCH0ME,MAAA,QACA,gBAAA,KANJ,oCAUI,QAAA,EClEJ,KACA,ID2EA,IC1EA,KD8EE,YAAA,SAAA,CAAA,UACA,UAAA,IAIF,IAEE,WAAA,EAEA,cAAA,KAEA,SAAA,KAGA,mBAAA,UAQF,OAEE,OAAA,EAAA,EAAA,KAQF,IACE,eAAA,OACA,aAAA,KAGF,eACE,SAAA,OAQF,MACE,gBAAA,SAGF,QACE,YAAA,OACA,eAAA,OACA,MAAA,QACA,WAAA,KACA,aAAA,OAGF,GAGE,WAAA,QAQF,MAEE,QAAA,aACA,cAAA,MAMF,OACE,cAAA,EAOF,aACE,QAAA,IAAA,OACA,QAAA,IAAA,KAAA,yBC9GF,ODiHA,MC/GA,SADA,OAEA,SDmHE,OAAA,EACA,YAAA,QACA,UAAA,QACA,YAAA,QAGF,OCjHA,MDmHE,SAAA,QAGF,OCjHA,ODmHE,eAAA,KC7GF,aACA,cDkHA,OCpHA,mBDwHE,mBAAA,OCjHF,gCACA,+BACA,gCDmHA,yBAIE,QAAA,EACA,aAAA,KClHF,qBDqHA,kBAEE,WAAA,WACA,QAAA,EAIF,iBCrHA,2BACA,kBAFA,iBD+HE,mBAAA,QAGF,SACE,SAAA,KAEA,OAAA,SAGF,SAME,UAAA,EAEA,QAAA,EACA,OAAA,EACA,OAAA,EAKF,OACE,QAAA,MACA,MAAA,KACA,UAAA,KACA,QAAA,EACA,cAAA,MACA,UAAA,OACA,YAAA,QACA,MAAA,QACA,YAAA,OAGF,SACE,eAAA,SEnIF,yCDEA,yCDuIE,OAAA,KEpIF,cF4IE,eAAA,KACA,mBAAA,KExIF,4CDEA,yCD+IE,mBAAA,KAQF,6BACE,KAAA,QACA,mBAAA,OAOF,OACE,QAAA,aAGF,QACE,QAAA,UACA,OAAA,QAGF,SACE,QAAA,KErJF,SF2JE,QAAA","sourcesContent":["/*!\n * Bootstrap Reboot v4.0.0 (https://getbootstrap.com)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n\n@import \"functions\";\n@import \"variables\";\n@import \"mixins\";\n@import \"reboot\";\n","// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix\n\n// Reboot\n//\n// Normalization of HTML elements, manually forked from Normalize.css to remove\n// styles targeting irrelevant browsers while applying new styles.\n//\n// Normalize is licensed MIT. https://github.com/necolas/normalize.css\n\n\n// Document\n//\n// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.\n// 2. Change the default font family in all browsers.\n// 3. Correct the line height in all browsers.\n// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.\n// 5. Setting @viewport causes scrollbars to overlap content in IE11 and Edge, so\n// we force a non-overlapping, non-auto-hiding scrollbar to counteract.\n// 6. Change the default tap highlight to be completely transparent in iOS.\n\n*,\n*::before,\n*::after {\n box-sizing: border-box; // 1\n}\n\nhtml {\n font-family: sans-serif; // 2\n line-height: 1.15; // 3\n -webkit-text-size-adjust: 100%; // 4\n -ms-text-size-adjust: 100%; // 4\n -ms-overflow-style: scrollbar; // 5\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0); // 6\n}\n\n// IE10+ doesn't honor `` in some cases.\n@at-root {\n @-ms-viewport {\n width: device-width;\n }\n}\n\n// stylelint-disable selector-list-comma-newline-after\n// Shim for \"new\" HTML5 structural elements to display correctly (IE10, older browsers)\narticle, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n// stylelint-enable selector-list-comma-newline-after\n\n// Body\n//\n// 1. Remove the margin in all browsers.\n// 2. As a best practice, apply a default `background-color`.\n// 3. Set an explicit initial text-align value so that we can later use the\n// the `inherit` value on things like `` elements.\n\nbody {\n margin: 0; // 1\n font-family: $font-family-base;\n font-size: $font-size-base;\n font-weight: $font-weight-base;\n line-height: $line-height-base;\n color: $body-color;\n text-align: left; // 3\n background-color: $body-bg; // 2\n}\n\n// Suppress the focus outline on elements that cannot be accessed via keyboard.\n// This prevents an unwanted focus outline from appearing around elements that\n// might still respond to pointer events.\n//\n// Credit: https://github.com/suitcss/base\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\n\n// Content grouping\n//\n// 1. Add the correct box sizing in Firefox.\n// 2. Show the overflow in Edge and IE.\n\nhr {\n box-sizing: content-box; // 1\n height: 0; // 1\n overflow: visible; // 2\n}\n\n\n//\n// Typography\n//\n\n// Remove top margins from headings\n//\n// By default, `

`-`

` all receive top and bottom margins. We nuke the top\n// margin for easier control within type scales as it avoids margin collapsing.\n// stylelint-disable selector-list-comma-newline-after\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: $headings-margin-bottom;\n}\n// stylelint-enable selector-list-comma-newline-after\n\n// Reset margins on paragraphs\n//\n// Similarly, the top margin on `

`s get reset. However, we also reset the\n// bottom margin to use `rem` units instead of `em`.\np {\n margin-top: 0;\n margin-bottom: $paragraph-margin-bottom;\n}\n\n// Abbreviations\n//\n// 1. Remove the bottom border in Firefox 39-.\n// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n// 3. Add explicit cursor to indicate changed behavior.\n// 4. Duplicate behavior to the data-* attribute for our tooltip plugin\n\nabbr[title],\nabbr[data-original-title] { // 4\n text-decoration: underline; // 2\n text-decoration: underline dotted; // 2\n cursor: help; // 3\n border-bottom: 0; // 1\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: $dt-font-weight;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0; // Undo browser default\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic; // Add the correct font style in Android 4.3-\n}\n\n// stylelint-disable font-weight-notation\nb,\nstrong {\n font-weight: bolder; // Add the correct font weight in Chrome, Edge, and Safari\n}\n// stylelint-enable font-weight-notation\n\nsmall {\n font-size: 80%; // Add the correct font size in all browsers\n}\n\n//\n// Prevent `sub` and `sup` elements from affecting the line height in\n// all browsers.\n//\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub { bottom: -.25em; }\nsup { top: -.5em; }\n\n\n//\n// Links\n//\n\na {\n color: $link-color;\n text-decoration: $link-decoration;\n background-color: transparent; // Remove the gray background on active links in IE 10.\n -webkit-text-decoration-skip: objects; // Remove gaps in links underline in iOS 8+ and Safari 8+.\n\n @include hover {\n color: $link-hover-color;\n text-decoration: $link-hover-decoration;\n }\n}\n\n// And undo these styles for placeholder links/named anchors (without href)\n// which have not been made explicitly keyboard-focusable (without tabindex).\n// It would be more straightforward to just use a[href] in previous block, but that\n// causes specificity issues in many other styles that are too complex to fix.\n// See https://github.com/twbs/bootstrap/issues/19402\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n\n @include hover-focus {\n color: inherit;\n text-decoration: none;\n }\n\n &:focus {\n outline: 0;\n }\n}\n\n\n//\n// Code\n//\n\n// stylelint-disable font-family-no-duplicate-names\npre,\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; // Correct the inheritance and scaling of font size in all browsers.\n font-size: 1em; // Correct the odd `em` font sizing in all browsers.\n}\n// stylelint-enable font-family-no-duplicate-names\n\npre {\n // Remove browser default top margin\n margin-top: 0;\n // Reset browser default of `1em` to use `rem`s\n margin-bottom: 1rem;\n // Don't allow content to break outside\n overflow: auto;\n // We have @viewport set which causes scrollbars to overlap content in IE11 and Edge, so\n // we force a non-overlapping, non-auto-hiding scrollbar to counteract.\n -ms-overflow-style: scrollbar;\n}\n\n\n//\n// Figures\n//\n\nfigure {\n // Apply a consistent margin strategy (matches our type styles).\n margin: 0 0 1rem;\n}\n\n\n//\n// Images and content\n//\n\nimg {\n vertical-align: middle;\n border-style: none; // Remove the border on images inside links in IE 10-.\n}\n\nsvg:not(:root) {\n overflow: hidden; // Hide the overflow in IE\n}\n\n\n//\n// Tables\n//\n\ntable {\n border-collapse: collapse; // Prevent double borders\n}\n\ncaption {\n padding-top: $table-cell-padding;\n padding-bottom: $table-cell-padding;\n color: $text-muted;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n // Matches default `` alignment by inheriting from the ``, or the\n // closest parent with a set `text-align`.\n text-align: inherit;\n}\n\n\n//\n// Forms\n//\n\nlabel {\n // Allow labels to use `margin` for spacing.\n display: inline-block;\n margin-bottom: .5rem;\n}\n\n// Remove the default `border-radius` that macOS Chrome adds.\n//\n// Details at https://github.com/twbs/bootstrap/issues/24093\nbutton {\n border-radius: 0;\n}\n\n// Work around a Firefox/IE bug where the transparent `button` background\n// results in a loss of the default `button` focus styles.\n//\n// Credit: https://github.com/suitcss/base/\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0; // Remove the margin in Firefox and Safari\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible; // Show the overflow in Edge\n}\n\nbutton,\nselect {\n text-transform: none; // Remove the inheritance of text transform in Firefox\n}\n\n// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`\n// controls in Android 4.\n// 2. Correct the inability to style clickable types in iOS and Safari.\nbutton,\nhtml [type=\"button\"], // 1\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button; // 2\n}\n\n// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box; // 1. Add the correct box sizing in IE 10-\n padding: 0; // 2. Remove the padding in IE 10-\n}\n\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n // Remove the default appearance of temporal inputs to avoid a Mobile Safari\n // bug where setting a custom line-height prevents text from being vertically\n // centered within the input.\n // See https://bugs.webkit.org/show_bug.cgi?id=139848\n // and https://github.com/twbs/bootstrap/issues/11266\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto; // Remove the default vertical scrollbar in IE.\n // Textareas should really only resize vertically so they don't break their (horizontal) containers.\n resize: vertical;\n}\n\nfieldset {\n // Browsers set a default `min-width: min-content;` on fieldsets,\n // unlike e.g. `

`s, which have `min-width: 0;` by default.\n // So we reset that to ensure fieldsets behave more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359\n // and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements\n min-width: 0;\n // Reset the default outline behavior of fieldsets so they don't affect page layout.\n padding: 0;\n margin: 0;\n border: 0;\n}\n\n// 1. Correct the text wrapping in Edge and IE.\n// 2. Correct the color inheritance from `fieldset` elements in IE.\nlegend {\n display: block;\n width: 100%;\n max-width: 100%; // 1\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit; // 2\n white-space: normal; // 1\n}\n\nprogress {\n vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.\n}\n\n// Correct the cursor style of increment and decrement buttons in Chrome.\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n // This overrides the extra rounded corners on search inputs in iOS so that our\n // `.form-control` class can properly style them. Note that this cannot simply\n // be added to `.form-control` as it's not specific enough. For details, see\n // https://github.com/twbs/bootstrap/issues/11586.\n outline-offset: -2px; // 2. Correct the outline style in Safari.\n -webkit-appearance: none;\n}\n\n//\n// Remove the inner padding and cancel buttons in Chrome and Safari on macOS.\n//\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// 1. Correct the inability to style clickable types in iOS and Safari.\n// 2. Change font properties to `inherit` in Safari.\n//\n\n::-webkit-file-upload-button {\n font: inherit; // 2\n -webkit-appearance: button; // 1\n}\n\n//\n// Correct element displays\n//\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item; // Add the correct display in all browsers\n cursor: pointer;\n}\n\ntemplate {\n display: none; // Add the correct display in IE\n}\n\n// Always hide an element with the `hidden` HTML attribute (from PureCSS).\n// Needed for proper display in IE 10-.\n[hidden] {\n display: none !important;\n}\n","/*!\n * Bootstrap Reboot v4.0.0 (https://getbootstrap.com)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n -ms-overflow-style: scrollbar;\n -webkit-tap-highlight-color: transparent;\n}\n\n@-ms-viewport {\n width: device-width;\n}\n\narticle, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n -webkit-text-decoration-skip: objects;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: .5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nbutton,\nhtml [type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n/*# sourceMappingURL=bootstrap-reboot.css.map */","/*!\n * Bootstrap Reboot v4.0.0 (https://getbootstrap.com)\n * Copyright 2011-2018 The Bootstrap Authors\n * Copyright 2011-2018 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)\n */\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nhtml {\n font-family: sans-serif;\n line-height: 1.15;\n -webkit-text-size-adjust: 100%;\n -ms-text-size-adjust: 100%;\n -ms-overflow-style: scrollbar;\n -webkit-tap-highlight-color: transparent;\n}\n\n@-ms-viewport {\n width: device-width;\n}\n\narticle, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {\n display: block;\n}\n\nbody {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n font-size: 1rem;\n font-weight: 400;\n line-height: 1.5;\n color: #212529;\n text-align: left;\n background-color: #fff;\n}\n\n[tabindex=\"-1\"]:focus {\n outline: 0 !important;\n}\n\nhr {\n box-sizing: content-box;\n height: 0;\n overflow: visible;\n}\n\nh1, h2, h3, h4, h5, h6 {\n margin-top: 0;\n margin-bottom: 0.5rem;\n}\n\np {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nabbr[title],\nabbr[data-original-title] {\n text-decoration: underline;\n text-decoration: underline dotted;\n cursor: help;\n border-bottom: 0;\n}\n\naddress {\n margin-bottom: 1rem;\n font-style: normal;\n line-height: inherit;\n}\n\nol,\nul,\ndl {\n margin-top: 0;\n margin-bottom: 1rem;\n}\n\nol ol,\nul ul,\nol ul,\nul ol {\n margin-bottom: 0;\n}\n\ndt {\n font-weight: 700;\n}\n\ndd {\n margin-bottom: .5rem;\n margin-left: 0;\n}\n\nblockquote {\n margin: 0 0 1rem;\n}\n\ndfn {\n font-style: italic;\n}\n\nb,\nstrong {\n font-weight: bolder;\n}\n\nsmall {\n font-size: 80%;\n}\n\nsub,\nsup {\n position: relative;\n font-size: 75%;\n line-height: 0;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -.25em;\n}\n\nsup {\n top: -.5em;\n}\n\na {\n color: #007bff;\n text-decoration: none;\n background-color: transparent;\n -webkit-text-decoration-skip: objects;\n}\n\na:hover {\n color: #0056b3;\n text-decoration: underline;\n}\n\na:not([href]):not([tabindex]) {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus {\n color: inherit;\n text-decoration: none;\n}\n\na:not([href]):not([tabindex]):focus {\n outline: 0;\n}\n\npre,\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\npre {\n margin-top: 0;\n margin-bottom: 1rem;\n overflow: auto;\n -ms-overflow-style: scrollbar;\n}\n\nfigure {\n margin: 0 0 1rem;\n}\n\nimg {\n vertical-align: middle;\n border-style: none;\n}\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\ntable {\n border-collapse: collapse;\n}\n\ncaption {\n padding-top: 0.75rem;\n padding-bottom: 0.75rem;\n color: #6c757d;\n text-align: left;\n caption-side: bottom;\n}\n\nth {\n text-align: inherit;\n}\n\nlabel {\n display: inline-block;\n margin-bottom: .5rem;\n}\n\nbutton {\n border-radius: 0;\n}\n\nbutton:focus {\n outline: 1px dotted;\n outline: 5px auto -webkit-focus-ring-color;\n}\n\ninput,\nbutton,\nselect,\noptgroup,\ntextarea {\n margin: 0;\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\nbutton,\ninput {\n overflow: visible;\n}\n\nbutton,\nselect {\n text-transform: none;\n}\n\nbutton,\nhtml [type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n padding: 0;\n border-style: none;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n box-sizing: border-box;\n padding: 0;\n}\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n -webkit-appearance: listbox;\n}\n\ntextarea {\n overflow: auto;\n resize: vertical;\n}\n\nfieldset {\n min-width: 0;\n padding: 0;\n margin: 0;\n border: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n max-width: 100%;\n padding: 0;\n margin-bottom: .5rem;\n font-size: 1.5rem;\n line-height: inherit;\n color: inherit;\n white-space: normal;\n}\n\nprogress {\n vertical-align: baseline;\n}\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n[type=\"search\"] {\n outline-offset: -2px;\n -webkit-appearance: none;\n}\n\n[type=\"search\"]::-webkit-search-cancel-button,\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n::-webkit-file-upload-button {\n font: inherit;\n -webkit-appearance: button;\n}\n\noutput {\n display: inline-block;\n}\n\nsummary {\n display: list-item;\n cursor: pointer;\n}\n\ntemplate {\n display: none;\n}\n\n[hidden] {\n display: none !important;\n}\n\n/*# sourceMappingURL=bootstrap-reboot.css.map */","// stylelint-disable indentation\n\n// Hover mixin and `$enable-hover-media-query` are deprecated.\n//\n// Origally added during our alphas and maintained during betas, this mixin was\n// designed to prevent `:hover` stickiness on iOS—an issue where hover styles\n// would persist after initial touch.\n//\n// For backward compatibility, we've kept these mixins and updated them to\n// always return their regular psuedo-classes instead of a shimmed media query.\n//\n// Issue: https://github.com/twbs/bootstrap/issues/25195\n\n@mixin hover {\n &:hover { @content; }\n}\n\n@mixin hover-focus {\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin plain-hover-focus {\n &,\n &:hover,\n &:focus {\n @content;\n }\n}\n\n@mixin hover-focus-active {\n &:hover,\n &:focus,\n &:active {\n @content;\n }\n}\n"]} -------------------------------------------------------------------------------- /lib/bootstrap-4.0.0-dist/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v4.0.0 (https://getbootstrap.com) 3 | * Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e(t.bootstrap={},t.jQuery,t.Popper)}(this,function(t,e,n){"use strict";function i(t,e){for(var n=0;n0?i:null}catch(t){return null}},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(n){t(n).trigger(e.end)},supportsTransitionEnd:function(){return Boolean(e)},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var s in n)if(Object.prototype.hasOwnProperty.call(n,s)){var r=n[s],o=e[s],a=o&&i.isElement(o)?"element":(l=o,{}.toString.call(l).match(/\s([a-zA-Z]+)/)[1].toLowerCase());if(!new RegExp(r).test(a))throw new Error(t.toUpperCase()+': Option "'+s+'" provided type "'+a+'" but expected type "'+r+'".')}var l}};return e=("undefined"==typeof window||!window.QUnit)&&{end:"transitionend"},t.fn.emulateTransitionEnd=n,i.supportsTransitionEnd()&&(t.event.special[i.TRANSITION_END]={bindType:e.end,delegateType:e.end,handle:function(e){if(t(e.target).is(this))return e.handleObj.handler.apply(this,arguments)}}),i}(e),L=(a="alert",h="."+(l="bs.alert"),c=(o=e).fn[a],u={CLOSE:"close"+h,CLOSED:"closed"+h,CLICK_DATA_API:"click"+h+".data-api"},f="alert",d="fade",_="show",g=function(){function t(t){this._element=t}var e=t.prototype;return e.close=function(t){t=t||this._element;var e=this._getRootElement(t);this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){o.removeData(this._element,l),this._element=null},e._getRootElement=function(t){var e=P.getSelectorFromElement(t),n=!1;return e&&(n=o(e)[0]),n||(n=o(t).closest("."+f)[0]),n},e._triggerCloseEvent=function(t){var e=o.Event(u.CLOSE);return o(t).trigger(e),e},e._removeElement=function(t){var e=this;o(t).removeClass(_),P.supportsTransitionEnd()&&o(t).hasClass(d)?o(t).one(P.TRANSITION_END,function(n){return e._destroyElement(t,n)}).emulateTransitionEnd(150):this._destroyElement(t)},e._destroyElement=function(t){o(t).detach().trigger(u.CLOSED).remove()},t._jQueryInterface=function(e){return this.each(function(){var n=o(this),i=n.data(l);i||(i=new t(this),n.data(l,i)),"close"===e&&i[e](this)})},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},s(t,null,[{key:"VERSION",get:function(){return"4.0.0"}}]),t}(),o(document).on(u.CLICK_DATA_API,'[data-dismiss="alert"]',g._handleDismiss(new g)),o.fn[a]=g._jQueryInterface,o.fn[a].Constructor=g,o.fn[a].noConflict=function(){return o.fn[a]=c,g._jQueryInterface},g),R=(m="button",E="."+(v="bs.button"),T=".data-api",y=(p=e).fn[m],C="active",I="btn",A="focus",b='[data-toggle^="button"]',D='[data-toggle="buttons"]',S="input",w=".active",N=".btn",O={CLICK_DATA_API:"click"+E+T,FOCUS_BLUR_DATA_API:"focus"+E+T+" blur"+E+T},k=function(){function t(t){this._element=t}var e=t.prototype;return e.toggle=function(){var t=!0,e=!0,n=p(this._element).closest(D)[0];if(n){var i=p(this._element).find(S)[0];if(i){if("radio"===i.type)if(i.checked&&p(this._element).hasClass(C))t=!1;else{var s=p(n).find(w)[0];s&&p(s).removeClass(C)}if(t){if(i.hasAttribute("disabled")||n.hasAttribute("disabled")||i.classList.contains("disabled")||n.classList.contains("disabled"))return;i.checked=!p(this._element).hasClass(C),p(i).trigger("change")}i.focus(),e=!1}}e&&this._element.setAttribute("aria-pressed",!p(this._element).hasClass(C)),t&&p(this._element).toggleClass(C)},e.dispose=function(){p.removeData(this._element,v),this._element=null},t._jQueryInterface=function(e){return this.each(function(){var n=p(this).data(v);n||(n=new t(this),p(this).data(v,n)),"toggle"===e&&n[e]()})},s(t,null,[{key:"VERSION",get:function(){return"4.0.0"}}]),t}(),p(document).on(O.CLICK_DATA_API,b,function(t){t.preventDefault();var e=t.target;p(e).hasClass(I)||(e=p(e).closest(N)),k._jQueryInterface.call(p(e),"toggle")}).on(O.FOCUS_BLUR_DATA_API,b,function(t){var e=p(t.target).closest(N)[0];p(e).toggleClass(A,/^focus(in)?$/.test(t.type))}),p.fn[m]=k._jQueryInterface,p.fn[m].Constructor=k,p.fn[m].noConflict=function(){return p.fn[m]=y,k._jQueryInterface},k),j=function(t){var e="carousel",n="bs.carousel",i="."+n,o=t.fn[e],a={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0},l={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean"},h="next",c="prev",u="left",f="right",d={SLIDE:"slide"+i,SLID:"slid"+i,KEYDOWN:"keydown"+i,MOUSEENTER:"mouseenter"+i,MOUSELEAVE:"mouseleave"+i,TOUCHEND:"touchend"+i,LOAD_DATA_API:"load"+i+".data-api",CLICK_DATA_API:"click"+i+".data-api"},_="carousel",g="active",p="slide",m="carousel-item-right",v="carousel-item-left",E="carousel-item-next",T="carousel-item-prev",y={ACTIVE:".active",ACTIVE_ITEM:".active.carousel-item",ITEM:".carousel-item",NEXT_PREV:".carousel-item-next, .carousel-item-prev",INDICATORS:".carousel-indicators",DATA_SLIDE:"[data-slide], [data-slide-to]",DATA_RIDE:'[data-ride="carousel"]'},C=function(){function o(e,n){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this._config=this._getConfig(n),this._element=t(e)[0],this._indicatorsElement=t(this._element).find(y.INDICATORS)[0],this._addEventListeners()}var C=o.prototype;return C.next=function(){this._isSliding||this._slide(h)},C.nextWhenVisible=function(){!document.hidden&&t(this._element).is(":visible")&&"hidden"!==t(this._element).css("visibility")&&this.next()},C.prev=function(){this._isSliding||this._slide(c)},C.pause=function(e){e||(this._isPaused=!0),t(this._element).find(y.NEXT_PREV)[0]&&P.supportsTransitionEnd()&&(P.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},C.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},C.to=function(e){var n=this;this._activeElement=t(this._element).find(y.ACTIVE_ITEM)[0];var i=this._getItemIndex(this._activeElement);if(!(e>this._items.length-1||e<0))if(this._isSliding)t(this._element).one(d.SLID,function(){return n.to(e)});else{if(i===e)return this.pause(),void this.cycle();var s=e>i?h:c;this._slide(s,this._items[e])}},C.dispose=function(){t(this._element).off(i),t.removeData(this._element,n),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},C._getConfig=function(t){return t=r({},a,t),P.typeCheckConfig(e,t,l),t},C._addEventListeners=function(){var e=this;this._config.keyboard&&t(this._element).on(d.KEYDOWN,function(t){return e._keydown(t)}),"hover"===this._config.pause&&(t(this._element).on(d.MOUSEENTER,function(t){return e.pause(t)}).on(d.MOUSELEAVE,function(t){return e.cycle(t)}),"ontouchstart"in document.documentElement&&t(this._element).on(d.TOUCHEND,function(){e.pause(),e.touchTimeout&&clearTimeout(e.touchTimeout),e.touchTimeout=setTimeout(function(t){return e.cycle(t)},500+e._config.interval)}))},C._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},C._getItemIndex=function(e){return this._items=t.makeArray(t(e).parent().find(y.ITEM)),this._items.indexOf(e)},C._getItemByDirection=function(t,e){var n=t===h,i=t===c,s=this._getItemIndex(e),r=this._items.length-1;if((i&&0===s||n&&s===r)&&!this._config.wrap)return e;var o=(s+(t===c?-1:1))%this._items.length;return-1===o?this._items[this._items.length-1]:this._items[o]},C._triggerSlideEvent=function(e,n){var i=this._getItemIndex(e),s=this._getItemIndex(t(this._element).find(y.ACTIVE_ITEM)[0]),r=t.Event(d.SLIDE,{relatedTarget:e,direction:n,from:s,to:i});return t(this._element).trigger(r),r},C._setActiveIndicatorElement=function(e){if(this._indicatorsElement){t(this._indicatorsElement).find(y.ACTIVE).removeClass(g);var n=this._indicatorsElement.children[this._getItemIndex(e)];n&&t(n).addClass(g)}},C._slide=function(e,n){var i,s,r,o=this,a=t(this._element).find(y.ACTIVE_ITEM)[0],l=this._getItemIndex(a),c=n||a&&this._getItemByDirection(e,a),_=this._getItemIndex(c),C=Boolean(this._interval);if(e===h?(i=v,s=E,r=u):(i=m,s=T,r=f),c&&t(c).hasClass(g))this._isSliding=!1;else if(!this._triggerSlideEvent(c,r).isDefaultPrevented()&&a&&c){this._isSliding=!0,C&&this.pause(),this._setActiveIndicatorElement(c);var I=t.Event(d.SLID,{relatedTarget:c,direction:r,from:l,to:_});P.supportsTransitionEnd()&&t(this._element).hasClass(p)?(t(c).addClass(s),P.reflow(c),t(a).addClass(i),t(c).addClass(i),t(a).one(P.TRANSITION_END,function(){t(c).removeClass(i+" "+s).addClass(g),t(a).removeClass(g+" "+s+" "+i),o._isSliding=!1,setTimeout(function(){return t(o._element).trigger(I)},0)}).emulateTransitionEnd(600)):(t(a).removeClass(g),t(c).addClass(g),this._isSliding=!1,t(this._element).trigger(I)),C&&this.cycle()}},o._jQueryInterface=function(e){return this.each(function(){var i=t(this).data(n),s=r({},a,t(this).data());"object"==typeof e&&(s=r({},s,e));var l="string"==typeof e?e:s.slide;if(i||(i=new o(this,s),t(this).data(n,i)),"number"==typeof e)i.to(e);else if("string"==typeof l){if("undefined"==typeof i[l])throw new TypeError('No method named "'+l+'"');i[l]()}else s.interval&&(i.pause(),i.cycle())})},o._dataApiClickHandler=function(e){var i=P.getSelectorFromElement(this);if(i){var s=t(i)[0];if(s&&t(s).hasClass(_)){var a=r({},t(s).data(),t(this).data()),l=this.getAttribute("data-slide-to");l&&(a.interval=!1),o._jQueryInterface.call(t(s),a),l&&t(s).data(n).to(l),e.preventDefault()}}},s(o,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return a}}]),o}();return t(document).on(d.CLICK_DATA_API,y.DATA_SLIDE,C._dataApiClickHandler),t(window).on(d.LOAD_DATA_API,function(){t(y.DATA_RIDE).each(function(){var e=t(this);C._jQueryInterface.call(e,e.data())})}),t.fn[e]=C._jQueryInterface,t.fn[e].Constructor=C,t.fn[e].noConflict=function(){return t.fn[e]=o,C._jQueryInterface},C}(e),H=function(t){var e="collapse",n="bs.collapse",i="."+n,o=t.fn[e],a={toggle:!0,parent:""},l={toggle:"boolean",parent:"(string|element)"},h={SHOW:"show"+i,SHOWN:"shown"+i,HIDE:"hide"+i,HIDDEN:"hidden"+i,CLICK_DATA_API:"click"+i+".data-api"},c="show",u="collapse",f="collapsing",d="collapsed",_="width",g="height",p={ACTIVES:".show, .collapsing",DATA_TOGGLE:'[data-toggle="collapse"]'},m=function(){function i(e,n){this._isTransitioning=!1,this._element=e,this._config=this._getConfig(n),this._triggerArray=t.makeArray(t('[data-toggle="collapse"][href="#'+e.id+'"],[data-toggle="collapse"][data-target="#'+e.id+'"]'));for(var i=t(p.DATA_TOGGLE),s=0;s0&&(this._selector=o,this._triggerArray.push(r))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var o=i.prototype;return o.toggle=function(){t(this._element).hasClass(c)?this.hide():this.show()},o.show=function(){var e,s,r=this;if(!this._isTransitioning&&!t(this._element).hasClass(c)&&(this._parent&&0===(e=t.makeArray(t(this._parent).find(p.ACTIVES).filter('[data-parent="'+this._config.parent+'"]'))).length&&(e=null),!(e&&(s=t(e).not(this._selector).data(n))&&s._isTransitioning))){var o=t.Event(h.SHOW);if(t(this._element).trigger(o),!o.isDefaultPrevented()){e&&(i._jQueryInterface.call(t(e).not(this._selector),"hide"),s||t(e).data(n,null));var a=this._getDimension();t(this._element).removeClass(u).addClass(f),this._element.style[a]=0,this._triggerArray.length>0&&t(this._triggerArray).removeClass(d).attr("aria-expanded",!0),this.setTransitioning(!0);var l=function(){t(r._element).removeClass(f).addClass(u).addClass(c),r._element.style[a]="",r.setTransitioning(!1),t(r._element).trigger(h.SHOWN)};if(P.supportsTransitionEnd()){var _="scroll"+(a[0].toUpperCase()+a.slice(1));t(this._element).one(P.TRANSITION_END,l).emulateTransitionEnd(600),this._element.style[a]=this._element[_]+"px"}else l()}}},o.hide=function(){var e=this;if(!this._isTransitioning&&t(this._element).hasClass(c)){var n=t.Event(h.HIDE);if(t(this._element).trigger(n),!n.isDefaultPrevented()){var i=this._getDimension();if(this._element.style[i]=this._element.getBoundingClientRect()[i]+"px",P.reflow(this._element),t(this._element).addClass(f).removeClass(u).removeClass(c),this._triggerArray.length>0)for(var s=0;s0&&t(n).toggleClass(d,!i).attr("aria-expanded",i)}},i._getTargetFromElement=function(e){var n=P.getSelectorFromElement(e);return n?t(n)[0]:null},i._jQueryInterface=function(e){return this.each(function(){var s=t(this),o=s.data(n),l=r({},a,s.data(),"object"==typeof e&&e);if(!o&&l.toggle&&/show|hide/.test(e)&&(l.toggle=!1),o||(o=new i(this,l),s.data(n,o)),"string"==typeof e){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return a}}]),i}();return t(document).on(h.CLICK_DATA_API,p.DATA_TOGGLE,function(e){"A"===e.currentTarget.tagName&&e.preventDefault();var i=t(this),s=P.getSelectorFromElement(this);t(s).each(function(){var e=t(this),s=e.data(n)?"toggle":i.data();m._jQueryInterface.call(e,s)})}),t.fn[e]=m._jQueryInterface,t.fn[e].Constructor=m,t.fn[e].noConflict=function(){return t.fn[e]=o,m._jQueryInterface},m}(e),W=function(t){var e="dropdown",i="bs.dropdown",o="."+i,a=".data-api",l=t.fn[e],h=new RegExp("38|40|27"),c={HIDE:"hide"+o,HIDDEN:"hidden"+o,SHOW:"show"+o,SHOWN:"shown"+o,CLICK:"click"+o,CLICK_DATA_API:"click"+o+a,KEYDOWN_DATA_API:"keydown"+o+a,KEYUP_DATA_API:"keyup"+o+a},u="disabled",f="show",d="dropup",_="dropright",g="dropleft",p="dropdown-menu-right",m="dropdown-menu-left",v="position-static",E='[data-toggle="dropdown"]',T=".dropdown form",y=".dropdown-menu",C=".navbar-nav",I=".dropdown-menu .dropdown-item:not(.disabled)",A="top-start",b="top-end",D="bottom-start",S="bottom-end",w="right-start",N="left-start",O={offset:0,flip:!0,boundary:"scrollParent"},k={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)"},L=function(){function a(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var l=a.prototype;return l.toggle=function(){if(!this._element.disabled&&!t(this._element).hasClass(u)){var e=a._getParentFromElement(this._element),i=t(this._menu).hasClass(f);if(a._clearMenus(),!i){var s={relatedTarget:this._element},r=t.Event(c.SHOW,s);if(t(e).trigger(r),!r.isDefaultPrevented()){if(!this._inNavbar){if("undefined"==typeof n)throw new TypeError("Bootstrap dropdown require Popper.js (https://popper.js.org)");var o=this._element;t(e).hasClass(d)&&(t(this._menu).hasClass(m)||t(this._menu).hasClass(p))&&(o=e),"scrollParent"!==this._config.boundary&&t(e).addClass(v),this._popper=new n(o,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===t(e).closest(C).length&&t("body").children().on("mouseover",null,t.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),t(this._menu).toggleClass(f),t(e).toggleClass(f).trigger(t.Event(c.SHOWN,s))}}}},l.dispose=function(){t.removeData(this._element,i),t(this._element).off(o),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},l.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},l._addEventListeners=function(){var e=this;t(this._element).on(c.CLICK,function(t){t.preventDefault(),t.stopPropagation(),e.toggle()})},l._getConfig=function(n){return n=r({},this.constructor.Default,t(this._element).data(),n),P.typeCheckConfig(e,n,this.constructor.DefaultType),n},l._getMenuElement=function(){if(!this._menu){var e=a._getParentFromElement(this._element);this._menu=t(e).find(y)[0]}return this._menu},l._getPlacement=function(){var e=t(this._element).parent(),n=D;return e.hasClass(d)?(n=A,t(this._menu).hasClass(p)&&(n=b)):e.hasClass(_)?n=w:e.hasClass(g)?n=N:t(this._menu).hasClass(p)&&(n=S),n},l._detectNavbar=function(){return t(this._element).closest(".navbar").length>0},l._getPopperConfig=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t._config.offset(e.offsets)||{}),e}:e.offset=this._config.offset,{placement:this._getPlacement(),modifiers:{offset:e,flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}}},a._jQueryInterface=function(e){return this.each(function(){var n=t(this).data(i);if(n||(n=new a(this,"object"==typeof e?e:null),t(this).data(i,n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}})},a._clearMenus=function(e){if(!e||3!==e.which&&("keyup"!==e.type||9===e.which))for(var n=t.makeArray(t(E)),s=0;s0&&r--,40===e.which&&rdocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},p._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},p._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent"},f="show",d="out",_={HIDE:"hide"+o,HIDDEN:"hidden"+o,SHOW:"show"+o,SHOWN:"shown"+o,INSERTED:"inserted"+o,CLICK:"click"+o,FOCUSIN:"focusin"+o,FOCUSOUT:"focusout"+o,MOUSEENTER:"mouseenter"+o,MOUSELEAVE:"mouseleave"+o},g="fade",p="show",m=".tooltip-inner",v=".arrow",E="hover",T="focus",y="click",C="manual",I=function(){function a(t,e){if("undefined"==typeof n)throw new TypeError("Bootstrap tooltips require Popper.js (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var I=a.prototype;return I.enable=function(){this._isEnabled=!0},I.disable=function(){this._isEnabled=!1},I.toggleEnabled=function(){this._isEnabled=!this._isEnabled},I.toggle=function(e){if(this._isEnabled)if(e){var n=this.constructor.DATA_KEY,i=t(e.currentTarget).data(n);i||(i=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(n,i)),i._activeTrigger.click=!i._activeTrigger.click,i._isWithActiveTrigger()?i._enter(null,i):i._leave(null,i)}else{if(t(this.getTipElement()).hasClass(p))return void this._leave(null,this);this._enter(null,this)}},I.dispose=function(){clearTimeout(this._timeout),t.removeData(this.element,this.constructor.DATA_KEY),t(this.element).off(this.constructor.EVENT_KEY),t(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&t(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,null!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},I.show=function(){var e=this;if("none"===t(this.element).css("display"))throw new Error("Please use show on visible elements");var i=t.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){t(this.element).trigger(i);var s=t.contains(this.element.ownerDocument.documentElement,this.element);if(i.isDefaultPrevented()||!s)return;var r=this.getTipElement(),o=P.getUID(this.constructor.NAME);r.setAttribute("id",o),this.element.setAttribute("aria-describedby",o),this.setContent(),this.config.animation&&t(r).addClass(g);var l="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,h=this._getAttachment(l);this.addAttachmentClass(h);var c=!1===this.config.container?document.body:t(this.config.container);t(r).data(this.constructor.DATA_KEY,this),t.contains(this.element.ownerDocument.documentElement,this.tip)||t(r).appendTo(c),t(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new n(this.element,r,{placement:h,modifiers:{offset:{offset:this.config.offset},flip:{behavior:this.config.fallbackPlacement},arrow:{element:v},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){e._handlePopperPlacementChange(t)}}),t(r).addClass(p),"ontouchstart"in document.documentElement&&t("body").children().on("mouseover",null,t.noop);var u=function(){e.config.animation&&e._fixTransition();var n=e._hoverState;e._hoverState=null,t(e.element).trigger(e.constructor.Event.SHOWN),n===d&&e._leave(null,e)};P.supportsTransitionEnd()&&t(this.tip).hasClass(g)?t(this.tip).one(P.TRANSITION_END,u).emulateTransitionEnd(a._TRANSITION_DURATION):u()}},I.hide=function(e){var n=this,i=this.getTipElement(),s=t.Event(this.constructor.Event.HIDE),r=function(){n._hoverState!==f&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),t(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()};t(this.element).trigger(s),s.isDefaultPrevented()||(t(i).removeClass(p),"ontouchstart"in document.documentElement&&t("body").children().off("mouseover",null,t.noop),this._activeTrigger[y]=!1,this._activeTrigger[T]=!1,this._activeTrigger[E]=!1,P.supportsTransitionEnd()&&t(this.tip).hasClass(g)?t(i).one(P.TRANSITION_END,r).emulateTransitionEnd(150):r(),this._hoverState="")},I.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},I.isWithContent=function(){return Boolean(this.getTitle())},I.addAttachmentClass=function(e){t(this.getTipElement()).addClass("bs-tooltip-"+e)},I.getTipElement=function(){return this.tip=this.tip||t(this.config.template)[0],this.tip},I.setContent=function(){var e=t(this.getTipElement());this.setElementContent(e.find(m),this.getTitle()),e.removeClass(g+" "+p)},I.setElementContent=function(e,n){var i=this.config.html;"object"==typeof n&&(n.nodeType||n.jquery)?i?t(n).parent().is(e)||e.empty().append(n):e.text(t(n).text()):e[i?"html":"text"](n)},I.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},I._getAttachment=function(t){return c[t.toUpperCase()]},I._setListeners=function(){var e=this;this.config.trigger.split(" ").forEach(function(n){if("click"===n)t(e.element).on(e.constructor.Event.CLICK,e.config.selector,function(t){return e.toggle(t)});else if(n!==C){var i=n===E?e.constructor.Event.MOUSEENTER:e.constructor.Event.FOCUSIN,s=n===E?e.constructor.Event.MOUSELEAVE:e.constructor.Event.FOCUSOUT;t(e.element).on(i,e.config.selector,function(t){return e._enter(t)}).on(s,e.config.selector,function(t){return e._leave(t)})}t(e.element).closest(".modal").on("hide.bs.modal",function(){return e.hide()})}),this.config.selector?this.config=r({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},I._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},I._enter=function(e,n){var i=this.constructor.DATA_KEY;(n=n||t(e.currentTarget).data(i))||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(i,n)),e&&(n._activeTrigger["focusin"===e.type?T:E]=!0),t(n.getTipElement()).hasClass(p)||n._hoverState===f?n._hoverState=f:(clearTimeout(n._timeout),n._hoverState=f,n.config.delay&&n.config.delay.show?n._timeout=setTimeout(function(){n._hoverState===f&&n.show()},n.config.delay.show):n.show())},I._leave=function(e,n){var i=this.constructor.DATA_KEY;(n=n||t(e.currentTarget).data(i))||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(i,n)),e&&(n._activeTrigger["focusout"===e.type?T:E]=!1),n._isWithActiveTrigger()||(clearTimeout(n._timeout),n._hoverState=d,n.config.delay&&n.config.delay.hide?n._timeout=setTimeout(function(){n._hoverState===d&&n.hide()},n.config.delay.hide):n.hide())},I._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},I._getConfig=function(n){return"number"==typeof(n=r({},this.constructor.Default,t(this.element).data(),n)).delay&&(n.delay={show:n.delay,hide:n.delay}),"number"==typeof n.title&&(n.title=n.title.toString()),"number"==typeof n.content&&(n.content=n.content.toString()),P.typeCheckConfig(e,n,this.constructor.DefaultType),n},I._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},I._cleanTipClass=function(){var e=t(this.getTipElement()),n=e.attr("class").match(l);null!==n&&n.length>0&&e.removeClass(n.join(""))},I._handlePopperPlacementChange=function(t){this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},I._fixTransition=function(){var e=this.getTipElement(),n=this.config.animation;null===e.getAttribute("x-placement")&&(t(e).removeClass(g),this.config.animation=!1,this.hide(),this.show(),this.config.animation=n)},a._jQueryInterface=function(e){return this.each(function(){var n=t(this).data(i),s="object"==typeof e&&e;if((n||!/dispose|hide/.test(e))&&(n||(n=new a(this,s),t(this).data(i,n)),"string"==typeof e)){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}})},s(a,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return u}},{key:"NAME",get:function(){return e}},{key:"DATA_KEY",get:function(){return i}},{key:"Event",get:function(){return _}},{key:"EVENT_KEY",get:function(){return o}},{key:"DefaultType",get:function(){return h}}]),a}();return t.fn[e]=I._jQueryInterface,t.fn[e].Constructor=I,t.fn[e].noConflict=function(){return t.fn[e]=a,I._jQueryInterface},I}(e),x=function(t){var e="popover",n="bs.popover",i="."+n,o=t.fn[e],a=new RegExp("(^|\\s)bs-popover\\S+","g"),l=r({},U.Default,{placement:"right",trigger:"click",content:"",template:''}),h=r({},U.DefaultType,{content:"(string|element|function)"}),c="fade",u="show",f=".popover-header",d=".popover-body",_={HIDE:"hide"+i,HIDDEN:"hidden"+i,SHOW:"show"+i,SHOWN:"shown"+i,INSERTED:"inserted"+i,CLICK:"click"+i,FOCUSIN:"focusin"+i,FOCUSOUT:"focusout"+i,MOUSEENTER:"mouseenter"+i,MOUSELEAVE:"mouseleave"+i},g=function(r){var o,g;function p(){return r.apply(this,arguments)||this}g=r,(o=p).prototype=Object.create(g.prototype),o.prototype.constructor=o,o.__proto__=g;var m=p.prototype;return m.isWithContent=function(){return this.getTitle()||this._getContent()},m.addAttachmentClass=function(e){t(this.getTipElement()).addClass("bs-popover-"+e)},m.getTipElement=function(){return this.tip=this.tip||t(this.config.template)[0],this.tip},m.setContent=function(){var e=t(this.getTipElement());this.setElementContent(e.find(f),this.getTitle());var n=this._getContent();"function"==typeof n&&(n=n.call(this.element)),this.setElementContent(e.find(d),n),e.removeClass(c+" "+u)},m._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},m._cleanTipClass=function(){var e=t(this.getTipElement()),n=e.attr("class").match(a);null!==n&&n.length>0&&e.removeClass(n.join(""))},p._jQueryInterface=function(e){return this.each(function(){var i=t(this).data(n),s="object"==typeof e?e:null;if((i||!/destroy|hide/.test(e))&&(i||(i=new p(this,s),t(this).data(n,i)),"string"==typeof e)){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}})},s(p,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return l}},{key:"NAME",get:function(){return e}},{key:"DATA_KEY",get:function(){return n}},{key:"Event",get:function(){return _}},{key:"EVENT_KEY",get:function(){return i}},{key:"DefaultType",get:function(){return h}}]),p}(U);return t.fn[e]=g._jQueryInterface,t.fn[e].Constructor=g,t.fn[e].noConflict=function(){return t.fn[e]=o,g._jQueryInterface},g}(e),K=function(t){var e="scrollspy",n="bs.scrollspy",i="."+n,o=t.fn[e],a={offset:10,method:"auto",target:""},l={offset:"number",method:"string",target:"(string|element)"},h={ACTIVATE:"activate"+i,SCROLL:"scroll"+i,LOAD_DATA_API:"load"+i+".data-api"},c="dropdown-item",u="active",f={DATA_SPY:'[data-spy="scroll"]',ACTIVE:".active",NAV_LIST_GROUP:".nav, .list-group",NAV_LINKS:".nav-link",NAV_ITEMS:".nav-item",LIST_ITEMS:".list-group-item",DROPDOWN:".dropdown",DROPDOWN_ITEMS:".dropdown-item",DROPDOWN_TOGGLE:".dropdown-toggle"},d="offset",_="position",g=function(){function o(e,n){var i=this;this._element=e,this._scrollElement="BODY"===e.tagName?window:e,this._config=this._getConfig(n),this._selector=this._config.target+" "+f.NAV_LINKS+","+this._config.target+" "+f.LIST_ITEMS+","+this._config.target+" "+f.DROPDOWN_ITEMS,this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,t(this._scrollElement).on(h.SCROLL,function(t){return i._process(t)}),this.refresh(),this._process()}var g=o.prototype;return g.refresh=function(){var e=this,n=this._scrollElement===this._scrollElement.window?d:_,i="auto"===this._config.method?n:this._config.method,s=i===_?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),t.makeArray(t(this._selector)).map(function(e){var n,r=P.getSelectorFromElement(e);if(r&&(n=t(r)[0]),n){var o=n.getBoundingClientRect();if(o.width||o.height)return[t(n)[i]().top+s,r]}return null}).filter(function(t){return t}).sort(function(t,e){return t[0]-e[0]}).forEach(function(t){e._offsets.push(t[0]),e._targets.push(t[1])})},g.dispose=function(){t.removeData(this._element,n),t(this._scrollElement).off(i),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},g._getConfig=function(n){if("string"!=typeof(n=r({},a,n)).target){var i=t(n.target).attr("id");i||(i=P.getUID(e),t(n.target).attr("id",i)),n.target="#"+i}return P.typeCheckConfig(e,n,l),n},g._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},g._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},g._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},g._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(var s=this._offsets.length;s--;){this._activeTarget!==this._targets[s]&&t>=this._offsets[s]&&("undefined"==typeof this._offsets[s+1]||t=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}(e),t.Util=P,t.Alert=L,t.Button=R,t.Carousel=j,t.Collapse=H,t.Dropdown=W,t.Modal=M,t.Popover=x,t.Scrollspy=K,t.Tab=V,t.Tooltip=U,Object.defineProperty(t,"__esModule",{value:!0})}); 7 | //# sourceMappingURL=bootstrap.min.js.map -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Apr 22 21:20:45 2015 4 | 5 | @author: Chenriwei 6 | 7 | @function: 8 | 主要实现人脸检测、关键点检测、人脸对齐、归一化等操作。 9 | 将各个步骤衔接起来,实现一键操作。 10 | 11 | @attention: 12 | 1,只适合在windows下使用; 13 | 2,人脸检测器和关键点检测器利用了香港中文大学提供的二进制文件,版权归他们所有; 14 | 3,可以用更好的人脸检测器和关键点检测器来替换掉默认的检测器。 15 | """ 16 | import makeimagelist 17 | import os 18 | import aligment 19 | import facecrop 20 | import textutil 21 | 22 | def test(ImagePath,savePathDetect,savePathAligned,savePathCroped,fileformat=['png','jpg'],tag_recover=False,savesize=[128,128]): 23 | ''' 24 | 必须提供的参数: 25 | 1,@ImagePath:待检测和对齐的图像路径 26 | 2,@savePathDetect:保存检测到的人脸的文件夹路径 27 | 3,@savePathAligned:保存对其后的人脸文件夹路径 28 | 可选的参数(有默认值): 29 | 4,@fileformat:图像的格式列表,默认为png和jpg格式 30 | 5,@tag_recover: 是否先裁剪处人脸图像之后再做归一化,默认为False 31 | 6, @savesize: 检测后保留的人脸图像的大小,当tag_recover=True 的时候,才会生效,默认大小为64*64 32 | 33 | ''' 34 | 35 | if not os.path.exists(savePathDetect): 36 | os.makedirs(savePathDetect) 37 | if not os.path.exists(savePathAligned): 38 | os.makedirs(savePathAligned) 39 | if not os.path.exists(savePathCroped): 40 | os.makedirs(savePathCroped) 41 | 42 | 43 | print 'Begin making filelist. step (1/6) ' 44 | #创建imagelist.list 文件,用来保存文件图像文件列表 45 | imagelist = './Output/imagelist.list' 46 | fid=open(imagelist,'w') 47 | makeimagelist.makeImageFileList(ImagePath,fid,fileformat) 48 | fid.close() 49 | #统计有多少个图像文件 50 | count=textutil.count_text_line(imagelist) 51 | textutil.insertLine(imagelist,1,str(count)) 52 | 53 | print 'Done make file list. step(1/6)' 54 | 55 | #人脸检测,生成imageBbox.list 文件, 56 | print 'Begin Face Detection task. step(2/6)' 57 | bboxlist='./Output/imagebbox.list' 58 | os.system('FaceDetect.exe data '+imagelist+' '+bboxlist) 59 | print 'Done Face Detection task.step(2/6)' 60 | 61 | #清除检测不到的图像,或者检测到多个的文件,以便于后面的人脸关键点检测。 62 | print 'Begin Box file Clean and Replace. step(3/6)' 63 | detectlist='./Output/imagebbox_detect.list' 64 | misslist='./Output/imagebbox_miss.list' 65 | textutil.cleanbox(fileinput=bboxlist,detectlistfile=detectlist,misslistfile=misslist) 66 | replacelist='./Output/imagebbox_detect_replace.list' 67 | textutil.replace_file(detectlist,replacelist,ImagePath) 68 | print 'Done Box file Clean and Replace. step(3/6)' 69 | 70 | if tag_recover==True: 71 | #人脸先裁剪 72 | # 保留检测到的人脸图像,可选, 73 | print 'Begin Save Detected Face Image. step(4/4) optional' 74 | facecrop.face_cropout(ImagePath,savePathDetect,replacelist,w=savesize[0],h=savesize[1]) 75 | print 'Done Save Detected Face Image. step(4/4) optional' 76 | ImagePath=savePathDetect 77 | 78 | print 'Begin making filelist. step (1/6) ' 79 | #创建imagelist.list 文件,用来保存文件图像文件列表 80 | imagelist = './Output/imagelist_recover.list' 81 | fid=open(imagelist,'w') 82 | makeimagelist.makeImageFileList(ImagePath,fid,fileformat) 83 | fid.close() 84 | #统计有多少个图像文件 85 | count=textutil.count_text_line(imagelist) 86 | textutil.insertLine(imagelist,1,str(count)) 87 | 88 | print 'Done make file list. step(1/6)' 89 | 90 | #人脸检测,生成imageBbox.list 文件, 91 | print 'Begin Face Detection task. step(2/6)' 92 | bboxlist='./Output/imagebbox__recover.list' 93 | os.system('FaceDetect.exe data '+imagelist+' '+bboxlist) 94 | print 'Done Face Detection task.step(2/6)' 95 | 96 | #清除检测不到的图像,或者检测到多个的文件,以便于后面的人脸关键点检测。 97 | print 'Begin Box file Clean and Replace. step(3/6)' 98 | detectlist='./Output/imagebbox_recover_detect.list' 99 | misslist='./Output/imagebbox_recover_miss.list' 100 | textutil.cleanbox(fileinput=bboxlist,detectlistfile=detectlist,misslistfile=misslist) 101 | replacelist='./Output/imagebbox_detect_recover_replace.list' 102 | textutil.replace_file(detectlist,replacelist,ImagePath) 103 | print 'Done Box file Clean and Replace. step(3/6)' 104 | 105 | #人脸关键点检测 106 | print 'Begin Face Point Detection. step(4/6)' 107 | resultpath='./Output/result.bin' 108 | command_='FacePointDetect.exe '+replacelist+' '+ImagePath+' Input '+resultpath 109 | os.system(command_) 110 | print 'Done Face Point Detection. step(4/6)' 111 | 112 | print 'Begin write Points files. step(5/6)' 113 | points=textutil.take_out_point(resultpath) 114 | imagepointlist='./Output/imagelist_point.list' 115 | textutil.writePoint2File(replacelist,imagepointlist,points) 116 | print 'Done write Points files. step(5/6)' 117 | 118 | print 'Begin Alignment Face. step(6/6)' 119 | aligment.align_all(imagepointlist,ImagePath,savePathAligned) 120 | print 'Done Alignment Face. step(6/6)' 121 | 122 | print 'Begin Face croped in' 123 | facecrop.face_crop_in(savePathAligned,savePathCroped,replacelist,savesize[0],savesize[1]) 124 | print 'Done Face croped in ' 125 | print 'All work is done!' 126 | 127 | if __name__ == "__main__" : 128 | ''' 129 | @param: 提供的参数:1,图像的文件名位置,2,需要保留的文件位置,3,图像的格式列表 130 | ''' 131 | ImagePath=r'F:\MyDataSet\IdTest\origin' 132 | savePathDetect=r'F:\MyDataSet\IdTest\detect' 133 | savePathAligned=r'F:\MyDataSet\IdTest\aligned' 134 | savePathCroped=r'F:\MyDataSet\IdTest\croped' 135 | test(ImagePath,savePathDetect,savePathAligned,savePathCroped,tag_recover=True,savesize=[128,128]) -------------------------------------------------------------------------------- /makeImageFileList.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Tue Jun 02 13:36:35 2015 4 | 5 | @author: Chenriwei 6 | """ 7 | import os.path 8 | import glob 9 | 10 | def makeImageFileList(filePath,fid,fileformat=['jpg','png']): 11 | ''' 12 | @brief: 实现递归的文件目录写入文件fid中 13 | @param: fidPath:根目录 14 | @param: fid: 文件对象 15 | @param: fileformat: 需要扫描的文件格式 16 | ''' 17 | dirlist=os.listdir(filePath) 18 | for t in dirlist: 19 | # 如果有子目录,则递归调用 20 | if os.path.isdir(os.path.join(filePath,t)): 21 | subpath=os.path.join(filePath,t) 22 | makeImageFileList(subpath,fid,fileformat) 23 | # 当前文件夹下有图片文件,则先加入文件列表 24 | for image_format in fileformat: 25 | for filename in glob.glob(filePath+'\*.'+image_format): 26 | fid.write(filename+'\n') 27 | # 下面的方案的错误在于 os.walk 会递归遍历。 28 | # for dirname, dirnames, filenames in os.walk(filePath):# document os.walk 会遍历到低,不合适 29 | # # 当前文件夹下有图片文件,则先加入文件列表 30 | # print dirnames 31 | # print filenames 32 | # for image_format in fileformat: 33 | # for filename in glob.glob(filePath+'\*.'+image_format): 34 | # print 'Adding filename:',filename 35 | # fid.write(filename+'\n') 36 | # # 递归调用 37 | # for subdirname in dirnames: 38 | # subpath = os.path.join(dirname, subdirname) 39 | # makeImageFileList(subpath,fid,fileformat) 40 | # 41 | if __name__=='__main__': 42 | fid = open('imagelist.list', 'w') 43 | filePath=r'E:\Multi-Pie\data\session04' 44 | fileformat=['png'] 45 | makeImageFileList(filePath,fid,fileformat) 46 | fid.close() -------------------------------------------------------------------------------- /makeimagelist.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Apr 22 21:20:45 2015 4 | 5 | @author: Chenriwei 6 | """ 7 | 8 | import os.path 9 | import glob 10 | 11 | def makeImageFileList_3d(filepath,fileformat=['jpg']): 12 | file_object = open('imagelist.list', 'w') 13 | filecount=0 14 | for dirname, dirnames, filenames in os.walk(filepath): 15 | for subdirname in dirnames: 16 | subject_path = os.path.join(dirname, subdirname) 17 | for dirname_2,subdirnames,subfilenames in os.walk(subject_path): 18 | subsubject_path = os.path.join(subject_path, dirname_2) 19 | for image_format in fileformat: 20 | for filename in glob.glob(subsubject_path+'\*.'+image_format): 21 | filecount=filecount+1 22 | 23 | file_object.write(str(filecount)+'\n') 24 | for dirname, dirnames, filenames in os.walk(filepath): 25 | for subdirname in dirnames: 26 | subject_path = os.path.join(dirname, subdirname) 27 | for dirname_2,subdirnames,subfilenames in os.walk(subject_path): 28 | subsubject_path = os.path.join(subject_path, dirname_2) 29 | for image_format in fileformat: 30 | for filename in glob.glob(subsubject_path+'\*.'+image_format): 31 | file_object.write(filename+'\n') 32 | print (filename) 33 | file_object.close( ) 34 | 35 | def makeImageFileList_2d(filepath,fileformat=['jpg']): 36 | file_object = open('imagelist.list', 'w') 37 | filecount=0 38 | for dirname, dirnames, filenames in os.walk(filepath): 39 | for subdirname in dirnames: 40 | subject_path = os.path.join(dirname, subdirname) 41 | for image_format in fileformat: 42 | for filename in glob.glob(subject_path+'\*.'+image_format): 43 | filecount=filecount+1 44 | 45 | file_object.write(str(filecount)+'\n') 46 | for dirname, dirnames, filenames in os.walk(filepath): 47 | for subdirname in dirnames: 48 | subject_path = os.path.join(dirname, subdirname) 49 | print (subject_path) 50 | for image_format in fileformat: 51 | for filename in glob.glob(subject_path+'\*.'+image_format): 52 | #abs_path = "%s\%s\n" % (subject_path, filename) 53 | print (filename) 54 | file_object.write(filename+'\n') 55 | file_object.close( ) 56 | 57 | def makeImageFileList_1d(filepath,fileformat=['jpg']): 58 | file_object = open('imagelist.list', 'w') 59 | 60 | filecount=0 61 | for dirname, dirnames, filenames in os.walk(filepath): 62 | for filename in filenames: 63 | filecount=filecount+1 64 | file_object.write(str(filecount)+'\n') 65 | for dirname, dirnames, filenames in os.walk(filepath): 66 | for filename in filenames: 67 | print (filename) 68 | abs_path =filepath + "\%s\n" % (filename) 69 | print (abs_path) 70 | file_object.write(abs_path) 71 | file_object.close( ) 72 | print ('done!') 73 | def makeImageFileList(filePath,fid,fileformat=['jpg','png']): 74 | ''' 75 | @brief: 实现递归的文件目录写入文件fid中 76 | @param: fidPath:根目录 77 | @param: fid: 文件对象 78 | @param: fileformat: 需要扫描的文件格式 79 | ''' 80 | dirlist=os.listdir(filePath) 81 | for t in dirlist: 82 | # 如果有子目录,则递归调用 83 | if os.path.isdir(os.path.join(filePath,t)): 84 | subpath=os.path.join(filePath,t) 85 | makeImageFileList(subpath,fid,fileformat) 86 | # 当前文件夹下有图片文件,则先加入文件列表 87 | for image_format in fileformat: 88 | for filename in glob.glob(filePath+'\*.'+image_format): 89 | fid.write(filename+'\n') 90 | if __name__ == "__main__": 91 | makeImageFileList_1d(r'F:\Dataset\MORPH','jpg') 92 | print ('done!') -------------------------------------------------------------------------------- /opencv_core231.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/opencv_core231.dll -------------------------------------------------------------------------------- /opencv_highgui231.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/opencv_highgui231.dll -------------------------------------------------------------------------------- /opencv_imgproc231.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/opencv_imgproc231.dll -------------------------------------------------------------------------------- /retain_max_face.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Fri May 29 14:17:05 2015 4 | 5 | @author: Chenriwei 6 | @brief: 用于当一张人脸图像中有张人脸图像的时候,只保留最大的那个。 7 | """ 8 | import numpy as np 9 | 10 | def retain_max_face(line): 11 | ''' 12 | @param:行内容 13 | @return:返回新的行内容 14 | ''' 15 | word=line.split() 16 | num_detect=len(word)/4 17 | areas=np.empty((num_detect,),dtype=np.int32)#保留的是图像的面积 18 | for i in range(num_detect): 19 | #print int(word[4*i+1]),int(word[4*i+2]),int(word[4*i+3]),int(word[4*i+4]) 20 | areas[i]=(int(word[4*i+2])-int(word[4*i+1]))*(int(word[4*i+4])-int(word[4*i+3])) 21 | print areas[i] 22 | m=np.argmax(areas) 23 | newline=word[0]+' '+word[4*m+1]+' '+word[4*m+2]+' '+word[4*m+3]+' '+word[4*m+4]+'\n' 24 | return newline 25 | 26 | def cleanBoxFile(): 27 | file0="imageBbox.list" 28 | file3="imageBbox_mul_max.list" 29 | file0_obj=open(file0,'r') 30 | fid3=open(file3,'w') 31 | lines=file0_obj.readlines() 32 | for line in lines: 33 | if line.count(" ")==4: 34 | pass 35 | else: 36 | if line.count(" ")>4:#表明有多个人脸被检测到 37 | newline=retain_max_face(line) 38 | fid3.write(newline) 39 | file0_obj.close() 40 | fid3.close() 41 | print 'done!' 42 | if __name__ == "__main__" : 43 | cleanBoxFile() -------------------------------------------------------------------------------- /skimagetest.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Wed Apr 22 23:03:31 2015 4 | 5 | @author: Chenriwei 6 | """ 7 | import os 8 | import math 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | from skimage import data,io,transform 12 | from skimage.transform import warp_coords, PiecewiseAffineTransform 13 | 14 | fid=open('imageBbox_detect.list') 15 | line=fid.readline().split() 16 | name=line[0] 17 | x1=int(line[1])# 左 18 | x2=int(line[2])# 右 19 | y1=int(line[3])# 上 20 | y2=int(line[4])# 下 21 | x=x2-x1 22 | y=y2-y1 23 | extx=math.floor(x*0.2) 24 | exty=math.floor(y*0.2)#扩展剪切面积,使得可以显示更多。 25 | im=data.imread(name,as_grey=True) 26 | imcrop=im[y1 - 4*exty:y2+exty,x1-extx:x2+extx] 27 | transform.resize(imcrop,(64,64)) 28 | io.imsave(name,imcrop) 29 | io.imshow(imcrop) 30 | print line -------------------------------------------------------------------------------- /smartContract/nasface.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var FaceItem = function(text) { 4 | if (text) { 5 | var obj = JSON.parse(text); 6 | this.key = obj.key; 7 | this.value = obj.value; 8 | this.author = obj.author; 9 | } else { 10 | this.key = ""; 11 | this.author = ""; 12 | this.value = ""; 13 | } 14 | }; 15 | 16 | FaceItem.prototype = { 17 | toString: function () { 18 | return JSON.stringify(this); 19 | } 20 | }; 21 | 22 | var NasFaceMain = function () { 23 | LocalContractStorage.defineMapProperty(this, "repo", { 24 | parse: function (text) { 25 | return new FaceItem(text); 26 | }, 27 | stringify: function (o) { 28 | return o.toString(); 29 | } 30 | }); 31 | }; 32 | 33 | NasFaceMain.prototype = { 34 | init: function () { 35 | // todo 36 | }, 37 | 38 | save: function (key, value) { 39 | 40 | key = key.trim(); 41 | value = value.trim(); 42 | if (key === "" || value === ""){ 43 | throw new Error("empty key / value"); 44 | } 45 | if (value.length > 64 || key.length > 64){ 46 | throw new Error("key / value exceed limit length") 47 | } 48 | 49 | var from = Blockchain.transaction.from; 50 | var faceItem = this.repo.get(key); 51 | if (faceItem){ 52 | throw new Error("value has been occupied"); 53 | } 54 | 55 | faceItem = new FaceItem(); //区分大小写 56 | faceItem.author = from; 57 | faceItem.key = key; 58 | faceItem.value = value; 59 | 60 | this.repo.put(key, faceItem); 61 | }, 62 | 63 | get: function (key) { 64 | key = key.trim(); 65 | if ( key === "" ) { 66 | throw new Error("empty key") 67 | } 68 | return this.repo.get(key); 69 | } 70 | }; 71 | module.exports = NasFaceMain; -------------------------------------------------------------------------------- /tbb.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lawup/nasface/de111a7910cf286322516fe2e6abdcb1fa112306/tbb.dll -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | print(sys.argv[1]) 4 | 5 | 6 | -------------------------------------------------------------------------------- /textutil.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Thu Jun 04 16:15:32 2015 4 | 5 | @author: Chenriwei 6 | """ 7 | import numpy as np 8 | import struct 9 | def insertLine(filename,index=1,text=''): 10 | ''' 11 | @brief: 将指定的文件内容插入到文件的指定的一行中 12 | @param: index 13 | 插入的行数,从1开始。 14 | @param: filename 15 | 文件名 16 | ''' 17 | fid=open(filename,'r') 18 | lines=[] 19 | for line in fid: 20 | lines.append(line) 21 | fid.close() 22 | 23 | text=text+'\n' 24 | lines.insert(index-1,text) 25 | s=''.join(lines) 26 | print (len(lines)) 27 | fid=open(filename,'w') 28 | fid.write(s) 29 | fid.close() 30 | 31 | def count_text_line(filename): 32 | ''' 33 | @breif: 计算文件的行数 34 | @param: filename 35 | 文件名。 36 | ''' 37 | fid=open(filename) 38 | lines=[] 39 | for line in fid: 40 | lines.append(line) 41 | fid.close() 42 | return len(lines) 43 | 44 | def replace_file(filename1,filename2,filapath): 45 | ''' 46 | @brief: main inplement the file replace function. 47 | ''' 48 | fid=open(filename1) 49 | fid_save=open(filename2,'w') 50 | lines=fid.readlines() 51 | for line in lines: 52 | newline=line.replace(filapath,'') 53 | fid_save.write(newline) 54 | fid.close() 55 | fid_save.close() 56 | 57 | def take_out_point(filepath='./Output/result.bin'): 58 | ''' 59 | @breif: mainly to take the bin file to a txt file for readly by other 60 | 61 | ''' 62 | fid = open(filepath, 'rb'); 63 | 64 | imageNum=struct.unpack('i',fid.read(4))[0] 65 | print (imageNum) 66 | 67 | pointNum =struct.unpack('i',fid.read(4))[0] 68 | print (pointNum) 69 | for i in range(imageNum): 70 | valid=struct.unpack('b',fid.read(1)) 71 | pointdata=np.empty((2*pointNum * imageNum,1),dtype=np.float64) 72 | k=0 73 | for i in range(imageNum): 74 | for j in range(pointNum):#2*pointNum * imageNum* 75 | pointdata[k]=struct.unpack('d',fid.read(8)) 76 | k=k+1 77 | pointdata[k]=struct.unpack('d',fid.read(8)) 78 | k=k+1 79 | points=np.reshape(pointdata,(imageNum,2 * pointNum)) 80 | fid.close() 81 | return points 82 | 83 | def writePoint2File(filename,filename2,points): 84 | fid=open(filename) 85 | fid_save=open(filename2,'w') 86 | numfile=np.shape(points)[0] 87 | for i in range(numfile): 88 | fn=fid.readline().split()[0]# image filename 89 | fid_save.write(fn) 90 | for j in range(10): 91 | fid_save.write(' '+str(int(points[i][j]))) 92 | fid_save.write('\n') 93 | fid.close() 94 | fid_save.close() 95 | 96 | def retain_max_face(line): 97 | ''' 98 | @param:行内容 99 | @return:返回新的行内容 100 | ''' 101 | word=line.split() 102 | num_detect=int(len(word)/4) 103 | areas=np.empty((int(num_detect),),dtype=np.int32)#保留的是图像的面积 104 | for i in range(num_detect): 105 | #print (int(word[4*i+1]),int(word[4*i+2]),int(word[4*i+3]),int(word[4*i+4])) 106 | areas[i]=(int(word[4*i+2])-int(word[4*i+1]))*(int(word[4*i+4])-int(word[4*i+3])) 107 | #print (areas[i]) 108 | m=np.argmax(areas) 109 | newline=word[0]+' '+word[4*m+1]+' '+word[4*m+2]+' '+word[4*m+3]+' '+word[4*m+4]+'\n' 110 | return newline 111 | 112 | def cleanbox(fileinput="imageBbox.list",detectlistfile="imageBbox_detect.list",misslistfile="imageBbox_miss.list"): 113 | ''' 114 | 清除掉没有检测到的人脸图像,或者检测到多个人脸的图像 115 | 因为只需要考虑单个人脸即可 116 | 对于多个人脸的情况,可以后面再补充进来。 117 | ''' 118 | 119 | file0_obj=open(fileinput,'r') 120 | file1_obj=open(detectlistfile,'w') 121 | file2_obj=open(misslistfile,'w') 122 | lines=file0_obj.readlines() 123 | for line in lines: 124 | #print (line) 125 | if line.count(" ")==4: 126 | file1_obj.write(line) 127 | else: 128 | if line.count(" ")>4:#表明有多个人脸被检测到 129 | newline=retain_max_face(line) 130 | file1_obj.write(newline) 131 | else: 132 | file2_obj.write(line) 133 | file0_obj.close() 134 | file1_obj.close() 135 | file2_obj.close() 136 | #print ('done!') 137 | 138 | if __name__=='__main__': 139 | insertLine('undetect.list',10,'Hello wrorld') 140 | --------------------------------------------------------------------------------