김예미
Showing 51 changed files with 2555 additions and 8 deletions
...@@ -4,10 +4,8 @@ ...@@ -4,10 +4,8 @@
4 <component name="GradleSettings"> 4 <component name="GradleSettings">
5 <option name="linkedExternalProjectsSettings"> 5 <option name="linkedExternalProjectsSettings">
6 <GradleProjectSettings> 6 <GradleProjectSettings>
7 - <compositeConfiguration>
8 - <compositeBuild compositeDefinitionSource="SCRIPT" />
9 - </compositeConfiguration>
10 <option name="delegatedBuild" value="false" /> 7 <option name="delegatedBuild" value="false" />
8 + <option name="testRunner" value="PLATFORM" />
11 <option name="distributionType" value="DEFAULT_WRAPPED" /> 9 <option name="distributionType" value="DEFAULT_WRAPPED" />
12 <option name="externalProjectPath" value="$PROJECT_DIR$" /> 10 <option name="externalProjectPath" value="$PROJECT_DIR$" />
13 <option name="modules"> 11 <option name="modules">
...@@ -17,7 +15,6 @@ ...@@ -17,7 +15,6 @@
17 </set> 15 </set>
18 </option> 16 </option>
19 <option name="resolveModulePerSourceSet" value="false" /> 17 <option name="resolveModulePerSourceSet" value="false" />
20 - <option name="testRunner" value="PLATFORM" />
21 </GradleProjectSettings> 18 </GradleProjectSettings>
22 </option> 19 </option>
23 </component> 20 </component>
......
1 +.content{
2 + width :100%;
3 + height :100%;
4 +}
5 +.win_top{
6 + width :100%;
7 + height :10%;
8 + float:left;
9 +}
10 +#title{
11 + width :68%;
12 + height :10%;
13 + float:left;
14 +}
15 +#title img{
16 + height: 80px;
17 + width : auto;
18 + margin-left : 20px;
19 + float:left;
20 +}
21 +#title img:hover{
22 + opacity:0.6;
23 +}
24 +#selected-date{
25 + font-size: 10px;
26 + float:left;
27 + font-weight: bold;
28 + margin-top : -10px;
29 + margin-left:17px;
30 + border-bottom: 1px solid #4e73df;
31 +
32 +}
33 +#selected-file{
34 + font-size: 10px;
35 + float:left;
36 + font-weight: bold;
37 + margin-top : -10px;
38 + margin-left:70px;
39 + border-bottom: 1px solid #4e73df;
40 +}
41 +#date{
42 + width:28%;
43 + height :15%;
44 + float:left;
45 + vertical-align: middle;
46 +}
47 +p.float_left{
48 + float:left;
49 +}
50 +.results{
51 + width :98%;
52 + height :85%;
53 + position:absolute;
54 + bottom:10px;
55 + left:10px;
56 + text-align: center;
57 + float:left;
58 + border :2px dashed #4e73df;
59 + overflow-y:auto;
60 +}
61 +.photo{
62 + width : 240px;
63 + height : 300px;
64 + border :1px solid #4e73df;
65 + color:black;
66 + float : left;
67 + margin : 5px;
68 +
69 +}
70 +.top{
71 + width:240px;
72 + height:240px;
73 +}
74 +.top img{
75 + width:100%;
76 + height:100%;
77 + object-fit:contain;
78 +}
79 +.bottom{
80 + width:240px;
81 + height:60px;
82 +}
83 +.name{
84 + width : 200px;
85 + height:60px;
86 + float : left;
87 +}
88 +.check{
89 + width : 40px;
90 + height:60px;
91 + float : left;
92 +}
93 +.check input{
94 + width:20px;
95 + height :20px;
96 + margin-top:20px;
97 + margin-right:10px;
98 + border: 2px solid #bcbcbc;
99 +}
100 +.check input:checked{
101 + background-color: #4e73df;
102 +}
103 +#start_date{
104 + border: 1px solid #4e73df;
105 + background-color: white;
106 + line-height: 1;
107 + font-size: 17px;
108 + width: 200px;
109 + height :50px;
110 + padding:10px 15px;
111 + display: block;
112 + box-sizing: border-box;
113 + border-radius: 60px;
114 + color: dimgray;
115 + font-weight: 100;
116 + letter-spacing: 0.01em;
117 + position: relative;
118 + z-index: 1;
119 + margin-left: 10px;
120 +}
121 +#end_date{
122 + border: 1px solid #4e73df;
123 + background-color: white;
124 + line-height: 1;
125 + font-size: 17px;
126 + width: 200px;
127 + height :50px;
128 + padding:10px 15px;
129 + display: block;
130 + box-sizing: border-box;
131 + border-radius: 60px;
132 + color: dimgray;
133 + font-weight: 100;
134 + letter-spacing: 0.01em;
135 + position: relative;
136 + z-index: 1;
137 + margin-left: 10px;
138 +}
139 +#select{
140 + border: 1px solid #4e73df;
141 + background-color: #4e73df;
142 + line-height: 1;
143 + font-size: 17px;
144 + width: 135px;
145 + height :50px;
146 + padding:10px 15px;
147 + display: block;
148 + box-sizing: border-box;
149 + color: white;
150 + font-weight: 100;
151 + letter-spacing: 0.01em;
152 + position: relative;
153 + z-index: 1;
154 + margin-left: 10px;
155 +}
156 +#select:hover{
157 + background-color: white;
158 + color: #4e73df;
159 +}
160 +#submit{
161 + border: 1px solid #4e73df;
162 + background-color: #4e73df;
163 + line-height: 1;
164 + font-size: 17px;
165 + width: 100px;
166 + height :50px;
167 + padding:10px 15px;
168 + display: block;
169 + box-sizing: border-box;
170 + border-radius: 60px;
171 + color: white;
172 + font-weight: 100;
173 + letter-spacing: 0.01em;
174 + position: relative;
175 + z-index: 1;
176 + margin-left: 10px;
177 +}
178 +#submit:hover{
179 + background-color: white;
180 + color: #4e73df;
181 +}
182 +#save_photo{
183 + border: 1px solid #4e73df;
184 + background-color: #4e73df;
185 + line-height: 1;
186 + font-size: 17px;
187 + width: 135px;
188 + height :50px;
189 + padding:10px 15px;
190 + display: block;
191 + box-sizing: border-box;
192 + color: white;
193 + font-weight: 100;
194 + letter-spacing: 0.01em;
195 + position: relative;
196 + z-index: 1;
197 + margin-left: 10px;
198 + visibility: visible;
199 +}
200 +#save_photo:hover{
201 + background-color: white;
202 + color: #4e73df;
203 +}
204 +#closeBtn {
205 + border: 1px solid #4e73df;
206 + background-color: #4e73df;
207 + line-height: 1;
208 + font-size: 25px;
209 + width: 50px;
210 + height :50px;
211 + padding:10px 15px;
212 + display: block;
213 + box-sizing: border-box;
214 + border-radius: 60px;
215 + color: white;
216 + font-weight: 100;
217 + letter-spacing: 0.01em;
218 + position: relative;
219 + z-index: 1;
220 + margin-left: 5px;
221 +}
222 +#closeBtn:hover{
223 + background-color: white;
224 + color: #4e73df;
225 +}
1 +.content{
2 + width :100%;
3 + height :100%;
4 +}
5 +.win_top{
6 + width :100%;
7 + height :10%;
8 + float:left;
9 +}
10 +#title{
11 + width :68%;
12 + height :10%;
13 + float:left;
14 +}
15 +#title img{
16 + height: 80px;
17 + width : auto;
18 + margin-left : 20px;
19 + float:left;
20 +}
21 +#title img:hover{
22 + opacity :0.6;
23 +}
24 +#date{
25 + width:28%;
26 + height :15%;
27 + float:left;
28 + vertical-align: middle;
29 +}
30 +p.float_left{
31 + float:left;
32 +}
33 +.results{
34 + width :98%;
35 + height :85%;
36 + position:absolute;
37 + bottom:10px;
38 + left:10px;
39 + text-align: center;
40 + float:left;
41 + overflow-y:auto;
42 + border : 2px solid #4e73df
43 +}
44 +#image{
45 + float: left;
46 + filter:blur(5px);
47 + margin:5px;
48 +}
49 +#image:hover{
50 +opacity: 0.8;
51 +}
52 +#detect{
53 + border: 1px solid dimgray;
54 + background-color: dimgray;
55 + line-height: 1;
56 + font-size: 17px;
57 + width: 200px;
58 + height :40px;
59 + padding:10px 15px;
60 + display: block;
61 + box-sizing: border-box;
62 + color: white;
63 + font-weight: 100;
64 + letter-spacing: 0.01em;
65 + position: absolute;
66 + top:4%;
67 + right:5%;
68 + z-index: 1;
69 + margin-top: 10px;
70 +}
71 +#detect:hover{
72 + background-color: white;
73 + color: dimgray;
74 +}
...\ No newline at end of file ...\ No newline at end of file
1 +.all{
2 + width :100%;
3 + height :100%;
4 +}
5 +.top{
6 + width :100%;
7 + height :10%;
8 + float:left;
9 +}
10 +.title{
11 + width :70%;
12 + height :10%;
13 + float:left;
14 +}
15 +.title img{
16 + height: 80px;
17 + width : auto;
18 + margin-left : 20px;
19 + float:left;
20 +}.title img:hover{
21 + opacity:0.6;
22 +}
23 +.content{
24 + width :100%;
25 + height :90%;
26 +}
27 +p.float_left{
28 + float:left;
29 +}
30 +#explanation{
31 + width:35%;
32 + height:27.5%;
33 + position: absolute;
34 + right: 2%;
35 + bottom: 55%;
36 + text-align: center;
37 +}
38 +#explanation h1{
39 + margin-top:12%;
40 + color:dimgray;
41 +}
42 +#map {
43 + width:35%;
44 + height:50%;
45 + clear:both;
46 + border:solid 1px #4e73df;
47 + position: absolute;
48 + right: 2%;
49 + bottom: 3%;
50 +}
51 +#main{
52 + width:58%;
53 + height:78%;
54 + border:solid 5px #4e73df;
55 + position: absolute;
56 + left: 2%;
57 + bottom : 3%;
58 + overflow-y:auto;
59 + background-color: #7FB2F0;
60 +}
61 +.p{
62 + width:295px;
63 + height:295px;
64 + float : left;
65 + margin :1px;
66 + background-color: #4e73df;
67 +}
68 +.p img{
69 + width:100%;
70 + height:100%;
71 + object-fit:contain;
72 +}
73 +.ex{
74 + width: 147.5px;
75 + height:147.5px;
76 + float : left;
77 + margin :0.5px;
78 + background-color: #4e73df;
79 +}
80 +.ex img{
81 + width:100%;
82 + height:100%;
83 + object-fit:contain;
84 +}
...\ No newline at end of file ...\ No newline at end of file
1 +
2 +.all{
3 + width :100%;
4 + height :100%;
5 +}
6 +.top{
7 + width :100%;
8 + height :15%;
9 + float:left;
10 +}
11 +.title{
12 + width :80%;
13 + height :10%;
14 + float:left;
15 +}
16 +.title img{
17 + height: 80px;
18 + width : auto;
19 + margin-left : 20px;
20 + float:left;
21 +}
22 +.title img:hover{
23 + opacity:0.6;
24 +}
25 +#btn_area{
26 + width:20%;
27 + height :15%;
28 + float:left;
29 + vertical-align: middle;
30 +}
31 +#start{
32 + border: 1px solid #4e73df;
33 + background-color: #4e73df;
34 + line-height: 1;
35 + font-size: 17px;
36 + width: 150px;
37 + height :40px;
38 + padding:10px 15px;
39 + display: block;
40 + box-sizing: border-box;
41 + border-radius: 60px;
42 + color: white;
43 + font-weight: 100;
44 + letter-spacing: 0.01em;
45 + position: relative;
46 + z-index: 1;
47 + margin-top: -5px;
48 +}
49 +#next{
50 + border: 1px solid #4e73df;
51 + background-color: #4e73df;
52 + line-height: 1;
53 + font-size: 14px;
54 + width: 150px;
55 + height :40px;
56 + padding:10px 15px;
57 + display: block;
58 + box-sizing: border-box;
59 + border-radius: 60px;
60 + color: white;
61 + font-weight: 100;
62 + letter-spacing: 0.01em;
63 + position: relative;
64 + z-index: 1;
65 + visibility: hidden;
66 + margin-top: -5px;
67 +}
68 +#start:hover{
69 + background-color: white;
70 + color: #4e73df;
71 +}
72 +p.float_left{
73 + float:left;
74 +}
75 +.chart_cont{
76 + position:absolute;
77 + height:79%;
78 + width:27%;
79 + left : 3%;
80 + bottom :5%;
81 + overflow-y: auto;
82 + float:left;
83 + border:2px solid #4e73df;
84 +}
85 +.chart-container{
86 + position: relative;
87 + height:600px;
88 + width:280px;
89 +}
90 +#content{
91 + width :65%;
92 + height :79%;
93 + position: absolute;
94 + right : 3%;
95 + bottom:5%;
96 + overflow-y: auto;
97 + float:left;
98 + border:2px solid #4e73df;
99 +}
100 +.photo {
101 + width: 300px;
102 + height: 220px;
103 + margin : 5px;
104 + float:left;
105 + border:1px dashed #4e73df;
106 +}
107 +.p_title{
108 + width: 300px;
109 + height: 20px;
110 + float:left;
111 + text-align: center;
112 +}
113 +.p_title p{
114 + font-size : 13px;
115 + color: black;
116 + font-weight: bold;
117 + margin-top: -0.5px;
118 +}
119 +.image{
120 + height : 200px;
121 + width : 200px;
122 + text-align: center;
123 + float:left;
124 +}
125 +.image img{
126 + width:100%;
127 + height:100%;
128 + object-fit:contain;
129 +}
130 +.keyword{
131 + width :99%;
132 + height: 15%;
133 + float:left;
134 + text-align: center;
135 +}
136 +.k_content{
137 + width :99%;
138 + height: 85%;
139 + float:left;
140 + text-align: center;
141 + overflow-y: auto;
142 +}
143 +.keyword_photo{
144 + float:left;
145 + border:1px dashed #4e73df;
146 + height : 200px;
147 + width : 200px;
148 + text-align: center;
149 + margin : 10px;
150 +}
151 +.keyword_photo img{
152 + width:100%;
153 + height:100%;
154 + object-fit:contain;
155 +}
156 +.labels{
157 + width :100px;
158 + height : 200px;
159 + float :left;
160 + vertical-align: middle;
161 +}
162 +.labels p{
163 + font-size : 10px;
164 + margin-top: -0.2px;
165 + margin-bottom: -0.2px;
166 + margin-left :2px;
167 + color: navy;
168 +}
...\ No newline at end of file ...\ No newline at end of file
1 +.div_root{
2 + width:100%;
3 + height:100%;
4 + margin:0px;
5 +}
6 +.div_top{
7 + width:100%;
8 + height:20%;
9 + float:left;
10 +}
11 +.div_top img{
12 + margin-left: 20px;
13 + height:120px;
14 + float:left;
15 +}
16 +.div_top img:hover{
17 + opacity: 0.6;
18 +}
19 +.div_content{
20 + width : 100%;
21 + height: 80%;
22 + float:left;
23 +}
24 +.div_con_block{
25 + width:80%;
26 + height:25%;
27 + float:left;
28 + margin-left: 50px;
29 +}
30 +.div_con_block p{
31 + margin-left : 30px;
32 + margin-top: -10px;
33 + color : dimgray;
34 +}
35 +.div_con_block img{
36 + padding :20px;
37 + height : 100px;
38 +}
39 +.div_con_block img:hover{
40 + opacity: 0.5;
41 +}
42 +.fa-chevron-left{
43 + margin-top: 10px;
44 + margin-left :5px;
45 + margin-right : 5px;
46 + color: dimgray;
47 +}
48 +.fa-chevron-left:hover{
49 + opacity: 0.5;
50 +}
51 +.float_left{
52 + float :left;
53 +}
54 +#image{
55 + font-size: 15px;
56 + height :30px;
57 + width : 300px;
58 + float: left;
59 + margin:20px;
60 + border: 1px solid dimgray;
61 + background-color: dimgray;
62 +}
1 +
2 +.all{
3 + width :100%;
4 + height :100%;
5 +}
6 +.top{
7 + width :100%;
8 + height :15%;
9 + float:left;
10 +}
11 +#title{
12 + width :60%;
13 + height :15%;
14 + float:left;
15 +}
16 +#title img{
17 + height: 100px;
18 + width : auto;
19 + margin-left : 20px;
20 + float:left;
21 +}#title img:hover{
22 + opacity: 0.6;
23 +}
24 +#btn_area{
25 + width:40%;
26 + height :15%;
27 + float:left;
28 + vertical-align: middle;
29 +}
30 +#start{
31 + border: 1px solid dimgray;
32 + background-color: dimgray;
33 + line-height: 1;
34 + font-size: 17px;
35 + width: 150px;
36 + height :40px;
37 + padding:10px 15px;
38 + display: block;
39 + box-sizing: border-box;
40 + color: white;
41 + font-weight: 100;
42 + letter-spacing: 0.01em;
43 + position: relative;
44 + z-index: 1;
45 + margin-left : 20px;
46 +}
47 +#start:hover{
48 + background-color: white;
49 + color: dimgray;
50 +}
51 +button.p_btn{
52 + border: 1px solid dimgray;
53 + background-color: dimgray;
54 + line-height: 1;
55 + font-size: 17px;
56 + width: 50px;
57 + height :50px;
58 + padding:10px 15px;
59 + display: block;
60 + box-sizing: border-box;
61 + color: white;
62 + font-weight: 100;
63 + letter-spacing: 0.01em;
64 + position: relative;
65 + z-index: 1;
66 +}
67 +button.p_btn:hover{
68 + background-color: white;
69 + color: dimgray;
70 +}
71 +#date{
72 + border: 1px solid dimgray;
73 + background-color: white;
74 + line-height: 1;
75 + font-size: 17px;
76 + width: 200px;
77 + height :40px;
78 + padding:10px 15px;
79 + display: block;
80 + box-sizing: border-box;
81 + border-radius: 60px;
82 + color: dimgray;
83 + font-weight: 100;
84 + letter-spacing: 0.01em;
85 + position: relative;
86 + z-index: 1;
87 + margin-left: 10px;
88 +}
89 +p.float_left{
90 + float:left;
91 +}
92 +p.float_right{
93 + float:right;
94 +}
95 +#content{
96 + width :90%;
97 + height :80%;
98 + overflow-y: auto;
99 + position: absolute;
100 + left : 5%;
101 + bottom:5%;
102 + background-color: #FFFFFF;
103 +}
104 +/* -----------------------------------------------
105 +* Timeline
106 +* --------------------------------------------- */
107 +.main-timeline{
108 + font-family: 'Roboto Condensed', sans-serif;
109 + position: relative;
110 +}
111 +.main-timeline:after{
112 + content: '';
113 + display: block;
114 + clear: both;
115 +}
116 +.main-timeline:before{
117 + content: '';
118 + height: 100%;
119 + width: 7px;
120 + border-left: 7px dashed #999;
121 + transform: translateX(-50%);
122 + position: absolute;
123 + left: 50%;
124 + top: 0;
125 +}
126 +.main-timeline .timeline{
127 + width: 45%;
128 + padding: 0 0 0 40px;
129 + margin: 0 0 0 20px;
130 + float: right;
131 + position: relative;
132 +}
133 +.main-timeline .timeline:after{
134 + content: '';
135 + background-color: #6044F0;
136 + height: 35px;
137 + width: 40px;
138 + position: absolute;
139 + left: 0;
140 + top: 60px;
141 + clip-path: polygon(0 50%, 100% 0, 100% 100%);
142 +}
143 +.main-timeline .timeline-content{
144 + color: #555;
145 + text-align: center;
146 + padding: 35px 40px 35px;
147 + display: block;
148 + position: relative;
149 + z-index: 1;
150 +}
151 +.main-timeline .timeline-content:hover{ text-decoration: none; }
152 +.main-timeline .timeline-content:before,
153 +.main-timeline .timeline-content:after{
154 + content: '';
155 + background-color: #fff;
156 + border-radius: 50px 0;
157 + box-shadow: 0 0 10px -3px rgba(0,0,0,0.5);
158 + position: absolute;
159 + left: 10px;
160 + bottom: 10px;
161 + right: 0;
162 + top: 0;
163 + z-index: -1;
164 +}
165 +.main-timeline .timeline-content:after{
166 + background-color: transparent;
167 + box-shadow: none;
168 + border: 2px solid #6044F0;
169 + left: 0;
170 + bottom: 0;
171 + right: 10px;
172 + top: 10px;
173 +}
174 +.main-timeline .timeline-icon{
175 + color: #fff;
176 + background-color: #000;
177 + font-size: 25px;
178 + text-align: center;
179 + line-height: 50px;
180 + height: 50px;
181 + width: 50px;
182 + border-radius: 50%;
183 + position: absolute;
184 + left: 0;
185 + top: 0;
186 + z-index: 2;
187 +}
188 +.main-timeline .title{
189 + color: #6044F0;
190 + font-size: 20px;
191 + font-weight: 700;
192 + text-transform: uppercase;
193 + letter-spacing: 1px;
194 + margin: 0 0 5px;
195 +}
196 +.main-timeline .description{
197 + font-size: 15px;
198 + font-weight: 500;
199 + letter-spacing: 1px;
200 + margin: 0 0 0 10px;
201 +}
202 +.main-timeline .timeline:nth-child(even){
203 + float: left;
204 + padding: 0 40px 0 0;
205 + margin: 0 20px 0 0;
206 +}
207 +.main-timeline .timeline:nth-child(even):after{
208 + transform: rotateY(180deg);
209 + left: auto;
210 + right: 0;
211 +}
212 +.main-timeline .timeline:nth-child(even) .timeline-content:before,
213 +.main-timeline .timeline:nth-child(even) .timeline-content:after{
214 + border-radius: 0 50px;
215 +}
216 +.main-timeline .timeline:nth-child(even) .timeline-icon{
217 + left: auto;
218 + right: 0;
219 +}
220 +.main-timeline .timeline:nth-child(4n+2):after{ background-color: #FF3754; }
221 +.main-timeline .timeline:nth-child(4n+2) .timeline-content:after{ border-color: #FF3754; }
222 +.main-timeline .timeline:nth-child(4n+2) .title{ color: #FF3754; }
223 +.main-timeline .timeline:nth-child(4n+3):after{ background-color: #01C1E1; }
224 +.main-timeline .timeline:nth-child(4n+3) .timeline-content:after{ border-color: #01C1E1; }
225 +.main-timeline .timeline:nth-child(4n+3) .title{ color: #01C1E1; }
226 +.main-timeline .timeline:nth-child(4n+4):after{ background-color: #10B175; }
227 +.main-timeline .timeline:nth-child(4n+4) .timeline-content:after{ border-color: #10B175; }
228 +.main-timeline .timeline:nth-child(4n+4) .title{ color: #10B175; }
229 +@media screen and (max-width:767px){
230 + .main-timeline:before{ display: none; }
231 + .main-timeline .timeline,
232 + .main-timeline .timeline:nth-child(even){
233 + width: 100%;
234 + padding: 0 0 35px 0;
235 + margin: 0;
236 + }
237 + .main-timeline .timeline:last-child{ padding: 0; }
238 + .main-timeline .timeline:after,
239 + .main-timeline .timeline:nth-child(even):after{
240 + transform: translateX(-50%) rotate(-90deg);
241 + left: 50%;
242 + top: auto;
243 + bottom: 0;
244 + }
245 + .main-timeline .timeline:last-child:after{ display: none; }
246 +}
247 +@media screen and (max-width:576px){
248 + .main-timeline .title{ font-size: 18px; }
249 +}
250 +p.text-right{
251 + text-align: right;
252 +}
253 +.shadow-textarea textarea.form-control::placeholder {
254 + font-weight: 300;
255 +}
256 +.shadow-textarea textarea.form-control {
257 + padding-left: 0.8rem;
258 + padding-right: 0.8rem;
259 + width:80%;
260 + margin-top: 10px;
261 + margin-left:5px;
262 +}
263 +.fa-chevron-left{
264 + margin-left :5px;
265 + margin-right : 5px;
266 + color: dimgray;
267 +}
268 +.fa-chevron-left:hover{
269 + opacity: 0.5;
270 +}
...\ No newline at end of file ...\ No newline at end of file
1 -const { app, BrowserWindow, ipcMain } = require('electron') 1 +const { app, BrowserWindow, ipcMain, dialog } = require('electron')
2 const path = require('path') 2 const path = require('path')
3 const url = require('url') 3 const url = require('url')
4 +const vision = require('@google-cloud/vision');
4 5
5 // Keep a global reference of the window object, if you don't, the window will 6 // Keep a global reference of the window object, if you don't, the window will
6 // be closed automatically when the JavaScript object is garbage collected. 7 // be closed automatically when the JavaScript object is garbage collected.
...@@ -52,6 +53,153 @@ app.on('activate', ()=>{ ...@@ -52,6 +53,153 @@ app.on('activate', ()=>{
52 ipcMain.on("device-name", (e, arg) => { 53 ipcMain.on("device-name", (e, arg) => {
53 win.webContents.send("device", arg); 54 win.webContents.send("device", arg);
54 }); 55 });
56 +
57 +//photos taken in selected dates
58 + ipcMain.on("photo", (e, arg) => {
59 + win.webContents.send("select_result", arg);
60 + });
61 +
62 + //open-file-dialog
63 + ipcMain.on('open-file-dialog', async (event) => {
64 +
65 + const result = await dialog.showOpenDialog({
66 + properties: ['openFile', 'openDirectory']
67 + })
68 + win.webContents.send('selected-directory',result);
69 + })
70 +
71 + //console 출력
72 + ipcMain.on('print', (e, arg)=>{
73 + console.log(arg);
74 + })
75 +
76 + //internet connect 확인
77 + /**
78 + * const check = require('check-internet-connected');
79 +
80 + const config = {
81 + timeout : 5000,
82 + retries : 3,
83 + domain : 'apple.com'
84 + }
85 +
86 + check(config)
87 + .then(()=>{
88 + console.log("Connection available");
89 + }).catch((err)=>{
90 + console.log("No connection", err);
91 + });
92 + */
93 + //이미지 라벨
94 + var label_result = new Array();
95 + ipcMain.on('image_labels', async (event, list) =>{
96 + label_result = [];
97 + await Promise.all(list.map(async (element)=>{
98 + var path = new String();
99 + path = element.path;
100 + var num = path.indexOf("DCIM");
101 + var folder_path = new String();
102 + folder_path = "./photos/" + path.substring(num);
103 + await quickstart(folder_path, element.display_name);
104 + }))
105 + //라벨 검출 결과 전송
106 + win.webContents.send('labels_result',label_result);
107 + console.log(label_result.length);
108 + })
109 +
110 + async function quickstart(path, name) {
111 +
112 + const client = new vision.ImageAnnotatorClient();
113 +
114 + // Performs label detection on the image file
115 + const [result] = await client.labelDetection(path);
116 + const labels = result.labelAnnotations;
117 +
118 + path = '../.'+path;
119 + var content = {path : path, name : name, labels : labels}
120 + label_result.push(content);
121 + }
55 122
56 123
57 -
...\ No newline at end of file ...\ No newline at end of file
124 + //detext unsafe image
125 + let detect_result = new Array();
126 +
127 + ipcMain.on("detect", async (e, result)=>{
128 + detect_result = [];
129 + await Promise.all(result.map(async (element)=>{
130 + var path = new String();
131 + path = element.path;
132 + var num = path.indexOf("DCIM");
133 + var folder_path = new String();
134 + folder_path = "./photos/" + path.substring(num);
135 + await detect(folder_path, element.display_name);
136 + }))
137 + win.webContents.send('detect_result', detect_result);
138 + console.log("detect_success");
139 + });
140 +
141 + async function detect(path, name){
142 + //const vision = require('@google-cloud/vision');
143 + // Creates a client
144 + const client = new vision.ImageAnnotatorClient();
145 + // Performs safe search detection on the local file
146 + const [result] = await client.safeSearchDetection(path);
147 + const detections = result.safeSearchAnnotation;
148 +
149 + var adult_sum = 0;
150 + var racy_sum = 0;
151 +
152 + if(detections.adult == "VERY_LIKELY"){
153 + adult_sum = 100;
154 + }
155 + else if(detections.adult == "LIKELY"){
156 + adult_sum = 80;
157 + }
158 + else if(detections.adult == "POSSIBLE"){
159 + adult_sum = 60;
160 + }
161 + else if(detections.adult == "UNLIKELY"){
162 + adult_sum = 40;
163 + }
164 + else if(detections.adult == "VERY_UNLIKELY"){
165 + adult_sum = 20;
166 + }
167 + else{
168 + adult_sum = 0;
169 + }
170 +
171 + if(detections.racy == "VERY_LIKELY"){
172 + racy_sum = 100;
173 + }
174 + else if(detections.racy == "LIKELY"){
175 + racy_sum = 80;
176 + }
177 + else if(detections.racy == "POSSIBLE"){
178 + racy_sum = 60;
179 + }
180 + else if(detections.racy == "UNLIKELY"){
181 + racy_sum = 40;
182 + }
183 + else if(detections.racy == "VERY_UNLIKELY"){
184 + racy_sum = 20;
185 + }
186 + else{
187 + racy_sum = 0;
188 + }
189 +
190 + var score = (adult_sum + racy_sum) / 2;
191 +
192 + path = '../.'+path;
193 +
194 + if(score>=60){
195 + var content = {path : path, name : name, score : score};
196 + detect_result.push(content);
197 + }
198 +
199 + }
200 + ipcMain.on('open-error-dialog', (event) => {
201 + dialog.showErrorBox('detected unsafe contents', '당신의 휴대폰에서 유해한 사진을 발견했습니다!')
202 + })
203 +//이전에 사용한 photos 폴더 삭제
204 +var rimraf = require("rimraf");
205 +rimraf("./photos", function(){console.log("")});
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -29,6 +29,45 @@ ...@@ -29,6 +29,45 @@
29 "sumchecker": "^3.0.1" 29 "sumchecker": "^3.0.1"
30 } 30 }
31 }, 31 },
32 + "@google-cloud/promisify": {
33 + "version": "2.0.1",
34 + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.1.tgz",
35 + "integrity": "sha512-82EQzwrNauw1fkbUSr3f+50Bcq7g4h0XvLOk8C5e9ABkXYHei7ZPi9tiMMD7Vh3SfcdH97d1ibJ3KBWp2o1J+w=="
36 + },
37 + "@google-cloud/vision": {
38 + "version": "2.0.0",
39 + "resolved": "https://registry.npmjs.org/@google-cloud/vision/-/vision-2.0.0.tgz",
40 + "integrity": "sha512-e7/Ohh23TqKXPd9JDXOIGjGknoejycMMnsTNxFwGG2jCTlxXMbIbEU60BQ8oQEuc5+YjYhqceng1hfV5aFq94g==",
41 + "requires": {
42 + "@google-cloud/promisify": "^2.0.0",
43 + "google-gax": "^2.3.1",
44 + "is": "^3.3.0"
45 + }
46 + },
47 + "@grpc/grpc-js": {
48 + "version": "1.0.5",
49 + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.0.5.tgz",
50 + "integrity": "sha512-Hm+xOiqAhcpT9RYM8lc15dbQD7aQurM7ZU8ulmulepiPlN7iwBXXwP3vSBUimoFoApRqz7pSIisXU8pZaCB4og==",
51 + "requires": {
52 + "semver": "^6.2.0"
53 + },
54 + "dependencies": {
55 + "semver": {
56 + "version": "6.3.0",
57 + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
58 + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
59 + }
60 + }
61 + },
62 + "@grpc/proto-loader": {
63 + "version": "0.5.4",
64 + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.4.tgz",
65 + "integrity": "sha512-HTM4QpI9B2XFkPz7pjwMyMgZchJ93TVkL3kWPW8GDMDKYxsMnmf4w2TNMJK7+KNiYHS5cJrCEAFlF+AwtXWVPA==",
66 + "requires": {
67 + "lodash.camelcase": "^4.3.0",
68 + "protobufjs": "^6.8.6"
69 + }
70 + },
32 "@jimp/bmp": { 71 "@jimp/bmp": {
33 "version": "0.9.8", 72 "version": "0.9.8",
34 "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.9.8.tgz", 73 "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.9.8.tgz",
...@@ -379,6 +418,60 @@ ...@@ -379,6 +418,60 @@
379 "core-js": "^3.4.1" 418 "core-js": "^3.4.1"
380 } 419 }
381 }, 420 },
421 + "@protobufjs/aspromise": {
422 + "version": "1.1.2",
423 + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
424 + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78="
425 + },
426 + "@protobufjs/base64": {
427 + "version": "1.1.2",
428 + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
429 + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
430 + },
431 + "@protobufjs/codegen": {
432 + "version": "2.0.4",
433 + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
434 + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
435 + },
436 + "@protobufjs/eventemitter": {
437 + "version": "1.1.0",
438 + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
439 + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A="
440 + },
441 + "@protobufjs/fetch": {
442 + "version": "1.1.0",
443 + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
444 + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=",
445 + "requires": {
446 + "@protobufjs/aspromise": "^1.1.1",
447 + "@protobufjs/inquire": "^1.1.0"
448 + }
449 + },
450 + "@protobufjs/float": {
451 + "version": "1.0.2",
452 + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
453 + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E="
454 + },
455 + "@protobufjs/inquire": {
456 + "version": "1.1.0",
457 + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
458 + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik="
459 + },
460 + "@protobufjs/path": {
461 + "version": "1.1.2",
462 + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
463 + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0="
464 + },
465 + "@protobufjs/pool": {
466 + "version": "1.1.0",
467 + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
468 + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q="
469 + },
470 + "@protobufjs/utf8": {
471 + "version": "1.1.0",
472 + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
473 + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA="
474 + },
382 "@sindresorhus/is": { 475 "@sindresorhus/is": {
383 "version": "0.14.0", 476 "version": "0.14.0",
384 "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", 477 "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
...@@ -394,12 +487,25 @@ ...@@ -394,12 +487,25 @@
394 "defer-to-connect": "^1.0.1" 487 "defer-to-connect": "^1.0.1"
395 } 488 }
396 }, 489 },
490 + "@types/long": {
491 + "version": "4.0.1",
492 + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz",
493 + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w=="
494 + },
397 "@types/node": { 495 "@types/node": {
398 "version": "12.12.34", 496 "version": "12.12.34",
399 "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.34.tgz", 497 "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.34.tgz",
400 "integrity": "sha512-BneGN0J9ke24lBRn44hVHNeDlrXRYF+VRp0HbSUNnEZahXGAysHZIqnf/hER6aabdBgzM4YOV4jrR8gj4Zfi0g==", 498 "integrity": "sha512-BneGN0J9ke24lBRn44hVHNeDlrXRYF+VRp0HbSUNnEZahXGAysHZIqnf/hER6aabdBgzM4YOV4jrR8gj4Zfi0g==",
401 "dev": true 499 "dev": true
402 }, 500 },
501 + "abort-controller": {
502 + "version": "3.0.0",
503 + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
504 + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
505 + "requires": {
506 + "event-target-shim": "^5.0.0"
507 + }
508 + },
403 "accepts": { 509 "accepts": {
404 "version": "1.3.7", 510 "version": "1.3.7",
405 "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", 511 "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
...@@ -424,6 +530,14 @@ ...@@ -424,6 +530,14 @@
424 "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", 530 "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
425 "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" 531 "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
426 }, 532 },
533 + "agent-base": {
534 + "version": "6.0.0",
535 + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz",
536 + "integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==",
537 + "requires": {
538 + "debug": "4"
539 + }
540 + },
427 "ajv": { 541 "ajv": {
428 "version": "6.12.0", 542 "version": "6.12.0",
429 "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", 543 "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
...@@ -574,6 +688,11 @@ ...@@ -574,6 +688,11 @@
574 "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", 688 "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
575 "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" 689 "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog=="
576 }, 690 },
691 + "arrify": {
692 + "version": "2.0.1",
693 + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
694 + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug=="
695 + },
577 "asn1": { 696 "asn1": {
578 "version": "0.2.4", 697 "version": "0.2.4",
579 "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 698 "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
...@@ -776,6 +895,11 @@ ...@@ -776,6 +895,11 @@
776 "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", 895 "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz",
777 "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=" 896 "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs="
778 }, 897 },
898 + "buffer-equal-constant-time": {
899 + "version": "1.0.1",
900 + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
901 + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
902 + },
779 "buffer-from": { 903 "buffer-from": {
780 "version": "1.1.1", 904 "version": "1.1.1",
781 "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 905 "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
...@@ -823,6 +947,32 @@ ...@@ -823,6 +947,32 @@
823 "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 947 "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
824 "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 948 "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
825 }, 949 },
950 + "chart.js": {
951 + "version": "2.9.3",
952 + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.3.tgz",
953 + "integrity": "sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw==",
954 + "requires": {
955 + "chartjs-color": "^2.1.0",
956 + "moment": "^2.10.2"
957 + }
958 + },
959 + "chartjs-color": {
960 + "version": "2.4.1",
961 + "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz",
962 + "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==",
963 + "requires": {
964 + "chartjs-color-string": "^0.6.0",
965 + "color-convert": "^1.9.3"
966 + }
967 + },
968 + "chartjs-color-string": {
969 + "version": "0.6.0",
970 + "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
971 + "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
972 + "requires": {
973 + "color-name": "^1.0.0"
974 + }
975 + },
826 "clone-response": { 976 "clone-response": {
827 "version": "1.0.2", 977 "version": "1.0.2",
828 "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", 978 "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
...@@ -837,6 +987,26 @@ ...@@ -837,6 +987,26 @@
837 "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 987 "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
838 "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" 988 "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
839 }, 989 },
990 + "color-convert": {
991 + "version": "1.9.3",
992 + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
993 + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
994 + "requires": {
995 + "color-name": "1.1.3"
996 + },
997 + "dependencies": {
998 + "color-name": {
999 + "version": "1.1.3",
1000 + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
1001 + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
1002 + }
1003 + }
1004 + },
1005 + "color-name": {
1006 + "version": "1.1.4",
1007 + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
1008 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
1009 + },
840 "combined-stream": { 1010 "combined-stream": {
841 "version": "1.0.8", 1011 "version": "1.0.8",
842 "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 1012 "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
...@@ -1021,6 +1191,17 @@ ...@@ -1021,6 +1191,17 @@
1021 "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", 1191 "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
1022 "dev": true 1192 "dev": true
1023 }, 1193 },
1194 + "duplexify": {
1195 + "version": "3.7.1",
1196 + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
1197 + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
1198 + "requires": {
1199 + "end-of-stream": "^1.0.0",
1200 + "inherits": "^2.0.1",
1201 + "readable-stream": "^2.0.0",
1202 + "stream-shift": "^1.0.0"
1203 + }
1204 + },
1024 "ecc-jsbn": { 1205 "ecc-jsbn": {
1025 "version": "0.1.2", 1206 "version": "0.1.2",
1026 "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 1207 "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
...@@ -1030,6 +1211,14 @@ ...@@ -1030,6 +1211,14 @@
1030 "safer-buffer": "^2.1.0" 1211 "safer-buffer": "^2.1.0"
1031 } 1212 }
1032 }, 1213 },
1214 + "ecdsa-sig-formatter": {
1215 + "version": "1.0.11",
1216 + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
1217 + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
1218 + "requires": {
1219 + "safe-buffer": "^5.0.1"
1220 + }
1221 + },
1033 "electron": { 1222 "electron": {
1034 "version": "8.2.0", 1223 "version": "8.2.0",
1035 "resolved": "https://registry.npmjs.org/electron/-/electron-8.2.0.tgz", 1224 "resolved": "https://registry.npmjs.org/electron/-/electron-8.2.0.tgz",
...@@ -1137,6 +1326,11 @@ ...@@ -1137,6 +1326,11 @@
1137 "dev": true, 1326 "dev": true,
1138 "optional": true 1327 "optional": true
1139 }, 1328 },
1329 + "event-target-shim": {
1330 + "version": "5.0.1",
1331 + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
1332 + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
1333 + },
1140 "exif-parser": { 1334 "exif-parser": {
1141 "version": "0.1.12", 1335 "version": "0.1.12",
1142 "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", 1336 "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz",
...@@ -1188,6 +1382,11 @@ ...@@ -1188,6 +1382,11 @@
1188 "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 1382 "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
1189 "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" 1383 "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
1190 }, 1384 },
1385 + "fast-text-encoding": {
1386 + "version": "1.0.2",
1387 + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.2.tgz",
1388 + "integrity": "sha512-5rQdinSsycpzvAoHga2EDn+LRX1d5xLFsuNG0Kg61JrAT/tASXcLL0nf/33v+sAxlQcfYmWbTURa1mmAf55jGw=="
1389 + },
1191 "fd-slicer": { 1390 "fd-slicer": {
1192 "version": "1.1.0", 1391 "version": "1.1.0",
1193 "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", 1392 "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
...@@ -1283,6 +1482,27 @@ ...@@ -1283,6 +1482,27 @@
1283 "wide-align": "^1.1.0" 1482 "wide-align": "^1.1.0"
1284 } 1483 }
1285 }, 1484 },
1485 + "gaxios": {
1486 + "version": "3.0.3",
1487 + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.0.3.tgz",
1488 + "integrity": "sha512-PkzQludeIFhd535/yucALT/Wxyj/y2zLyrMwPcJmnLHDugmV49NvAi/vb+VUq/eWztATZCNcb8ue+ywPG+oLuw==",
1489 + "requires": {
1490 + "abort-controller": "^3.0.0",
1491 + "extend": "^3.0.2",
1492 + "https-proxy-agent": "^5.0.0",
1493 + "is-stream": "^2.0.0",
1494 + "node-fetch": "^2.3.0"
1495 + }
1496 + },
1497 + "gcp-metadata": {
1498 + "version": "4.1.0",
1499 + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.1.0.tgz",
1500 + "integrity": "sha512-r57SV28+olVsflPlKyVig3Muo/VDlcsObMtvDGOEtEJXj+DDE8bEl0coIkXh//hbkSDTvo+f5lbihZOndYXQQQ==",
1501 + "requires": {
1502 + "gaxios": "^3.0.0",
1503 + "json-bigint": "^0.3.0"
1504 + }
1505 + },
1286 "get-stream": { 1506 "get-stream": {
1287 "version": "4.1.0", 1507 "version": "4.1.0",
1288 "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", 1508 "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
...@@ -1361,6 +1581,58 @@ ...@@ -1361,6 +1581,58 @@
1361 "define-properties": "^1.1.3" 1581 "define-properties": "^1.1.3"
1362 } 1582 }
1363 }, 1583 },
1584 + "google-auth-library": {
1585 + "version": "6.0.1",
1586 + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.0.1.tgz",
1587 + "integrity": "sha512-NWEM9W0o+fmUJMK/wEuJ1vAc8H/JAseOWB8tjOAAkz8yobU+5IDtO/rPCbbRwFF1obIOCe0lj1pkq9ld2OFZeg==",
1588 + "requires": {
1589 + "arrify": "^2.0.0",
1590 + "base64-js": "^1.3.0",
1591 + "ecdsa-sig-formatter": "^1.0.11",
1592 + "fast-text-encoding": "^1.0.0",
1593 + "gaxios": "^3.0.0",
1594 + "gcp-metadata": "^4.1.0",
1595 + "gtoken": "^5.0.0",
1596 + "jws": "^4.0.0",
1597 + "lru-cache": "^5.0.0"
1598 + }
1599 + },
1600 + "google-gax": {
1601 + "version": "2.6.1",
1602 + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.6.1.tgz",
1603 + "integrity": "sha512-AKQKfaaXCJhMrP4nniz/ei7j+uyqG7nNrGmQxDBIBtDMUbZUMnH0Kw8asts35vmciEV5UeIWfclVcAU+VaJptw==",
1604 + "requires": {
1605 + "@grpc/grpc-js": "~1.0.0",
1606 + "@grpc/proto-loader": "^0.5.1",
1607 + "@types/long": "^4.0.0",
1608 + "abort-controller": "^3.0.0",
1609 + "duplexify": "^3.6.0",
1610 + "google-auth-library": "^6.0.0",
1611 + "is-stream-ended": "^0.1.4",
1612 + "lodash.at": "^4.6.0",
1613 + "lodash.has": "^4.5.2",
1614 + "node-fetch": "^2.6.0",
1615 + "protobufjs": "^6.9.0",
1616 + "retry-request": "^4.0.0",
1617 + "semver": "^6.0.0",
1618 + "walkdir": "^0.4.0"
1619 + },
1620 + "dependencies": {
1621 + "semver": {
1622 + "version": "6.3.0",
1623 + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
1624 + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
1625 + }
1626 + }
1627 + },
1628 + "google-p12-pem": {
1629 + "version": "3.0.1",
1630 + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.1.tgz",
1631 + "integrity": "sha512-VlQgtozgNVVVcYTXS36eQz4PXPt9gIPqLOhHN0QiV6W6h4qSCNVKPtKC5INtJsaHHF2r7+nOIa26MJeJMTaZEQ==",
1632 + "requires": {
1633 + "node-forge": "^0.9.0"
1634 + }
1635 + },
1364 "got": { 1636 "got": {
1365 "version": "9.6.0", 1637 "version": "9.6.0",
1366 "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", 1638 "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
...@@ -1385,6 +1657,24 @@ ...@@ -1385,6 +1657,24 @@
1385 "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", 1657 "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
1386 "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" 1658 "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
1387 }, 1659 },
1660 + "gtoken": {
1661 + "version": "5.0.1",
1662 + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.0.1.tgz",
1663 + "integrity": "sha512-33w4FNDkUcyIOq/TqyC+drnKdI4PdXmWp9lZzssyEQKuvu9ZFN3KttaSnDKo52U3E51oujVGop93mKxmqO8HHg==",
1664 + "requires": {
1665 + "gaxios": "^3.0.0",
1666 + "google-p12-pem": "^3.0.0",
1667 + "jws": "^4.0.0",
1668 + "mime": "^2.2.0"
1669 + },
1670 + "dependencies": {
1671 + "mime": {
1672 + "version": "2.4.6",
1673 + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz",
1674 + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA=="
1675 + }
1676 + }
1677 + },
1388 "har-schema": { 1678 "har-schema": {
1389 "version": "2.0.0", 1679 "version": "2.0.0",
1390 "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 1680 "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
...@@ -1440,6 +1730,15 @@ ...@@ -1440,6 +1730,15 @@
1440 "sshpk": "^1.7.0" 1730 "sshpk": "^1.7.0"
1441 } 1731 }
1442 }, 1732 },
1733 + "https-proxy-agent": {
1734 + "version": "5.0.0",
1735 + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
1736 + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
1737 + "requires": {
1738 + "agent-base": "6",
1739 + "debug": "4"
1740 + }
1741 + },
1443 "ieee754": { 1742 "ieee754": {
1444 "version": "1.1.13", 1743 "version": "1.1.13",
1445 "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", 1744 "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
...@@ -1471,6 +1770,11 @@ ...@@ -1471,6 +1770,11 @@
1471 "dev": true, 1770 "dev": true,
1472 "optional": true 1771 "optional": true
1473 }, 1772 },
1773 + "is": {
1774 + "version": "3.3.0",
1775 + "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz",
1776 + "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg=="
1777 + },
1474 "is-fullwidth-code-point": { 1778 "is-fullwidth-code-point": {
1475 "version": "1.0.0", 1779 "version": "1.0.0",
1476 "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 1780 "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
...@@ -1484,6 +1788,16 @@ ...@@ -1484,6 +1788,16 @@
1484 "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", 1788 "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz",
1485 "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=" 1789 "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU="
1486 }, 1790 },
1791 + "is-stream": {
1792 + "version": "2.0.0",
1793 + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
1794 + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw=="
1795 + },
1796 + "is-stream-ended": {
1797 + "version": "0.1.4",
1798 + "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz",
1799 + "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw=="
1800 + },
1487 "is-typedarray": { 1801 "is-typedarray": {
1488 "version": "1.0.0", 1802 "version": "1.0.0",
1489 "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 1803 "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
...@@ -1555,6 +1869,21 @@ ...@@ -1555,6 +1869,21 @@
1555 } 1869 }
1556 } 1870 }
1557 }, 1871 },
1872 + "json-bigint": {
1873 + "version": "0.3.0",
1874 + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz",
1875 + "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=",
1876 + "requires": {
1877 + "bignumber.js": "^7.0.0"
1878 + },
1879 + "dependencies": {
1880 + "bignumber.js": {
1881 + "version": "7.2.1",
1882 + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz",
1883 + "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ=="
1884 + }
1885 + }
1886 + },
1558 "json-buffer": { 1887 "json-buffer": {
1559 "version": "3.0.0", 1888 "version": "3.0.0",
1560 "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", 1889 "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
...@@ -1596,6 +1925,25 @@ ...@@ -1596,6 +1925,25 @@
1596 "verror": "1.10.0" 1925 "verror": "1.10.0"
1597 } 1926 }
1598 }, 1927 },
1928 + "jwa": {
1929 + "version": "2.0.0",
1930 + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
1931 + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
1932 + "requires": {
1933 + "buffer-equal-constant-time": "1.0.1",
1934 + "ecdsa-sig-formatter": "1.0.11",
1935 + "safe-buffer": "^5.0.1"
1936 + }
1937 + },
1938 + "jws": {
1939 + "version": "4.0.0",
1940 + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
1941 + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
1942 + "requires": {
1943 + "jwa": "^2.0.0",
1944 + "safe-buffer": "^5.0.1"
1945 + }
1946 + },
1599 "keyv": { 1947 "keyv": {
1600 "version": "3.1.0", 1948 "version": "3.1.0",
1601 "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", 1949 "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
...@@ -1641,6 +1989,16 @@ ...@@ -1641,6 +1989,16 @@
1641 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 1989 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
1642 "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" 1990 "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
1643 }, 1991 },
1992 + "lodash.at": {
1993 + "version": "4.6.0",
1994 + "resolved": "https://registry.npmjs.org/lodash.at/-/lodash.at-4.6.0.tgz",
1995 + "integrity": "sha1-k83OZk8KGZTqM9181A4jr9EbD/g="
1996 + },
1997 + "lodash.camelcase": {
1998 + "version": "4.3.0",
1999 + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
2000 + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY="
2001 + },
1644 "lodash.defaults": { 2002 "lodash.defaults": {
1645 "version": "4.2.0", 2003 "version": "4.2.0",
1646 "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", 2004 "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
...@@ -1656,6 +2014,11 @@ ...@@ -1656,6 +2014,11 @@
1656 "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", 2014 "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
1657 "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" 2015 "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8="
1658 }, 2016 },
2017 + "lodash.has": {
2018 + "version": "4.5.2",
2019 + "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz",
2020 + "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI="
2021 + },
1659 "lodash.isplainobject": { 2022 "lodash.isplainobject": {
1660 "version": "4.0.6", 2023 "version": "4.0.6",
1661 "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", 2024 "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
...@@ -1666,6 +2029,11 @@ ...@@ -1666,6 +2029,11 @@
1666 "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", 2029 "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz",
1667 "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" 2030 "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg="
1668 }, 2031 },
2032 + "long": {
2033 + "version": "4.0.0",
2034 + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
2035 + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
2036 + },
1669 "lowercase-keys": { 2037 "lowercase-keys": {
1670 "version": "1.0.1", 2038 "version": "1.0.1",
1671 "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", 2039 "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
...@@ -1821,6 +2189,16 @@ ...@@ -1821,6 +2189,16 @@
1821 "resolved": "https://registry.npmjs.org/node-adb/-/node-adb-0.1.6.tgz", 2189 "resolved": "https://registry.npmjs.org/node-adb/-/node-adb-0.1.6.tgz",
1822 "integrity": "sha512-wai4LqO1NQJVeGerMTSln/Sp0vwuPmod9G0aRJJmgo0tk5wBAmyqUQ74wgcZIn0Ja9BCkBOmyz0LEA6nE8dWIg==" 2190 "integrity": "sha512-wai4LqO1NQJVeGerMTSln/Sp0vwuPmod9G0aRJJmgo0tk5wBAmyqUQ74wgcZIn0Ja9BCkBOmyz0LEA6nE8dWIg=="
1823 }, 2191 },
2192 + "node-fetch": {
2193 + "version": "2.6.0",
2194 + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
2195 + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
2196 + },
2197 + "node-forge": {
2198 + "version": "0.9.1",
2199 + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz",
2200 + "integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ=="
2201 + },
1824 "normalize-path": { 2202 "normalize-path": {
1825 "version": "3.0.0", 2203 "version": "3.0.0",
1826 "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 2204 "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
...@@ -2041,6 +2419,33 @@ ...@@ -2041,6 +2419,33 @@
2041 "dev": true, 2419 "dev": true,
2042 "optional": true 2420 "optional": true
2043 }, 2421 },
2422 + "protobufjs": {
2423 + "version": "6.9.0",
2424 + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.9.0.tgz",
2425 + "integrity": "sha512-LlGVfEWDXoI/STstRDdZZKb/qusoAWUnmLg9R8OLSO473mBLWHowx8clbX5/+mKDEI+v7GzjoK9tRPZMMcoTrg==",
2426 + "requires": {
2427 + "@protobufjs/aspromise": "^1.1.2",
2428 + "@protobufjs/base64": "^1.1.2",
2429 + "@protobufjs/codegen": "^2.0.4",
2430 + "@protobufjs/eventemitter": "^1.1.0",
2431 + "@protobufjs/fetch": "^1.1.0",
2432 + "@protobufjs/float": "^1.0.2",
2433 + "@protobufjs/inquire": "^1.1.0",
2434 + "@protobufjs/path": "^1.1.2",
2435 + "@protobufjs/pool": "^1.1.0",
2436 + "@protobufjs/utf8": "^1.1.0",
2437 + "@types/long": "^4.0.1",
2438 + "@types/node": "^13.7.0",
2439 + "long": "^4.0.0"
2440 + },
2441 + "dependencies": {
2442 + "@types/node": {
2443 + "version": "13.13.11",
2444 + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.11.tgz",
2445 + "integrity": "sha512-FX7mIFKfnGCfq10DGWNhfCNxhACEeqH5uulT6wRRA1KEt7zgLe0HdrAd9/QQkObDqp2Z0KEV3OAmNgs0lTx5tQ=="
2446 + }
2447 + }
2448 + },
2044 "psl": { 2449 "psl": {
2045 "version": "1.8.0", 2450 "version": "1.8.0",
2046 "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", 2451 "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
...@@ -2147,6 +2552,15 @@ ...@@ -2147,6 +2552,15 @@
2147 "lowercase-keys": "^1.0.0" 2552 "lowercase-keys": "^1.0.0"
2148 } 2553 }
2149 }, 2554 },
2555 + "retry-request": {
2556 + "version": "4.1.1",
2557 + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.1.1.tgz",
2558 + "integrity": "sha512-BINDzVtLI2BDukjWmjAIRZ0oglnCAkpP2vQjM3jdLhmT62h0xnQgciPwBRDAvHqpkPT2Wo1XuUyLyn6nbGrZQQ==",
2559 + "requires": {
2560 + "debug": "^4.1.1",
2561 + "through2": "^3.0.1"
2562 + }
2563 + },
2150 "rimraf": { 2564 "rimraf": {
2151 "version": "3.0.2", 2565 "version": "3.0.2",
2152 "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", 2566 "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
...@@ -2379,6 +2793,11 @@ ...@@ -2379,6 +2793,11 @@
2379 "through": "~2.3.4" 2793 "through": "~2.3.4"
2380 } 2794 }
2381 }, 2795 },
2796 + "stream-shift": {
2797 + "version": "1.0.1",
2798 + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
2799 + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ=="
2800 + },
2382 "string-width": { 2801 "string-width": {
2383 "version": "1.0.2", 2802 "version": "1.0.2",
2384 "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 2803 "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
...@@ -2455,6 +2874,14 @@ ...@@ -2455,6 +2874,14 @@
2455 "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 2874 "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
2456 "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 2875 "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
2457 }, 2876 },
2877 + "through2": {
2878 + "version": "3.0.1",
2879 + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz",
2880 + "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==",
2881 + "requires": {
2882 + "readable-stream": "2 || 3"
2883 + }
2884 + },
2458 "timm": { 2885 "timm": {
2459 "version": "1.6.2", 2886 "version": "1.6.2",
2460 "resolved": "https://registry.npmjs.org/timm/-/timm-1.6.2.tgz", 2887 "resolved": "https://registry.npmjs.org/timm/-/timm-1.6.2.tgz",
...@@ -2601,6 +3028,11 @@ ...@@ -2601,6 +3028,11 @@
2601 "extsprintf": "^1.2.0" 3028 "extsprintf": "^1.2.0"
2602 } 3029 }
2603 }, 3030 },
3031 + "walkdir": {
3032 + "version": "0.4.1",
3033 + "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz",
3034 + "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ=="
3035 + },
2604 "which": { 3036 "which": {
2605 "version": "2.0.2", 3037 "version": "2.0.2",
2606 "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 3038 "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
......
...@@ -12,12 +12,15 @@ ...@@ -12,12 +12,15 @@
12 "electron": "^8.2.0" 12 "electron": "^8.2.0"
13 }, 13 },
14 "dependencies": { 14 "dependencies": {
15 + "@google-cloud/vision": "^2.0.0",
15 "appium-adb": "^7.27.1", 16 "appium-adb": "^7.27.1",
17 + "chart.js": "^2.9.3",
16 "jQuery": "^1.7.4", 18 "jQuery": "^1.7.4",
17 "jquery": "^3.5.0", 19 "jquery": "^3.5.0",
18 "mysql": "^2.18.1", 20 "mysql": "^2.18.1",
19 "node-adb": "^0.1.6", 21 "node-adb": "^0.1.6",
20 "python-shell": "^2.0.0", 22 "python-shell": "^2.0.0",
23 + "rimraf": "^3.0.2",
21 "socket.io": "^2.3.0" 24 "socket.io": "^2.3.0"
22 } 25 }
23 } 26 }
......
...@@ -32,12 +32,12 @@ ...@@ -32,12 +32,12 @@
32 </div> 32 </div>
33 <div id ="menu"> 33 <div id ="menu">
34 <div id="btn_group"> 34 <div id="btn_group">
35 - <button id="btn" onclick="location.href='menu5.html'">menu5</button> 35 + <button id="btn" onclick="location.href='photo_classification/photo_main.html'">menu5</button>
36 </div> 36 </div>
37 </div> 37 </div>
38 <div id ="menu"> 38 <div id ="menu">
39 <div id="btn_group"> 39 <div id="btn_group">
40 - <button id="btn" onclick="location.href='menu6.html'">menu6</button> 40 + <button id="btn" onclick="location.href='timeline.html'">menu6</button>
41 </div> 41 </div>
42 </div> 42 </div>
43 </div> 43 </div>
......
1 +<!DOCTYPE html>
2 +<html lang="en">
3 +<head>
4 + <meta charset="UTF-8">
5 + <meta name="viewport" content="width=<sc>, initial-scale=1.0">
6 + <link rel="Stylesheet" href="../../assets/css/p_date.css">
7 + <title>Photo classification by date</title>
8 +</head>
9 +<body>
10 + <div class="content">
11 + <div class="win_top">
12 + <div id="title">
13 + <img src="../../assets/img/photo_date.png" onclick="history.go(-1)" class="float_left" title="Back to photo menu">
14 + </div>
15 + <div id="date">
16 + <p class="float_left"><button id="select">Select date</button></p>
17 + <p class="float_left"><button id="save_photo">Save photo</button></p>
18 + <p class="float_left" id="selected-date"></p>
19 + <p class="float_left" id="selected-file"></p>
20 + </div>
21 + </div>
22 +
23 + <div class="results" id="r">
24 + <h1 style="margin-top:300px; color:dimgray">날짜를 선택해 해당 기간동안의 사진을 확인하세요</h1>
25 + </div>
26 + </div>
27 +
28 +
29 +
30 + <script type="text/javascript">
31 + const { ipcRenderer } = require("electron");
32 + const { BrowserWindow } = require("electron").remote;
33 + var exec = require('child_process').exec, child;
34 +
35 + const btn = document.getElementById("select");
36 + const saveBtn = document.getElementById("save_photo");
37 +
38 + btn.addEventListener("click", () => {
39 + win = new BrowserWindow({
40 + width: 630,
41 + height: 100,
42 + frame: false,
43 + alwaysOnTop: true,
44 + webPreferences: {
45 + nodeIntegration: true
46 + }
47 + });
48 +
49 + //win.webContents.openDevTools();
50 + win.on("close", () => {
51 + win = null;
52 + });
53 + win.loadFile("./src/photo_classification/select_date.html");
54 + win.show();
55 +
56 + });
57 +
58 + saveBtn.addEventListener("click", () =>{
59 + var checkbox = document.getElementsByName('save');
60 + ipcRenderer.send('open-file-dialog');
61 + })
62 +
63 + ipcRenderer.on('selected-directory', (event, path) => {
64 + var parent_dir = new String();
65 + var num = __dirname.indexOf("src");
66 + parent_dir = __dirname.substring(0, num);
67 + if(!path.canceled){
68 + var checkbox = document.getElementsByName('save');
69 + checkbox.forEach(element => {
70 + if(element.checked){
71 + var loc = element.value.indexOf("photos");
72 + var imgpath = new String();
73 + imgpath = parent_dir+element.value.substring(loc).replace(/\//g,'\\').replace(/#%&!/g, " ");
74 + var command = 'copy "'+imgpath+'" '+path.filePaths[0];
75 + //document.getElementById('selected-file').innerHTML = command;
76 + exec(command, (error, stdout, stderr)=>{
77 + if(!error){
78 + document.getElementById('selected-file').innerHTML = "saved!";
79 + }
80 + });
81 + }
82 + })
83 + }
84 +
85 + })
86 +
87 + let result;
88 +
89 + ipcRenderer.on("select_result", (e, arg) => {
90 + result = arg.result;
91 + document.getElementById('selected-date').innerHTML = arg.start + " - " +arg.end;
92 + print_photo();
93 + });
94 +
95 + function print_photo(){
96 + const results = document.getElementById('r');
97 + var myHTML = '';
98 + for(var i = 0; i< result.length; i++){
99 + var path = new String();
100 + path = result[i].path;
101 + var num = path.indexOf("DCIM");
102 + var folder_path = new String();
103 + folder_path = "../../photos/"+ path.substring(num);
104 + myHTML += '<div class="photo"><div class="top"><img id="p" src="'+folder_path
105 + +'"></div><div class="bottom"><div class="name"><p id="title">'+result[i].display_name+'</p></div>';
106 + var replacement = folder_path.replace(/ /g, "#%&!");
107 + myHTML +="<div class='check'><input type='checkbox' name='save' value="+replacement+"></div></div></div>"
108 + }
109 + results.innerHTML = myHTML;
110 + saveBtn.style.visibility = "visible";
111 + };
112 + </script>
113 +</body>
114 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +<!DOCTYPE html>
2 +<html lang="en">
3 +<head>
4 + <meta charset="UTF-8">
5 + <meta name="viewport" content="width=<sc>, initial-scale=1.0">
6 + <script src="https://kit.fontawesome.com/e6f667a852.js" crossorigin="anonymous"></script>
7 + <link rel="Stylesheet" href="../../assets/css/p_detect.css">
8 + <title></title>
9 +</head>
10 +<body>
11 + <div class="content">
12 + <div class="win_top">
13 + <div id="title">
14 + <img src="../../assets/img/Detect unsafe Image.png" onclick="history.go(-1)" class="float_left" title="Back to photo menu">
15 + </div>
16 + <div id="date">
17 + <p class="float_left"><button id="detect">Start</button></p>
18 + </div>
19 + </div>
20 + <div class="results" id="r">
21 + <h1 style="margin-top:300px; color:dimgray">유해한 컨텐츠를 검사해 보세요</h1>
22 + </div>
23 + </div>
24 +</body>
25 +<script src="p_detect.js"></script>
26 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +var exec = require('child_process').exec, child;
2 +const { ipcRenderer } = require("electron");
3 +
4 +const dd = document.getElementById('detect');
5 +const r = document.getElementById('r');
6 + var mysql = require('mysql');
7 +
8 + var connection = mysql.createConnection({
9 + user:'root',
10 + password:'1234',
11 + database : 'dataextraction'
12 + })
13 +
14 +dd.addEventListener("click", ()=>{
15 +
16 + connection.connect();
17 + connection.query('SELECT * FROM photo', function(error, results, fields){
18 + if(error){
19 + }
20 + else{
21 + r.innerHTML = '<i class="fas fa-spinner fa-3x fa-spin" style="color:dimgray; position: absolute; bottom:47%; right:47%;"></i>';
22 + ipcRenderer.send("detect", results);
23 + }
24 + });
25 +});
26 +
27 +ipcRenderer.on('detect_result', (e, detect_result)=>{
28 + if(detect_result.length >0){
29 + r.style.border ="2px solid red";
30 + var myhtml = "<h1 style='font-size:1.5em'>유해 컨텐츠 "+detect_result.length+" 개 발견</h1>";
31 + detect_result.forEach(element => {
32 + myhtml+="<img src='"+element.path+"' id='image' onclick='showImage()' title='"+element.path+"'width=300px height=300px>";
33 + });
34 + r.innerHTML = myhtml;
35 + ipcRenderer.send('open-error-dialog')
36 + }
37 + else{
38 + r.innerHTML = "<h1 style='margin-top:300px; color:dimgray'>유해 컨텐츠 없음</h1>";
39 + }
40 +});
41 +
42 +function showImage(){
43 + var image = document.getElementById('image');
44 + var url=image.getAttribute('src');
45 + var imgWin = window.open(url,url, "width=500px, height=500px");
46 +};
47 +
48 +
1 +<!DOCTYPE html>
2 +<html lang="en">
3 +<head>
4 + <meta charset="UTF-8">
5 + <meta name="viewport" content="width=<sc>, initial-scale=1.0">
6 + <link rel="Stylesheet" href="../../assets/css/p_loc.css">
7 + <title>Photo classification by location</title>
8 + <style></style>
9 +</head>
10 +<body>
11 + <div class='all'>
12 + <div class='top'>
13 + <div class='title'>
14 + <img src="../../assets/img/photo_loc.png" onclick="history.go(-1)" class="float_left" title="Back to photo menu">
15 + </div>
16 + </div>
17 + <div class='content'>
18 + <div id="main">
19 + <h1 style="margin-top:250px; color:dimgray; text-align: center;">지도의 마크를 클릭해 해당 사진과 인근 위치에서 찍힌 사진을 확인하세요.</h1>
20 + </div>
21 + <div id="explanation">
22 +
23 + </div>
24 + <div id="map"></div>
25 + </div>
26 + </div>
27 +
28 +
29 + <script type=text/javascript>
30 +
31 + var mysql = require('mysql');
32 + //mysql 연동
33 + var connection = mysql.createConnection({
34 + user:'root',
35 + password:'1234',
36 + database : 'dataextraction'
37 + })
38 +
39 + connection.connect();
40 + var list;
41 + function initMap() {
42 +
43 + connection.query('SELECT * FROM photo where latitude is not null', function(error, results, fields){
44 + if(error){
45 + }
46 + else{
47 + list = results;
48 + var first_p = {lat: Number(list[0].latitude), lng: Number(list[0].longitude)};
49 + var map = new google.maps.Map(document.getElementById('map'), {
50 + zoom: 8,
51 + center: first_p
52 + });
53 +
54 + list.forEach(element => {
55 + var latlng = {lat : Number(element.latitude), lng : Number(element.longitude)};
56 +
57 + var time = new Date(Number(element.date_added)*1000);
58 + var path = new String();
59 + path = element.path;
60 + var num = path.indexOf("DCIM");
61 + var folder_path = new String();
62 + folder_path = "../../photos/" + path.substring(num);
63 + var address = new String();
64 + var geocoder = new google.maps.Geocoder;
65 + geocoder.geocode({'location' : latlng}, function(results, status){
66 + var marker = new google.maps.Marker({
67 + position: latlng,
68 + map: map,
69 + title: element.display_name
70 + });
71 + if(status == 'OK'){
72 + if(results[0]){
73 + address = results[0].formatted_address;
74 + var contentString = '<div id="content">'+
75 + '<div id="siteNotice">'+
76 + '</div>'+
77 + '<h1 id="firstHeading" class="firstHeading">'+element.title+'</h1>'+
78 + '<div id="bodyContent">'+
79 + '<p><b>'+element.display_name+'</b></p><p><b>'+time+'</b </p><p>'+
80 + results[0].formatted_address+'</p></div>'+
81 + '</div>';
82 + var infowindow = new google.maps.InfoWindow({
83 + content: contentString,
84 + maxWidth: 300
85 + });
86 + marker.addListener('click', function() {
87 + infowindow.open(map, marker);
88 + p_group(element);
89 + });
90 + }
91 + else{
92 + var contentString = '<div id="content">'+
93 + '<div id="siteNotice">'+
94 + '</div>'+
95 + '<h1 id="firstHeading" class="firstHeading">'+element.title+'</h1>'+
96 + '<div id="bodyContent">'+
97 + '<p><b>'+element.display_name+'</b></p><p><b>'+time+'</b </p><p>('+
98 + latlng.lat+','+latlng.lng+'</p></div>'+
99 + '</div>';
100 + var infowindow = new google.maps.InfoWindow({
101 + content: contentString,
102 + maxWidth: 300
103 + });
104 + marker.addListener('click', function() {
105 + infowindow.open(map, marker);
106 + p_group(element);
107 + });
108 + }
109 + }
110 + else{
111 + var contentString = '<div id="content">'+
112 + '<div id="siteNotice">'+
113 + '</div>'+
114 + '<h1 id="firstHeading" class="firstHeading">'+element.title+'</h1>'+
115 + '<div id="bodyContent">'+
116 + '<p><b>'+element.display_name+'</b></p><p><b>'+time+'</b </p><p>('+
117 + latlng.lat+','+latlng.lng+')</p></div>'+
118 + '</div>';
119 + var infowindow = new google.maps.InfoWindow({
120 + content: contentString,
121 + maxWidth: 300
122 + });
123 + marker.addListener('click', function() {
124 + infowindow.open(map, marker);
125 + p_group(element);
126 + });
127 + }
128 + });
129 +
130 + });
131 + }
132 + })
133 + }
134 +
135 + function p_group(photo){
136 + const main = document.getElementById('main');
137 + var path = new String();
138 + path = photo.path;
139 + var num = path.indexOf("DCIM");
140 + var folder_path = new String();
141 + folder_path = "../../photos/" + path.substring(num);
142 + var myHTML = '';
143 + myHTML += '<div class="p"><img src="'+folder_path+'"></div>';
144 + list.forEach(element=>{
145 + if(element.title != photo.title){
146 + var hor = photo.latitude - Number(element.latitude);
147 + hor *=111;
148 + var ver = photo.longitude - Number(element.longitude);
149 + ver *=88;
150 + if(((hor*hor) + (ver*ver))<=25){
151 + main.innerHTML = "<p>Bye</p>"
152 + var path2 = new String();
153 + path2 = element.path;
154 + var num2 = path2.indexOf("DCIM");
155 + var folder_path2 = new String();
156 + folder_path2 = "../../photos/" + path2.substring(num2);
157 + myHTML += '<div class="ex"><img id="ex" src="'+folder_path2+'"></div>';
158 +
159 + }
160 + }
161 +
162 + });
163 + main.innerHTML = myHTML;
164 + document.getElementById('explanation').innerHTML = "<h1>[ "+photo.display_name+" ]</h1><h1>5km 인근 사진 모음</h1>"
165 + }
166 + </script>
167 +<script async defer
168 +src="http://maps.google.com/maps/api/js?key=API_KEY&callback=initMap&sensor=true">
169 +</script>
170 +</body>
171 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +<!DOCTYPE html>
2 +<html lang="en">
3 +<head>
4 + <meta charset="UTF-8">
5 + <meta name="viewport" content="width=<sc>, initial-scale=1.0">
6 + <link rel="Stylesheet" href="../../assets/css/p_ml.css">
7 + <script src="https://kit.fontawesome.com/e6f667a852.js" crossorigin="anonymous"></script>
8 + <title>Photo Analysis by Google vision api</title>
9 +</head>
10 +<body>
11 +<div class="all">
12 + <div class="top">
13 + <div class="title">
14 + <img src="../../assets/img/analysis.png" onclick="history.go(-1)" class="float_left" title="Back to photo menu">
15 + </div>
16 + <div id="btn_area">
17 + <p ><button id="start">Start Analysis</button></p>
18 + <p ><button id="next">Back to all photos</button></p>
19 + </div>
20 + </div>
21 + <div class ="chart_cont">
22 + <div class="chart-container">
23 + <canvas id="chart"></canvas>
24 + </div>
25 + </div>
26 +
27 + <div id="content">
28 + <h1 style="margin-top:250px; color:dimgray; text-align: center;">"Start Analysis" 버튼을 눌러 사진 분석을 시작하세요</h1>
29 + <h2 style="color:dimgray; text-align: center;">(시간이 다소 소요될 수 있습니다)</h2>
30 + </div>
31 +</div>
32 + <script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
33 + <script src="p_ml.js"></script>
34 +</body>
35 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +const { ipcRenderer } = require("electron");
2 +const { BrowserWindow } = require("electron").remote;
3 +const content = document.getElementById('content');
4 +const btn = document.getElementById('start');
5 +const next = document.getElementById('next');
6 +const Chart = require("chart.js");
7 +const ctx = document.getElementById("chart").getContext('2d');;
8 +var list_length = new Array();
9 +let l_list = new Array();
10 +let p_list = new Array();
11 +
12 +var mysql = require('mysql');
13 +var list;
14 +
15 +//mysql 연동
16 +var connection = mysql.createConnection({
17 + user:'root',
18 + password:'1234',
19 + database : 'dataextraction'
20 +})
21 +
22 +connection.connect();
23 +
24 +btn.addEventListener("click", ()=>{
25 + content.innerHTML = '<i class="fas fa-spinner fa-3x fa-spin" style="color:dimgray; position: absolute; bottom:45%; right:45%;"></i>';
26 +
27 + connection.query("SELECT * FROM photo" , function(error, results, fields){
28 + if(error){
29 + }
30 + else{
31 + list = results;
32 + ipcRenderer.send('image_labels', list );
33 + }
34 +
35 + });
36 +
37 +})
38 +
39 +var label_name = Array();
40 +var photo_list = Array();
41 +var label_result = Array();
42 +
43 +ipcRenderer.on("labels_result", (e, result) => {
44 + var myHTML = '';
45 + label_result = result;
46 + result.forEach(element=>{
47 + myHTML +="<div class='photo'><div class='p_title'><p>"+element.name+"</p></div>"
48 + myHTML += '<div class="image"><img src="'+element.path+'"></div><div class ="labels">';
49 + element.labels.forEach(label=>{
50 + myHTML+='<p> #'+label.description+'</p>';
51 + find_labellist(label.description, element.path);
52 + });
53 + myHTML+='</div></div>';
54 + })
55 + content.innerHTML = myHTML;
56 + make_chart();
57 +});
58 +
59 +function find_labellist(label, path){
60 + var idx = label_name.indexOf(label);
61 + if(idx == -1){
62 + label_name.push(label);
63 + photo_list.push([path.toString()]);
64 + }
65 + else{
66 + photo_list[idx].push(path.toString());
67 + }
68 +}
69 +
70 +function make_chart(){
71 + for(var i =0; i< photo_list.length; i++){
72 + for(var j = i+1; j <photo_list.length; j++){
73 + if(photo_list[j].length > photo_list[i].length){
74 + var tmp = Array();
75 + tmp = photo_list[i];
76 + photo_list[i] = photo_list[j];
77 + photo_list[j] = tmp;
78 + var str = String();
79 + str = label_name[i];
80 + label_name[i] = label_name[j];
81 + label_name[j] = str;
82 + }
83 + }
84 + }
85 + l_list = label_name;
86 + p_list = photo_list;
87 + myHTML = String();
88 + photo_list.forEach(element => {
89 + list_length.push(element.length);
90 + });
91 +
92 + var mychart = new Chart(ctx,{
93 + type: 'horizontalBar',
94 + data :{
95 + labels : label_name.slice(0, 20),
96 + datasets:[{
97 + label : "nums of images",
98 + data : list_length.slice(0, 20),
99 + borderSkipped:'top',
100 + borderWidth :1,
101 + borderColor : '#FCE2A9',
102 + backgroundColor:'#FCE2A9',
103 + hoverBorderWidth: 2,
104 + barPercentage: 0.8,
105 + categoryPercentage:1,
106 + }],
107 + },
108 + options:{
109 + maintainAspectRatio: false,
110 + title: {
111 + display: true,
112 + text: 'PHOTO KEYWORD'
113 + },
114 + scales: {
115 + xAxes: [{
116 + stacked: true,
117 + gridLines:{
118 + offsetGridLines :true,
119 + },
120 + ticks:{
121 + beginAtZero :true
122 + }
123 + }],
124 + yAxes: [{
125 + ticks :{
126 + fontSize : 10
127 + },
128 + stacked: true,
129 + }]
130 + },
131 + tooltips: {
132 + callbacks: {
133 + labelColor: function(tooltipItem, chart) {
134 + return {
135 + borderColor : '#FCE2A9',
136 + backgroundColor:'#FCE2A9',
137 + };
138 + },
139 + labelTextColor: function(tooltipItem, chart) {
140 + return '#FFFFFF';
141 + }
142 + }
143 + },
144 + onClick : function(e){
145 + var activePoints = mychart.getElementsAtEvent(e);
146 + var idx= activePoints[0]._index;
147 + var myHTML = '<div class="keyword"><h1>#'+label_name[idx]+'</h1></div><div class="k_content">';
148 + photo_list[idx].forEach(photo=>{
149 + myHTML += '<div class="keyword_photo"><img src="'+photo+'"></div>';
150 + });
151 + myHTML+="</div>"
152 + document.getElementById("next").style.visibility = "visible";
153 + content.style.overflowY = "hidden";
154 + content.innerHTML = myHTML;
155 + },
156 + layout:{
157 + padding:{
158 + left:0,
159 + right:0,
160 + top:10,
161 + bottom:0,
162 + }
163 + }
164 + }
165 +
166 + })
167 +}
168 +next.addEventListener("click", ()=>{
169 + var myHTML = '';
170 + label_result.forEach(element=>{
171 + myHTML +="<div class='photo'><div class='p_title'><p>"+element.name+"</p></div>"
172 + myHTML += '<div class="image"><img src="'+element.path+'"></div><div class ="labels">';
173 + element.labels.forEach(label=>{
174 + myHTML+='<p> #'+label.description+'</p>';
175 + });
176 + myHTML+='</div></div>';
177 +})
178 +content.innerHTML = myHTML;
179 +document.getElementById("next").style.visibility = "hidden";
180 +content.style.overflowY = "auto";
181 +});
1 +<!DOCTYPE html>
2 +<html lang="en">
3 +<head>
4 + <meta charset="UTF-8">
5 + <meta name="viewport" content="width=<sc>, initial-scale=1.0">
6 + <link rel="Stylesheet" href="../../assets/css/photo_main.css">
7 + <title>Photo</title>
8 +</head>
9 +<body>
10 + <div class="div_root">
11 + <div class="div_top">
12 + <img src="../../assets/img/Photo.png" onclick="history.go(-1)" title="Back to main menu">
13 + </div>
14 + <div class="div_content">
15 + <div class="div_con_block">
16 + <img src="../../assets/img/photo_date.png" onclick="location.href='p_date.html'" title="날짜로 사진 분류">
17 + </div>
18 + <div class="div_con_block">
19 + <img src="../../assets/img/photo_loc.png" onclick="location.href='p_loc.html'" title="위치로 사진 분류">
20 + </div>
21 + <div class="div_con_block">
22 + <img src="../../assets/img/analysis.png" onclick="location.href='p_ml.html'" title="사진 분석(이미지 키워드 추출)">
23 + </div>
24 + <div class="div_con_block">
25 + <img src="../../assets/img/Detect unsafe Image.png" onclick="location.href='p_detect.html'" title="유해한 이미지 감지">
26 + </div>
27 + </div>
28 + </div>
29 + <script src="photo_main.js"></script>
30 +</body>
31 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +const {exec} = require('child_process');
2 +const { ipcRenderer } = require("electron");
3 +var fs = require('fs');
4 +var mysql = require('mysql');
5 +
6 + //mysql 연동
7 + var connection = mysql.createConnection({
8 + user:'root',
9 + password:'1234',
10 + database : 'dataextraction'
11 + })
12 +
13 +var testFolder = './';
14 +
15 +fs.readdir(testFolder, function(error, filelist){
16 + const index = filelist.indexOf("photos");
17 + if(index == -1){
18 + photo_extract();
19 + }
20 + else{
21 + ipcRenderer.send("print", "already pulled");
22 + }
23 + })
24 +
25 +function photo_extract(){
26 + connection.connect();
27 + connection.query('SELECT path FROM photo', function(error, results, fields){
28 + if(error){
29 + }
30 + if(results.length>0){
31 + var path = new String();
32 + path = results[0].path;
33 + var num = path.indexOf("DCIM");
34 + folder_path = path.substring(0, num+4);
35 + //var folder_path = "/storage/emulated/0/DCIM"; //test용 path
36 +
37 + exec("adb pull "+folder_path+" ./photos", (error, stdout, stderr)=>{
38 + if(error){
39 + ipcRenderer.send("print", "휴대폰이 연결되어 있는지 확인");
40 + }
41 + else{
42 + ipcRenderer.send("print", "succes");
43 + }
44 + });
45 + }
46 + });
47 +}
1 +<!DOCTYPE html>
2 +<html>
3 +<head>
4 + <meta charset="UTF-8">
5 + <title>Hello World!</title>
6 + <meta name="viewport" content="width=device-width, initial-scale=1, script-src 'self' 'unsafe-inline'" />
7 + <link rel="Stylesheet" media="all" type="text/css" href="bower_components/jquery-mobile-bower/css/jquery.mobile-1.4.5.css" />
8 + <link rel="Stylesheet" href="../../assets/css/p_date.css">
9 + <style type="text/css" media="all">
10 + body { cursor: default; }
11 + </style>
12 +</head>
13 +<body>
14 + <div class="date">
15 + <p class="float_left"><input type="date" id="start_date" ></p>
16 + <p class="float_left"><input type="date" id="end_date" ></p>
17 + <p class="float_left"><button id="submit">Submit</button></p>
18 + <p class="float_left"><button id="closeBtn">X</button></p>
19 + </div>
20 + <script src="select_date.js"></script>
21 +</body>
22 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +const {remote, ipcRenderer} = require("electron");
2 +
3 +const closeBtn = document.getElementById("closeBtn");
4 +
5 +closeBtn.addEventListener("click", () => {
6 + let window = remote.getCurrentWindow();
7 + window.close();
8 +});
9 +
10 + var mysql = require('mysql');
11 +
12 + //mysql 연동
13 + var connection = mysql.createConnection({
14 + user:'root',
15 + password:'1234',
16 + database : 'dataextraction'
17 + })
18 +
19 + connection.connect();
20 +
21 + //최대 선택 가능 날짜 설정
22 + var today = new Date();
23 + document.getElementById("start_date").max = today.toISOString().substring(0, 10);
24 + document.getElementById("end_date").max = today.toISOString().substring(0, 10);
25 +
26 + const btn = document.getElementById("submit");
27 +
28 +
29 + btn.addEventListener("click", () => {
30 + var start_date = new String(document.getElementById("start_date").value);
31 + var end_date = new String(document.getElementById("end_date").value);
32 +
33 +
34 + var st = new Date(start_date);
35 + var et = new Date(end_date);
36 +
37 + st.setHours(st.getHours() - 9);
38 + et.setHours(et.getHours() + 15);
39 + et.setMilliseconds(et.getMilliseconds() -1);
40 +
41 + var sTimestamp =st.getTime();
42 + var eTimestamp =et.getTime();
43 +
44 + connection.query('SELECT * FROM photo WHERE date_added > "'+sTimestamp+'" AND date_added <= "'+eTimestamp+'" ORDER BY date_added', function(error, results, fields){
45 + if(error){
46 + }
47 + else{
48 + var arg={
49 + result : results,
50 + start : start_date,
51 + end : end_date
52 + }
53 + ipcRenderer.send(
54 + "photo",
55 + arg
56 + );
57 + let window = remote.getCurrentWindow();
58 + window.close();
59 + }
60 +
61 + } )
62 +
63 + });
64 +
...\ No newline at end of file ...\ No newline at end of file
1 +<!DOCTYPE html>
2 +<html lang="en">
3 +<head>
4 + <meta charset="UTF-8">
5 + <meta name="viewport" content="width=<sc>, initial-scale=1.0">
6 + <link rel="Stylesheet" href="../assets/css/timeline.css">
7 + <script src="https://kit.fontawesome.com/e6f667a852.js" crossorigin="anonymous"></script>
8 + <title>TimeLine</title>
9 +</head>
10 +<body>
11 +<div class="all">
12 + <div class="top">
13 + <div id="title">
14 + <img src="../assets/img/TimeLine.png" onclick="history.go(-1)" class="float_left" title="Back to main menu">
15 + </div>
16 + <div id="btn_area">
17 + <p class="float_left"><input type="date" id="date" ></p>
18 + <p class="float_left"><button id="start">타임라인 생성</button></p>
19 + </div>
20 + </div>
21 +
22 + <div id="content">
23 + <div class="container">
24 + <div class="row">
25 + <div class="col-md-12">
26 + <div class="main-timeline" id="main">
27 +
28 + </div>
29 + </div>
30 + </div>
31 + </div>
32 + </div>
33 +</div>
34 +
35 + <script src="timeline.js"></script>
36 +</body>
37 +</html>
...\ No newline at end of file ...\ No newline at end of file
1 +const {remote, ipcRenderer} = require("electron");
2 +//const html2canvas = require("html2canvas");
3 +//const jsPDF = require("jspdf");
4 +
5 +const main = document.getElementById("main");
6 +const btn = document.getElementById("start");
7 +
8 +var today = new Date();
9 +document.getElementById("date").max = today.toISOString().substring(0, 10);
10 +var mysql = require('mysql');
11 +//mysql 연동
12 +
13 +var connection = mysql.createConnection({
14 + user:'root',
15 + password:'1234',
16 + database : 'dataextraction'
17 +})
18 +
19 +var photolist = new Array();
20 +var callloglist = new Array();
21 +var smslist = new Array();
22 +var usagelist = new Array();
23 +var callist = new Array();
24 +
25 +var img_src = [
26 + ["com.everytime.v2", "../assets/img/everytime.png"],
27 + ["kr.co.aladin.ebook", "../assets/img/aladin_ebook.png"],
28 + ["com.google.android.gm", "../assets/img/gmail.png"],
29 + ["kr.co.aladin.third_shop", "../assets/img/aladin.png"],
30 + ["com.google.android.talk", "../assets/img/hangout.png"],
31 + ["com.iloen.melon","../assets/img/melon.png"],
32 + ["com.instagram.android", "../assets/img/instagram.png"],
33 + ["com.twitter.android", "../assets/img/twitter.png"],
34 + ["com.kakao.talk", "../assets/img/kakaotalk.png"],
35 + ["com.google.android.youtube", "../assets/img/youtube.png"],
36 + ["com.snowcorp.soda.android", "../assets/img/soda.png"],
37 + ["com.nhn.android.blog", "../assets/img/nhnblog.png"],
38 + ["com.nhn.android.webtoon", "../assets/img/nhnwebtoon.png"]
39 +];
40 +
41 +connection.connect();
42 +
43 +btn.addEventListener("click", () => {
44 + var date = new String(document.getElementById("date").value);
45 + var datetype = new Date(date);
46 + datetype.setHours(datetype.getHours()-9);
47 + var day_start = datetype.getTime();
48 + datetype.setHours(datetype.getHours()+24);
49 + datetype.setSeconds(datetype.getMilliseconds()-1);
50 + var day_end = datetype.getTime();
51 + var s_date = date + " 00:00:00";
52 + var e_date = date + " 23:59:59";
53 +
54 +
55 + connection.query('SELECT * FROM calllog where date_format(date, "%Y-%m-%d %T") between ? and ?',[s_date, e_date], async function(error, results, fields){
56 + if(error){
57 + ipcRenderer.send("print", err);
58 + }
59 + else{
60 + callloglist = await results;
61 + }
62 + } ) ;
63 + connection.query('SELECT * FROM sms where date_format(date, "%Y-%m-%d %T") between ? and ?',[s_date, e_date], async function(error, results, fields){
64 + if(error){
65 + ipcRenderer.send("print", err);
66 + }
67 + else{
68 + smslist = await results;
69 + }
70 + } ) ;
71 + connection.query('SELECT * FROM calendar where date_format(dtstart, "%Y-%m-%d %T") between ? and ? and account_name <> "대한민국의 휴일" and account_name <> "Holiday Calendar"',[s_date, e_date], async function(error, results, fields){
72 + if(error){
73 + ipcRenderer.send("print", err);
74 + }
75 + else{
76 + callist = await results;
77 + }
78 + } ) ;
79 + connection.query("SELECT A.*, B.name as name FROM AppUsageDay A, AppInfo B WHERE A.lasttimeused between ? and ? and A.totaltimeforeground <> 0 and (A.packagename = B.packagename) order by totaltimeforeground desc",[day_start, day_end], async function(error, results, fields){
80 + if(error){
81 + ipcRenderer.send("print", err.msg);
82 + }
83 + else{
84 + usagelist = await results;
85 + }
86 + } ) ;
87 + day_start = day_start.toString().substring(0, 10);
88 + day_end = day_end.toString().substring(0, 10);
89 + connection.query('SELECT * FROM photo WHERE date_added between ? and ?',[day_start, day_end], async function(error, results, fields){
90 + if(error){
91 + ipcRenderer.send("print", err);
92 + }
93 + else{
94 + photolist = await results;
95 + makeTimeline();
96 + create.style.visibility = "visible";
97 + }
98 + } ) ;
99 +});
100 +
101 +
102 +
103 +function makeTimeline(){
104 + var timeline = new Array();
105 + photolist.forEach(element => {
106 + var time = new Date(Number(element.date_added)*1000).getTime();
107 + var latlng = {lat : Number(element.latitude), lng : Number(element.longitude)};
108 + var address = new String();
109 + /*geocoder.geocode({'location' : latlng}, async function(results, status){
110 + if(status == 'OK'){
111 + if(results[0]){
112 + address = await results[0].formatted_address;
113 + }
114 + }
115 + });
116 + */
117 + timeline.push([time, 0, element.display_name]);
118 + });
119 + callloglist.forEach(element =>{
120 + var time = new Date(element.date).getTime();
121 + timeline.push([time, 1, element.id]);
122 + });
123 + smslist.forEach(element=>{
124 + var time = new Date(element.date).getTime();
125 + timeline.push([time, 2, element.mid]);
126 + });
127 + callist.forEach(element=>{
128 + var time = new Date(element.dtstart).getTime();
129 + timeline.push([time, 3, element.id]);
130 + })
131 + usagelist.forEach(element=>{
132 + var time = new Date(Number(element.lasttimeused)- Number(element.totaltimeforeground)).getTime();
133 + timeline.push([time, 4, element.packagename, element.totaltimeforeground, element.name]);
134 + });
135 +
136 + for(var i = 0; i< timeline.length-1; i++){
137 + for(var j =i+1; j<timeline.length; j++){
138 + if(timeline[j][0] < timeline[i][0]){
139 + var tmp =timeline[i];
140 + timeline[i] = timeline[j];
141 + timeline[j] = tmp;
142 + }
143 + }
144 + }
145 +
146 + var myHTML = '';
147 + timeline.forEach(async function(element, idx){
148 + var time = new Date(element[0]);
149 + //time.setHours(time.getHours());
150 + var hour = time.getHours() % 12 || 12;
151 + var day_time = "AM";
152 + if(time.getHours() >= 12){
153 + day_time = "PM"
154 + }
155 + var t_str = hour.toString().padStart(2, '0') + ":" + time.getMinutes().toString().padStart(2,'0') + " " + day_time;
156 + if(element[1] == 0){
157 + //photo
158 + var photo = photolist.filter(function(photo){return photo.display_name == element[2]});
159 + var path = photo[0].path;
160 + var num = path.indexOf("DCIM");
161 + var folder_path = new String();
162 + folder_path = "../photos/"+ path.substring(num);
163 + myHTML += '<div class="timeline" >'
164 + +'<a href="#" class="timeline-content" id="photo'+idx.toString()+'">'
165 + +'<div class="timeline-icon">'
166 + +'<i class="fas fa-camera-retro"></i>'
167 + +'</div>'
168 + +'<h3 class="title">['+t_str+'] '+element[2]+'</h3>'
169 + +'<p class="description">'
170 + +'<img src="'+folder_path+'" style="width :300px;">'
171 + +'</p>'
172 + +'<p class="description">'
173 + +'<div class="form-group shadow-textarea">'
174 + +'<label for="exampleFormControlTextarea6"></label>'
175 + +'<textarea class="form-control z-depth-1" id="exampleFormControlTextarea6" rows="3" placeholder="Write something about this photo..."></textarea>'
176 + +'</div>'
177 + +'</a>'
178 + //+'<p class="float_right"><button class="p_btn" id="create'+idx.toString()+'" onclick="getPDF(this.id)">C</button></p>'
179 + +'</div>'
180 +
181 + }
182 + else if(element[1] == 1){
183 + //calllog
184 + var calllog = callloglist.filter(function(log){return log.id == element[2]});
185 + var type = '';
186 + if(calllog[0].type == 1){
187 + type = "수신"
188 + }
189 + else if(calllog[0].type == 2){
190 + type = "발신"
191 + }
192 + else if(calllog[0].type == 3){
193 + type = "부재 중"
194 + }
195 + else{
196 + type = "스팸"
197 + }
198 + myHTML += '<div class="timeline">'
199 + +'<a href="#" class="timeline-content">'
200 + +'<div class="timeline-icon">'
201 + +'<i class="fas fa-phone-alt"></i>'
202 + +'</div>'
203 + +'<h3 class="title">['+t_str+'] '+calllog[0].number+'</h3>'
204 + +'<p class="description"><b>'
205 + +type+'</b> '+ calllog[0].duration+'초'
206 + +'</p>'
207 + +'</a>'
208 + +'</div>'
209 + }
210 + else if(element[1] == 2){
211 + //sms
212 + var sms = smslist.filter(function(msg){return msg.mid == element[2]});
213 + var type = '';
214 + if(sms[0].type == 1){
215 + type = "수신"
216 + }
217 + else if(sms[0].type == 2){
218 + type = "발신"
219 + }
220 + else if(sms[0].type == 3){
221 + type = "부재 중"
222 + }
223 + else{
224 + type = "스팸"
225 + }
226 + myHTML += '<div class="timeline">'
227 + +'<a href="#" class="timeline-content">'
228 + +'<div class="timeline-icon">'
229 + +'<i class="fas fa-comments"></i>'
230 + +'</div>'
231 + +'<h3 class="title">['+t_str+'] '+sms[0].address+'</h3>'
232 + +'<p class="description"><b>'
233 + +type+'</b><br>'+ sms[0].body
234 + +'</p>'
235 + +'</a>'
236 + +'</div>'
237 + }
238 + else if(element[1] == 3){
239 + //calendar
240 + var cal = callist.filter(function(cal){return cal.id == element[2]});
241 + myHTML += '<div class="timeline">'
242 + +'<a href="#" class="timeline-content">'
243 + +'<div class="timeline-icon">'
244 + +'<i class="fas fa-calendar-check"></i>'
245 + +'</div>'
246 + +'<h3 class="title">['+t_str+'] '+cal[0].calendar_id+'</h3>'
247 + +'<p class="description">'
248 + +cal[0].event_location+'<br> '+ cal[0].description
249 + +'</p>'
250 + +'</a>'
251 + +'</div>'
252 + }
253 + else{
254 + //app usage
255 + var name = element[2].toString();
256 + if(name.indexOf("com.android") == -1 && name.indexOf("com.lge") == -1){
257 + var src = img_src.filter(function(app){return app[0] == name});
258 + var m = (Number(element[3])/60000).toFixed(2);
259 + if(src.length == 0){
260 + myHTML += '<div class="timeline">'
261 + +'<a href="#" class="timeline-content">'
262 + +'<div class="timeline-icon">'
263 + +'<i class="fas fa-mobile-alt"></i>'
264 + +'</div>'
265 + +'<h3 class="title">['+t_str+'] '+element[4]+'</h3>'
266 + +'<p class="description">'
267 + +'<br>사용 시간 : ' +m + '분'
268 + +'<img src="../assets/img/app.png" style="width :50px;position:absolute; right:10%; bottom:15%">'
269 + +'</p>'
270 + +'<p class="description">'
271 + +'</p>'
272 + +'</a>'
273 + +'</div>'
274 +
275 + }
276 + else{
277 + myHTML += '<div class="timeline">'
278 + +'<a href="#" class="timeline-content">'
279 + +'<div class="timeline-icon">'
280 + +'<i class="fas fa-mobile-alt"></i>'
281 + +'</div>'
282 + +'<h3 class="title">['+t_str+'] '+element[4]+'</h3>'
283 + +'<p class="description">'
284 + +'<br>사용 시간 : ' +m + '분'
285 + +'<img src="'+src[0][1]+'" style="width :50px;position:absolute; right:10%; bottom:15%">'
286 + +'</p>'
287 + +'</a>'
288 + +'</div>'
289 + }
290 + }
291 + }
292 + });
293 + main.innerHTML = myHTML;
294 +
295 +}
296 +/**
297 + * function getPDF(id){
298 + var index = id.substring(6);
299 + const pdf_wrap = document.getElementById('photo'+index);
300 + html2canvas(pdf_wrap).then(function(canvas){
301 + var doc = new jsPDF('p', 'mm', 'a4');
302 + var imgData = canvas.toDataURL('image/png');
303 + window.open(imgData, "test");
304 + doc.addImage(imgData, 'PNG', 0, 0);
305 + doc.save('photo'+index+'.pdf');
306 + });
307 +};
308 + */