1use crate::read_ebml::Process;
9use crate::read_ebml::Section;
10use crate::read_ebml::SubStep;
11use crate::read_ebml::Action;
12use crate::read_ebml::Requirement;
13use crate::read_ebml::Table;
14
15use std::fs::File;
16use std::fs::OpenOptions;
17use std::io::Write;
18
19pub fn generate_complete_html(filename:&String, p:&Process) {
24
25 let mut html_file = OpenOptions::new()
27 .read(true)
28 .write(true)
29 .create(true)
30 .open(filename)
31 .expect("cannot open file");
32
33 compose_top_of_html_file(&mut html_file);
35
36 compose_html_head(&mut html_file, &p);
38
39 compose_html_body(&mut html_file,&p,p.get_all_sections());
41
42 compose_bottom_of_html_file(&mut html_file);
44}
45
46fn compose_top_of_html_file(f:&mut File) {
48 f.write(b"<!DOCTYPE html>\n").expect("write failed");
49 f.write(b"<html lang=\"en-US\">\n\n").expect("write failed");
50}
51
52fn compose_bottom_of_html_file(f:&mut File) {
54 f.write(b"</html>").expect("write failed");
55}
56
57fn compose_html_head(f:&mut File,p:&Process) {
59 f.write(b"\t<head>\n").expect("write failed");
60
61 let temp_str = String::from("\t\t<title>") + p.get_number() + " \"" + p.get_title() + "\"</title>\n";
62 f.write(temp_str.as_bytes()).expect("write failed");
63 f.write(b"\t\t<meta charset=\"utf-8\" />\n").expect("write failed");
64 let temp_str = String::from("\t\t<meta name = \"keywords\" content = \"") + p.get_subject() + ", " + p.get_product() + "\" />\n";
65 f.write(temp_str.as_bytes()).expect("write failed");
66 let temp_str = String::from("\t\t<meta name = \"description\" content = \"") + p.get_number() + " " + p.get_title() + "\" />\n";
67 f.write(temp_str.as_bytes()).expect("write failed");
68 let temp_str = String::from("\t\t<meta name = \"author\" content = \"") + p.get_author() + "\" />\n";
69 f.write(temp_str.as_bytes()).expect("write failed");
70 f.write(b"\t\t<meta http-equiv = \"Content-Type\" content = \"text/html; charset = UTF-8\" />\n").expect("write failed");
71 f.write(b"\t\t<link rel=\"shortcut icon\" sizes=\"16x16 32x32 48x48\" type=\"image/png\" href=\"../assets/favicon.png\" />\n").expect("write failed");
72 f.write(b"\t\t<link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"../assets/favicon.png\" />\n").expect("write failed");
73 f.write(b"\t\t<link rel=\"mask-icon\" href=\"../assets/favicon.svg\" color=\"#000000\" />\n\n").expect("write failed");
74
75 f.write(b"\t\t<!-- The stanhope.css applies to every process, regardless of program -->\n").expect("write failed");
76 f.write(b"\t\t<link rel=\"stylesheet\" href=\"../assets/stanhope.css\"/>\n").expect("write failed");
77 for template in p.get_all_templates() {
80 let temp_str = String::from("\t\t<link rel=\"stylesheet\" href=\"../assets/") + &template + "\"/>\n";
81 f.write(temp_str.as_bytes()).expect("write failed");
82 }
83 f.write(b"\t</head>\n\n").expect("write failed");
84}
85
86fn compose_html_body(f:&mut File,p:&Process,s:&Vec<Section>) {
97 f.write(b"\t<body>\n\n").expect("write failed");
98 f.write(b"\t\t<div id=\"classification-header\" class=\"classification\"><p></p></div>\n").expect("write failed");
99
100 compose_html_body_title_page(f,p);
102 compose_html_body_rev_req_page(f,p);
103 compose_html_body_toc(f,p,s);
104
105 compose_html_body_section(f,p,s);
107 compose_html_body_end_of_sections_and_banners(f,p);
108
109 f.write(b"\t\t<div id=\"classification-footer\" class=\"classification\"><p></p></div>\n\n").expect("write failed");
110 f.write(b"\t</body>\n\n").expect("write failed");
111}
112
113fn compose_html_body_title_page(f:&mut File, p:&Process) {
117 f.write(b"\t\t<table id=\"whole-doc\">\n\n").expect("write failed");
119 f.write(b"\t\t\t<thead><tr><td>\n").expect("write failed");
120 f.write(b"\t\t\t\t<div class=\"header-space\"> </div>\n").expect("write failed");
121 f.write(b"\t\t\t</td></tr></thead>\n\n").expect("write failed");
122 f.write(b"\t\t<tbody>\n\n").expect("write failed");
123 f.write(b"\t\t\t<tr><td>\n\n").expect("write failed");
124 f.write(b"\t\t\t\t<section class=\"hide-on-screen\">\n").expect("write failed");
125 f.write(b"\t\t\t\t\t<div id=\"title-page\">\n").expect("write failed");
126
127 let temp_str = String::from("\t\t\t\t\t\t<div id=\"title-page-title\">") + p.get_title() + "</div>\n";
129 f.write(temp_str.as_bytes()).expect("write failed");
130
131 let proxi = Process::new();
133 let mut process_type = "".to_string();
134 if !(p.get_process_type() == proxi.get_process_type()) { process_type = "<br/>".to_owned() + p.get_process_type(); }
135 let temp_str = String::from("\t\t\t\t\t\t<div id=\"title-page-docno\">") + p.get_number() + &process_type + "<br/>Revision " + p.get_revision() + "</div>\n";
136 f.write(temp_str.as_bytes()).expect("write failed");
137
138 f.write(b"\t\t\t\t\t\t<div id=\"title-page-authors\">\n").expect("write failed");
140 f.write(b"\t\t\t\t\t\t\t<table>\n").expect("write failed");
141 f.write(b"\t\t\t\t\t\t\t\t<thead>\n").expect("write failed");
142 f.write(b"\t\t\t\t\t\t\t\t\t<tr>\n").expect("write failed");
143 let temp_str = String::from("\t\t\t\t\t\t\t\t\t\t<td>Written by:<br/>") + p.get_author() + "</td>\n";
144 f.write(temp_str.as_bytes()).expect("write failed");
145 let temp_str = String::from("\t\t\t\t\t\t\t\t\t\t<td>Reviewed by:<br/>") + p.get_reviewer() + "</td>\n";
146 f.write(temp_str.as_bytes()).expect("write failed");
147 f.write(b"\t\t\t\t\t\t\t\t\t</tr>\n").expect("write failed");
148 f.write(b"\t\t\t\t\t\t\t\t</thead>\n").expect("write failed");
149 f.write(b"\t\t\t\t\t\t\t\t<tbody>\n").expect("write failed");
150 f.write(b"\t\t\t\t\t\t\t\t\t<tr>\n").expect("write failed");
151 f.write(b"\t\t\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
152 f.write(b"\t\t\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
153 f.write(b"\t\t\t\t\t\t\t\t\t</tr>\n").expect("write failed");
154 f.write(b"\t\t\t\t\t\t\t\t</tbody>\n").expect("write failed");
155 f.write(b"\t\t\t\t\t\t\t</table>\n").expect("write failed");
156 f.write(b"\t\t\t\t\t\t</div>\n").expect("write failed");
157
158 f.write(b"\t\t\t\t\t\t<div id=\"title-page-fine-print\"></div>\n").expect("write failed");
160
161 f.write(b"\t\t\t\t\t\t<div id=\"title-page-no-ai\"></div>\n").expect("write failed");
163
164 f.write(b"\t\t\t\t\t</div>\n").expect("write failed");
166 f.write(b"\t\t\t\t</section>\n\n").expect("write failed");
167 f.write(b"\t\t\t</td></tr>\n\n").expect("write failed");
168}
169
170fn compose_html_body_rev_req_page(f:&mut File, p:&Process) {
172 f.write(b"\t\t\t<tr><td>\n\n").expect("write failed");
174 f.write(b"\t\t\t\t<section class=\"\">\n").expect("write failed");
175 f.write(b"\t\t\t\t\t<div id=\"revision-page\">\n").expect("write failed");
176 let temp_str = String::from("\t\t\t\t\t\t<span class=\"toc-title\">Revision Table for ").to_string() + p.get_number() + " \"" + p.get_title() + "\"</span>\n";
177 f.write(temp_str.as_bytes()).expect("write failed");
178
179 f.write(b"\t\t\t\t\t\t<div class=\"revision-table-container\">\n").expect("write failed");
181 f.write(b"\t\t\t\t\t\t\t<table>\n").expect("write failed");
182 f.write(b"\t\t\t\t\t\t\t\t<thead>\n").expect("write failed");
183 f.write(b"\t\t\t\t\t\t\t\t\t<tr>\n").expect("write failed");
184 f.write(b"\t\t\t\t\t\t\t\t\t\t<td class=\"revision-table-rev\">Rev</td>\n").expect("write failed");
185 f.write(b"\t\t\t\t\t\t\t\t\t\t<td class=\"revision-table-change\">Description of Change</td>\n").expect("write failed");
186 f.write(b"\t\t\t\t\t\t\t\t\t</tr>\n").expect("write failed");
187 f.write(b"\t\t\t\t\t\t\t\t</thead>\n").expect("write failed");
188 f.write(b"\t\t\t\t\t\t\t\t<tbody>\n").expect("write failed");
189
190 let mut rev_counter = 0;
193 let len_revs = p.get_all_revisions().len();
194 for rev in p.get_all_revisions().iter().rev() {
195 rev_counter += 1;
196 if rev_counter==len_revs {
198 f.write(b"\t\t\t\t\t\t\t\t\t<tr class=\"current-rev\">\n").expect("write failed");
199 let temp_str = "\t\t\t\t\t\t\t\t\t\t<td class=\"revision-table-rev\"><span class=\"current-rev\">".to_string() + &rev.0 + "</span></td>\n";
200 f.write(temp_str.as_bytes()).expect("write failed");
201 } else {
202 f.write(b"\t\t\t\t\t\t\t\t\t<tr>\n").expect("write failed");
203 let temp_str = "\t\t\t\t\t\t\t\t\t\t<td class=\"revision-table-rev\">".to_string() + &rev.0 + "</td>\n";
204 f.write(temp_str.as_bytes()).expect("write failed");
205 }
206 let temp_str = "\t\t\t\t\t\t\t\t\t\t<td class=\"revision-table-change\">".to_string() + &rev.1 + "</td>\n";
207 f.write(temp_str.as_bytes()).expect("write failed");
208 f.write(b"\t\t\t\t\t\t\t\t\t</tr>\n").expect("write failed");
209 }
210 f.write(b"\t\t\t\t\t\t\t\t</tbody>\n").expect("write failed");
212 f.write(b"\t\t\t\t\t\t\t</table>\n").expect("write failed");
213 f.write(b"\t\t\t\t\t\t</div>\n").expect("write failed");
214 f.write(b"\t\t\t\t\t</div>\n").expect("write failed");
215 f.write(b"\t\t\t\t</section>\n\n").expect("write failed");
216 f.write(b"\t\t\t</td></tr>\n\n").expect("write failed");
217
218 if p.get_all_verifications().len()==0 { return };
220
221 f.write(b"\t\t\t<tr><td>\n\n").expect("write failed");
223 f.write(b"\t\t\t\t<section class=\"\">\n").expect("write failed");
224 f.write(b"\t\t\t\t\t<div id=\"requirements-page\">\n").expect("write failed");
225 let temp_str = String::from("\t\t\t\t\t\t<span class=\"toc-title\">Requirements Table for ").to_string() + p.get_number() + " \"" + p.get_title() + "\"</span>\n";
226 f.write(temp_str.as_bytes()).expect("write failed");
227 let temp_str = "\t\t\t\t\t\t<div class=\"requirement\">Successful execution of this procedure produces evidence of verification for the requirements listed in the table below. Therefore, this procedure's execution is particularly important for us to achieve our goal. When you see procedure call-outs in this style of box, that step is what produces this critical evidence. Take the time to understand how these requirements will be verified prior to starting this procedure, and consult this procedure's author (".to_string() + p.get_author() + ") if necessary.</div>\n";
229 f.write(temp_str.as_bytes()).expect("write failed");
230 f.write(b"\t\t\t\t\t\t<div class=\"requirements-table-container\">\n").expect("write failed");
232 f.write(b"\t\t\t\t\t\t\t<table>\n").expect("write failed");
233 f.write(b"\t\t\t\t\t\t\t\t<thead>\n").expect("write failed");
234 f.write(b"\t\t\t\t\t\t\t\t\t<tr>\n").expect("write failed");
235 f.write(b"\t\t\t\t\t\t\t\t\t\t<td class=\"requirements-table-rid\">RID</td>\n").expect("write failed");
237 f.write(b"\t\t\t\t\t\t\t\t\t\t<td class=\"requirements-table-text\">Text of Requirement</td>\n").expect("write failed");
238 f.write(b"\t\t\t\t\t\t\t\t\t\t<td class=\"requirements-table-method\">Verif. Method</td>\n").expect("write failed");
239 f.write(b"\t\t\t\t\t\t\t\t\t\t<td class=\"requirements-table-step\">Step</td>\n").expect("write failed");
240 f.write(b"\t\t\t\t\t\t\t\t\t</tr>\n").expect("write failed");
241 f.write(b"\t\t\t\t\t\t\t\t</thead>\n").expect("write failed");
242 f.write(b"\t\t\t\t\t\t\t\t<tbody>\n").expect("write failed");
243 for req in p.get_all_verifications().iter() {
245 f.write(b"\t\t\t\t\t\t\t\t\t<tr>\n").expect("write failed");
246 let temp_str = "\t\t\t\t\t\t\t\t\t\t<td class=\"requirements-table-rid\">".to_string() + &req.0.get_id() + "</td>\n";
247 f.write(temp_str.as_bytes()).expect("write failed");
248 let temp_str = "\t\t\t\t\t\t\t\t\t\t<td class=\"requirements-table-text\">".to_string() + &req.0.get_text() + "</td>\n";
249 f.write(temp_str.as_bytes()).expect("write failed");
250 let temp_str = "\t\t\t\t\t\t\t\t\t\t<td class=\"requirements-table-method\">".to_string() + &req.0.get_method() + "</td>\n";
251 f.write(temp_str.as_bytes()).expect("write failed");
252 let temp_str = "\t\t\t\t\t\t\t\t\t\t<td class=\"requirements-table-step\">".to_string() + &req.1 + "</td>\n";
253 f.write(temp_str.as_bytes()).expect("write failed");
254 f.write(b"\t\t\t\t\t\t\t\t\t</tr>\n").expect("write failed");
255 }
256 f.write(b"\t\t\t\t\t\t\t\t</tbody>\n").expect("write failed");
258 f.write(b"\t\t\t\t\t\t\t</table>\n").expect("write failed");
259 f.write(b"\t\t\t\t\t\t</div>\n").expect("write failed");
260 f.write(b"\t\t\t\t\t</div>\n").expect("write failed");
261 f.write(b"\t\t\t\t</section>\n\n").expect("write failed");
262 f.write(b"\t\t\t</td></tr>\n\n").expect("write failed");
263}
264
265fn compose_html_body_toc(f:&mut File,p:&Process,s:&Vec<Section>) {
271
272 fn pick_color(index:usize) -> String {
274 match index % 3 {
276 2 => String::from("border: 0; background-color: #FFFFFF; color: #5566AA;"),
277 1 => String::from("border: 0; background-color: #FFFFFF; color: #5566AA;"),
278 0 => String::from("border: 0; background-color: #FFFFFF; color: #5566AA;"),
279 _ => String::from("border: 0; background-color: #AA99DD; color: #5566AA;"),
280 }
281 }
290
291 f.write(b"\t\t\t<tr><td>\n\n").expect("write failed");
293 f.write(b"\t\t\t\t<section class=\"\">\n").expect("write failed");
294 f.write(b"\t\t\t\t\t<div id=\"toc\">\n").expect("write failed");
295 let temp_str = String::from("\t\t\t\t\t\t<span class=\"toc-title\">").to_string() + p.get_number() + ", Rev " + p.get_revision() + " \"" + p.get_title() + "\"</span>\n";
296 f.write(temp_str.as_bytes()).expect("write failed");
297 f.write(b"\t\t\t\t\t\t<ul style=\"toc-section\">\n").expect("write failed");
299 for (ii,sec) in s.iter().enumerate() {
300 let temp_str = String::from("\t\t\t\t\t\t\t<li><a class=\"pageref\" href=\"#Section") + &(ii+1).to_string() + "\">Section " + &(ii+1).to_string() + "</a>: " + sec.get_title() + "</a></li>\n";
301 f.write(temp_str.as_bytes()).expect("write failed");
302 f.write(b"\t\t\t\t\t\t\t\t<ul style=\"toc-step\">\n").expect("write failed");
303 for (jj,stp) in sec.get_all_steps().iter().enumerate() {
304 let temp_str = String::from("\t\t\t\t\t\t\t\t\t<li><a class=\"pageref\" href=\"#Step") + &(ii+1).to_string() + "." + &(jj+1).to_string() + "\">Step " + &(ii+1).to_string() + "." + &(jj+1).to_string() + "</a>: " + stp.get_text() + "</a></li>\n";
305 f.write(temp_str.as_bytes()).expect("write failed");
306 }
307 f.write(b"\t\t\t\t\t\t\t\t</ul>\n").expect("write failed");
308 }
309 f.write(b"\t\t\t\t\t\t</ul>\n\n").expect("write failed");
310 f.write(b"\t\t\t\t\t</div>\n").expect("write failed");
311
312 f.write(b"\t\t\t\t\t<div id=\"roles\">\n").expect("write failed");
314 f.write(b"\t\t\t\t\t\t<span class=\"toc-title\">Personnel Performing this Process, by Named Role:</span>\n").expect("write failed");
315 f.write(b"\t\t\t\t\t\t<table id=\"roles-table\">\n").expect("write failed");
316 f.write(b"\t\t\t\t\t\t\t<thead id=\"roles-header\">\n").expect("write failed");
317 f.write(b"\t\t\t\t\t\t\t\t<tr>\n").expect("write failed");
318 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"role-title\">Role in this Process</td>\n").expect("write failed");
319 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"role-name\">Name of Person</td>\n").expect("write failed");
320 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"role-initials\">Initials</td>\n").expect("write failed");
321 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"role-contact\">Contact Information</td>\n").expect("write failed");
322 f.write(b"\t\t\t\t\t\t\t\t</tr>\n").expect("write failed");
323 f.write(b"\t\t\t\t\t\t\t</thead>\n").expect("write failed");
324 f.write(b"\t\t\t\t\t\t\t<tbody>\n").expect("write failed");
325 let num_roles:usize = 10;
326 for ii in 1..(num_roles+1) {
327 let temp_str = String::from("\t\t\t\t\t\t\t\t<tr id=\"role-".to_string() + &format!("{:0>2}",ii) + "\">\n");
328 f.write(temp_str.as_bytes()).expect("write failed");
329 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"role-title\"></td>\n").expect("write failed");
330 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"role-name\"></td>\n").expect("write failed");
331 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"role-initials\"></td>\n").expect("write failed");
332 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"role-contact\"></td>\n").expect("write failed");
333 f.write(b"\t\t\t\t\t\t\t\t</tr>\n").expect("write failed");
334 }
335 f.write(b"\t\t\t\t\t\t\t</tbody>\n").expect("write failed");
336 f.write(b"\t\t\t\t\t\t</table>\n").expect("write failed");
337 f.write(b"\t\t\t\t\t</div>\n").expect("write failed");
338
339 f.write(b"\t\t\t\t\t<div class=\"power-on\"><img/><span class=\"power-on-text\"></span></div>\n").expect("write failed");
342 f.write(b"\t\t\t\t\t<div class=\"rf-emission\"><img/><span class=\"rf-emission-text\"></span></div>\n").expect("write failed");
343 f.write(b"\t\t\t\t\t<div class=\"hazardous-ops\"><img/><span class=\"hazardous-ops-text\"></span></div>\n").expect("write failed");
344 f.write(b"\t\t\t\t\t<div class=\"esd\"><img/><span class=\"esd-text\"></span></div>\n").expect("write failed");
345 f.write(b"\t\t\t\t\t<div class=\"fod\"><img/><span class=\"fod-text\"></span></div>\n").expect("write failed");
346 f.write(b"\t\t\t\t\t<div class=\"welding\"><img/><span class=\"welding-text\"></span></div>\n").expect("write failed");
347 f.write(b"\t\t\t\t\t<div class=\"comsec\"><img/><span class=\"comsec-text\"></span></div>\n").expect("write failed");
348 f.write(b"\t\t\t\t\t<div class=\"cleanroom\"><img/><span class=\"cleanroom-text\"></span></div>\n").expect("write failed");
349 f.write(b"\t\t\t\t</section>\n\n").expect("write failed");
350 f.write(b"\t\t\t</td></tr>\n\n").expect("write failed");
351
352 if p.get_all_objectives().len() > 0 || p.get_all_out_of_scopes().len() > 0 || p.get_all_resources().len() > 0 || !(*p.get_subject()==String::from("N/A")) || !(*p.get_product()==String::from("N/A")) {
359 f.write(b"\t\t\t<tr><td>\n\n").expect("write failed");
361 f.write(b"\t\t\t\t<section class=\"\">\n").expect("write failed");
362
363 let all_objectives = p.get_all_objectives();
364 if all_objectives.len() > 0 {
365 f.write(b"\t\t\t\t\t<div id=\"all-objectives\">\n").expect("write failed");
367 let temp_str = String::from("\t\t\t\t\t\t<span class=\"toc-title\">This process has ") + &all_objectives.len().to_string() + " stated objective" + match all_objectives.len() {1=>"",_=>"s"} + ":</span>\n";
368 f.write(temp_str.as_bytes()).expect("write failed");
369 f.write(b"\t\t\t\t\t\t<ol class=\"objective-list\">\n").expect("write failed");
370 for (_jj,(obj,snum)) in all_objectives.iter().enumerate() {
371 let temp_str = String::from("\t\t\t\t\t\t\t<li>") + &obj + " (" + &snum + ")</li>\n";
372 f.write(temp_str.as_bytes()).expect("write failed");
373 }
374 f.write(b"\t\t\t\t\t\t</ol>\n").expect("write failed");
375 f.write(b"\t\t\t\t\t</div>\n").expect("write failed");
376 };
377
378 let all_out_of_scopes = p.get_all_out_of_scopes();
379 if all_out_of_scopes.len() > 0 {
380 f.write(b"\t\t\t\t\t<div id=\"all-out-of-scopes\">\n").expect("write failed");
382 let temp_str = String::from("\t\t\t\t\t\t<span class=\"toc-title\">This process has ") + &all_out_of_scopes.len().to_string() + " <em>Out Of Scope</em> declaration" + match all_out_of_scopes.len() {1=>"",_=>"s"} + ":</span>\n";
383 f.write(temp_str.as_bytes()).expect("write failed");
384 f.write(b"\t\t\t\t\t\t<ol class=\"out-of-scope-list\">\n").expect("write failed");
385 for (_jj,(oos,snum)) in all_out_of_scopes.iter().enumerate() {
386 let temp_str = String::from("\t\t\t\t\t\t\t<li>") + &oos + " (" + &snum + ")</li>\n";
387 f.write(temp_str.as_bytes()).expect("write failed");
388 }
389 f.write(b"\t\t\t\t\t\t</ol>\n").expect("write failed");
390 f.write(b"\t\t\t\t\t</div>\n").expect("write failed");
391 };
392
393 f.write(b"\t\t\t\t\t<div id=\"subject-product\">\n").expect("write failed");
395 match p.get_product().as_str() {
396 ""|"N/A" => {
397 match p.get_subject().as_str() {
398 ""|"N/A"|"NO SUBJECT IN EBML FILE" => (),
399 _ => {
400 let temp_str = String::from("\t\t\t\t\t\t<span class=\"toc-title\">\"") + p.get_title() + "\" applies to <em>" + p.get_subject() + "</em></span><br/>\n";
401 f.write(temp_str.as_bytes()).expect("write failed");
402 let temp_str = String::from("\t\t\t\t\t\t<div class=\"subject-product-image-container\"><img src=\"") + p.get_subject_image() + "\"/></div>\n";
403 f.write(temp_str.as_bytes()).expect("write failed");
404 },
405 }
406 },
407 _ => {
408 let temp_str = String::from("\t\t\t\t\t\t<span class=\"toc-title\">\"") + p.get_title() + "\" applies to <em>" + p.get_subject() + "</em> to produce <em>" + p.get_product() +"</em></span><br/>\n";
409 f.write(temp_str.as_bytes()).expect("write failed");
410 let temp_str = String::from("\t\t\t\t\t\t<div class=\"subject-product-image-container\"><img src=\"") + p.get_subject_image() + "\"/><span class=\"arrow\">→</span><img src=\"" + p.get_product_image() + "\"/></div>\n";
411 f.write(temp_str.as_bytes()).expect("write failed");
412 },
413 };
414 f.write(b"\t\t\t\t\t</div>\n").expect("write failed");
415
416 if p.get_all_resources().len() > 0 {
418 f.write(b"\t\t\t\t\t\t<div class=\"resources-container\">\n").expect("write failed");
419 let temp_str = "\t\t\t\t\t\t<span class=\"resources-text\">".to_string() + &p.get_all_resources().len().to_string() + " named resources are identified to perform this process:</span><br/>\n";
420 f.write(temp_str.as_bytes()).expect("write failed");
421
422 let mut step_num = "";
424 let mut index:usize = 0;
425 for (resource,resource_step) in p.get_all_resources() {
426 if !(step_num==resource_step) { index += 1; };
427 step_num = resource_step;
428 let temp_str = "\t\t\t\t\t\t\t<div class=\"resource-bubble\" style=\"".to_string() + &pick_color(index) + ";\"><span class=\"resource-bubble-step\">" + &resource_step + "</span><br/>" + &resource.get_name() + "</div>\n";
429 f.write(temp_str.as_bytes()).expect("write failed");
430 }
431 f.write(b"\t\t\t\t\t\t</div><div style=\"clear:both;\"></div>\n").expect("write failed");
432
433 if p.get_all_calibrated_resources().len() > 0 {
435 f.write(b"\t\t\t\t\t<div id=\"calibration\">\n").expect("write failed");
436 f.write(b"\t\t\t\t\t\t<span class=\"toc-title\">Equipment Calibration Status</span>\n").expect("write failed");
437 f.write(b"\t\t\t\t\t\t<table id=\"calibration-table\">\n").expect("write failed");
438 f.write(b"\t\t\t\t\t\t\t<thead id=\"calibration-header\">\n").expect("write failed");
439 f.write(b"\t\t\t\t\t\t\t\t<tr>\n").expect("write failed");
441 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"calibration-resource\">Equipment</td>\n").expect("write failed");
442 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"calibration-num\">Model Number</td>\n").expect("write failed");
443 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"calibration-serial\">Serial</td>\n").expect("write failed");
444 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"calibration-date\">Last Cal Date</td>\n").expect("write failed");
445 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"calibration-due\">Valid Until</td>\n").expect("write failed");
446 f.write(b"\t\t\t\t\t\t\t\t</tr>\n").expect("write failed");
447 f.write(b"\t\t\t\t\t\t\t</thead>\n").expect("write failed");
448 f.write(b"\t\t\t\t\t\t\t<tbody>\n").expect("write failed");
449 for resource in p.get_all_calibrated_resources() {
450 let temp_str = String::from("\t\t\t\t\t\t\t\t<tr>\n");
451 f.write(temp_str.as_bytes()).expect("write failed");
452 let temp_str = "\t\t\t\t\t\t\t\t\t<td class=\"calibration-resource\">".to_string() + &resource.get_name() + "</td>\n";
454 f.write(temp_str.as_bytes()).expect("write failed");
455 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"calibration-num\"></td>\n").expect("write failed");
456 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"calibration-serial\"></td>\n").expect("write failed");
457 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"calibration-date\"></td>\n").expect("write failed");
458 f.write(b"\t\t\t\t\t\t\t\t\t<td class=\"calibration-due\"></td>\n").expect("write failed");
459 f.write(b"\t\t\t\t\t\t\t\t</tr>\n").expect("write failed");
460 }
461 f.write(b"\t\t\t\t\t\t\t</tbody>\n").expect("write failed");
462 f.write(b"\t\t\t\t\t\t\t<tfoot>\n").expect("write failed");
463 f.write(b"\t\t\t\t\t\t\t\t<tr><td colspan=\"3\">If any equipment is within 30 days of needing recalibration, notify your QA rep. <strong>Today's Date:</strong></td></tr>\n").expect("write failed");
464 f.write(b"\t\t\t\t\t\t\t</tfoot>\n").expect("write failed");
465 f.write(b"\t\t\t\t\t\t</table>\n").expect("write failed");
466 f.write(b"\t\t\t\t\t</div>\n").expect("write failed");
467 }
468
469
470 }
471 f.write(b"\t\t\t\t</section>\n\n").expect("write failed");
472 f.write(b"\t\t\t</td></tr>\n\n").expect("write failed");
473 }
475 f.write(b"\t\t\t<tr id=\"non-conformances\"><td>\n\n").expect("write failed");
479 f.write(b"\t\t\t\t<section class=\"\">\n").expect("write failed");
480 f.write(b"\t\t\t\t\t<span class=\"toc-title\">Log of Non-Conformances during this execution:</span>\n").expect("write failed");
481 f.write(b"\t\t\t\t\t<table>\n").expect("write failed");
482 f.write(b"\t\t\t\t\t\t<thead>\n").expect("write failed");
483 f.write(b"\t\t\t\t\t\t\t<tr>\n").expect("write failed");
484 f.write(b"\t\t\t\t\t\t\t\t<td class=\"text-rotated\">Time</td>\n").expect("write failed");
485 f.write(b"\t\t\t\t\t\t\t\t<td class=\"text-rotated\">Step</td>\n").expect("write failed");
486 f.write(b"\t\t\t\t\t\t\t\t<td class=\"text-rotated\">Record</td>\n").expect("write failed");
487 f.write(b"\t\t\t\t\t\t\t\t<td>Brief Summary of Observation(s) that Deviated from Documented Expectations</td>\n").expect("write failed");
488 f.write(b"\t\t\t\t\t\t\t</tr>\n").expect("write failed");
489 f.write(b"\t\t\t\t\t\t</thead>\n").expect("write failed");
490 f.write(b"\t\t\t\t\t\t<tbody>\n").expect("write failed");
491 f.write(b"\t\t\t\t\t\t\t<tr>\n").expect("write failed");
492 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
493 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
494 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
495 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
496 f.write(b"\t\t\t\t\t\t\t</tr>\n").expect("write failed");
497 f.write(b"\t\t\t\t\t\t\t<tr>\n").expect("write failed");
498 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
499 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
500 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
501 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
502 f.write(b"\t\t\t\t\t\t\t</tr>\n").expect("write failed");
503 f.write(b"\t\t\t\t\t\t\t<tr>\n").expect("write failed");
504 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
505 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
506 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
507 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
508 f.write(b"\t\t\t\t\t\t\t</tr>\n").expect("write failed");
509 f.write(b"\t\t\t\t\t\t\t<tr>\n").expect("write failed");
510 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
511 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
512 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
513 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
514 f.write(b"\t\t\t\t\t\t\t</tr>\n").expect("write failed");
515 f.write(b"\t\t\t\t\t\t\t<tr>\n").expect("write failed");
516 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
517 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
518 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
519 f.write(b"\t\t\t\t\t\t\t\t<td></td>\n").expect("write failed");
520 f.write(b"\t\t\t\t\t\t\t</tr>\n").expect("write failed");
521 f.write(b"\t\t\t\t\t\t</tbody>\n").expect("write failed");
522 f.write(b"\t\t\t\t\t</table>\n").expect("write failed");
523 f.write(b"\t\t\t\t</section>\n\n").expect("write failed");
524 f.write(b"\t\t\t</td></tr>\n\n").expect("write failed");
525
526
527}
528
529fn compose_html_body_section(f:&mut File, p:&Process, all_sections:&Vec<Section>) {
531
532 let mut counter = 0;
534 for section in all_sections {
535 f.write(b"\t\t\t<tr><td>\n\n").expect("write failed");
537 f.write(b"\t\t\t\t<section>\n").expect("write failed");
538
539 counter += 1;
542
543 let temp_str = "\t\t\t\t\t<div class=\"section-title\"><a name=\"Section".to_string() + &counter.to_string() + "\"></a>Section " + &counter.to_string() + ": " + §ion.get_title() + "</div>\n";
545 f.write(temp_str.as_bytes()).expect("write failed");
546
547 for (ii,step) in section.get_all_steps().iter().enumerate() {
549
550 let temp_str = "\t\t\t\t\t<div class=\"step\"><span class=\"step-text\"><a name=\"Step".to_string() + &counter.to_string() + "." + &{ii+1}.to_string() + "\"></a>Step " + &counter.to_string() + "." + &{ii+1}.to_string() + ": " + &step.get_text() + "</span><br/>\n";
552 f.write(temp_str.as_bytes()).expect("write failed");
553
554 if step.get_resources().len() > 0 {
556 f.write(b"\t\t\t\t\t\t\t<div class=\"resources-container\">\n").expect("write failed");
557 let temp_str = "\t\t\t\t\t\t\t\t<span class=\"resources-text\">".to_string() + &step.get_resources().len().to_string() + " named resources are identified to perform this step:</span><br/>\n";
558 f.write(temp_str.as_bytes()).expect("write failed");
559 for resource in step.get_resources() {
560 let temp_str = "\t\t\t\t\t\t\t\t<div class=\"resource-bubble\">".to_string() + &resource.get_name() + "</div>\n";
561 f.write(temp_str.as_bytes()).expect("write failed");
562 }
563 f.write(b"\t\t\t\t\t\t\t</div><div style=\"clear:both;\"></div>\n").expect("write failed");
564 }
565 for (_jj,sub_step) in step.get_all_sub_steps().iter().enumerate() {
569 match sub_step {
570 SubStep::ActionSequence(action_sequence) => compose_html_body_section_step_action_sequence(f,&action_sequence),
571 SubStep::Command(command_text) => compose_html_body_section_step_command(f,&command_text),
572 SubStep::Image(image_file,image_text) => compose_html_body_section_step_image(f,&image_file,&image_text,section.get_relative_path()),
573 SubStep::Warning(warning_text) => compose_html_body_section_step_warning(f,&warning_text),
574 SubStep::Verification(requirement) => compose_html_body_section_step_verification(f,&p.get_author(),&requirement),
575 SubStep::Resource(_resource) => (),
578 SubStep::Context(text) => compose_html_body_section_step_context(f,&text),
579 SubStep::Objective(objective_text) => compose_html_body_section_step_objective(f,&objective_text),
580 SubStep::OutOfScope(out_of_scope_text) => compose_html_body_section_step_out_of_scope(f,&out_of_scope_text),
581 SubStep::Table(table) => compose_html_body_section_step_table(f,&table),
582 }
583 }
584 f.write(b"\t\t\t\t\t</div>\n").expect("write failed");
586 }
587 f.write(b"\t\t\t\t</section>\n\n").expect("write failed");
589 f.write(b"\t\t\t</td></tr>\n\n").expect("write failed");
590 }
591}
592
593fn compose_html_body_section_step_action_sequence(f:&mut File, act_seq:&Vec<Action>) {
595 f.write(b"\t\t\t\t\t\t<div class=\"action-sequence\">\n").expect("write failed");
597 f.write(b"\t\t\t\t\t\t\t<table>\n").expect("write failed");
598 f.write(b"\t\t\t\t\t\t\t\t<thead>\n").expect("write failed");
599 f.write(b"\t\t\t\t\t\t\t\t\t<tr>\n").expect("write failed");
600 f.write(b"\t\t\t\t\t\t\t\t\t\t<td class=\"action-sequence-action\">Action to perform</td>\n").expect("write failed");
602 f.write(b"\t\t\t\t\t\t\t\t\t\t<td class=\"action-sequence-expected\">Expected</td>\n").expect("write failed");
603 f.write(b"\t\t\t\t\t\t\t\t\t\t<td class=\"action-sequence-result\">Result</td>\n").expect("write failed");
604 f.write(b"\t\t\t\t\t\t\t\t\t\t<td class=\"action-sequence-tpv\">Done</td>\n").expect("write failed");
605 f.write(b"\t\t\t\t\t\t\t\t\t\t<td class=\"action-sequence-tpv\">TPV</td>\n").expect("write failed");
606 f.write(b"\t\t\t\t\t\t\t\t\t</tr>\n").expect("write failed");
607 f.write(b"\t\t\t\t\t\t\t\t</thead>\n").expect("write failed");
608 f.write(b"\t\t\t\t\t\t\t\t<tbody>\n").expect("write failed");
609
610 for act in act_seq {
612 f.write(b"\t\t\t\t\t\t\t\t\t<tr>\n").expect("write failed");
613 let temp_str = "\t\t\t\t\t\t\t\t\t\t<td class=\"action-sequence-action\">".to_string() + act.get_perform() + "</td>\n";
614 f.write(temp_str.as_bytes()).expect("write failed");
615 let temp_str = "\t\t\t\t\t\t\t\t\t\t<td class=\"action-sequence-expected\">".to_string() + act.get_expect() + "</td>\n";
616 f.write(temp_str.as_bytes()).expect("write failed");
617 let temp_str = "\t\t\t\t\t\t\t\t\t\t<td class=\"action-sequence-result\">".to_string() + "</td>\n";
618 f.write(temp_str.as_bytes()).expect("write failed");
619 let temp_str = "\t\t\t\t\t\t\t\t\t\t<td class=\"action-sequence-tpv\">".to_string() + "<span class=\"action-checkbox\">▢</span>" + "</td>\n";
620 f.write(temp_str.as_bytes()).expect("write failed");
621 let temp_str = "\t\t\t\t\t\t\t\t\t\t<td class=\"action-sequence-tpv\">".to_string() + { if !act.get_tpv() { "N/A" } else { "<span class=\"action-checkbox\">▢</span>" }} + "</td>\n";
622 f.write(temp_str.as_bytes()).expect("write failed");
623 f.write(b"\t\t\t\t\t\t\t\t\t</tr>\n").expect("write failed");
624 }
625
626 f.write(b"\t\t\t\t\t\t\t\t</tbody>\n").expect("write failed");
628 f.write(b"\t\t\t\t\t\t\t</table>\n").expect("write failed");
629 f.write(b"\t\t\t\t\t\t</div>\n").expect("write failed");
630}
631
632fn compose_html_body_section_step_command(f:&mut File, c:&String) {
634 let temp_str = "\t\t\t\t\t\t<div class=\"command\"><span class=\"command-text\">".to_string() + &c.to_string() + "</span></div>\n";
636 f.write(temp_str.as_bytes()).expect("write failed");
637}
638
639fn compose_html_body_section_step_image(f:&mut File, img:&String, txt:&String, path:&String) {
641 let temp_str = "\t\t\t\t\t\t<div class=\"image\"><div class=\"image-container\"><img src=\"".to_string() + &path.to_string() + &img.to_string() + "\" onerror=\"this.onerror=null; this.src='../assets/placeholderImage-small.png'\"/><br/><span class=\"image-text\">" + &txt.to_string() + "</span></div></div>\n";
645 f.write(temp_str.as_bytes()).expect("write failed");
646}
647
648fn compose_html_body_section_step_warning(f:&mut File, w:&String) {
650 let temp_str = "\t\t\t\t\t\t<div class=\"warning\"><span class=\"warning-text\">".to_string() + &w.to_string() + "</span></div>\n";
652 f.write(temp_str.as_bytes()).expect("write failed");
653}
654
655fn compose_html_body_section_step_verification(f:&mut File, author:&String, r:&Requirement) {
657 let temp_str = "\t\t\t\t\t\t<div class=\"requirement\">This step produces the evidence of verification for this requirement:<br/><span class=\"requirement-rid\">".to_string() + &r.get_id() + ": \"" + &r.get_text() + "\" (Verify by " + &r.get_method() + ")</span><br/>Please ensure the evidence produced passes the requirement before proceding. This might require consulting this procedure's author, " + author + ".</div>\n";
659 f.write(temp_str.as_bytes()).expect("write failed");
660}
661
662fn compose_html_body_section_step_context(f:&mut File, text:&String) {
664 let temp_str = "\t\t\t\t\t\t<div class=\"context\"><span class=\"context-text\">".to_string() + &text.to_string() + "</span></div>\n";
666 f.write(temp_str.as_bytes()).expect("write failed");
667}
668
669fn compose_html_body_section_step_objective(f:&mut File, objective_text:&String) {
671 let temp_str = "\t\t\t\t\t\t<div class=\"objective\">".to_string() + objective_text + "</div>\n";
673 f.write(temp_str.as_bytes()).expect("write failed");
674}
675
676fn compose_html_body_section_step_out_of_scope(f:&mut File, out_of_scope_text:&String) {
678 let temp_str = "\t\t\t\t\t\t<div class=\"out-of-scope\">".to_string() + out_of_scope_text + "</div>\n";
680 f.write(temp_str.as_bytes()).expect("write failed");
681}
682
683fn compose_html_body_section_step_table(f:&mut File, table:&Table) {
685
686 let (rows,cols) = table.get_size();
687
688 if rows > 0 {
690
691 f.write(b"\t\t\t\t\t\t<div class=\"csv-table-container\">\n").expect("write failed");
692 f.write(b"\t\t\t\t\t\t\t<table>\n").expect("write failed");
693
694 let temp_str = "\t\t\t\t\t\t\t\t<caption>".to_string() + table.get_caption() + "</caption>\n";
695 f.write(temp_str.as_bytes()).expect("write failed");
696
697 f.write(b"\t\t\t\t\t\t\t\t<thead>\n").expect("write failed");
698 f.write(b"\t\t\t\t\t\t\t\t\t<tr>\n").expect("write failed");
699 let first_row = table.get_row(0);
700 for jj in 0..cols {
701
702 let temp_str = "\t\t\t\t\t\t\t\t\t\t<th>".to_string() + &first_row[jj] + "</th>\n";
703 f.write(temp_str.as_bytes()).expect("write failed");
704 }
705 f.write(b"\t\t\t\t\t\t\t\t\t</tr>\n").expect("write failed");
706 f.write(b"\t\t\t\t\t\t\t\t</thead>\n").expect("write failed");
707 f.write(b"\t\t\t\t\t\t\t\t<tbody>\n").expect("write failed");
708
709 for ii in 1..rows {
710 let this_row = table.get_row(ii);
711 f.write(b"\t\t\t\t\t\t\t\t\t<tr>\n").expect("write failed");
712 for jj in 0..cols {
713 let temp_str = "\t\t\t\t\t\t\t\t\t\t<td>".to_string() + &this_row[jj] + "</td>\n";
714 f.write(temp_str.as_bytes()).expect("write failed");
715 }
716 f.write(b"\t\t\t\t\t\t\t\t\t</tr>\n").expect("write failed");
717 }
718
719 f.write(b"\t\t\t\t\t\t\t\t</tbody>\n").expect("write failed");
720 f.write(b"\t\t\t\t\t\t\t</table>\n").expect("write failed");
721 f.write(b"\t\t\t\t\t\t</div>\n").expect("write failed");
722 }
723}
724
725fn compose_html_body_end_of_sections_and_banners(f:&mut File, p:&Process) {
727 f.write(b"\t\t</tbody>\n\n").expect("write failed");
728 f.write(b"\t\t\t<tfoot><tr><td>\n").expect("write failed");
729 f.write(b"\t\t\t\t<div class=\"footer-space\"> </div>\n").expect("write failed");
730 f.write(b"\t\t\t</td></tr></tfoot>\n").expect("write failed");
731 f.write(b"\t\t</table>\n\n").expect("write failed");
732
733 f.write(b"\t\t<div class=\"header\">\n").expect("write failed");
735 f.write(b"\t\t\t<table style=\"margin:0; padding:0; width:100%;\">\n").expect("write failed");
736 f.write(b"\t\t\t\t<tbody style=\"margin:0; padding:0;\">\n").expect("write failed");
737 f.write(b"\t\t\t\t\t<tr style=\"vertical-align: top; margin:0;\">\n").expect("write failed");
738
739 let temp_str = "\t\t\t\t\t\t<td id=\"header-left\"><p class=\"header-p\"><img/><span style=\"font-size:1.3em; font-weight:bold;\">".to_string() + p.get_number() + ", Rev " + p.get_revision() + "</span><br/>Written by: " + p.get_author() + "<br/>Reviewed by: " + p.get_reviewer() + "</p></td>\n";
743 f.write(temp_str.as_bytes()).expect("write failed");
744 let temp_str = "\t\t\t\t\t\t<td id=\"header-right\"><p class=\"header-p\"><span style=\"font-size:1.3em; font-weight:bold;\">".to_string() + p.get_title() + "</span><br/>Applies to " + p.get_subject() + " to produce " + p.get_product() + "<br/>" + &p.get_all_resources().len().to_string() + " named resources are identified to perform this process</p></td>\n";
746 f.write(temp_str.as_bytes()).expect("write failed");
747 f.write(b"\t\t\t\t\t</tr>\n").expect("write failed");
749 f.write(b"\t\t\t\t</tbody>\n").expect("write failed");
750 f.write(b"\t\t\t</table>\n").expect("write failed");
751 f.write(b"\t\t</div>\n").expect("write failed");
752
753 f.write(b"\t\t<div class=\"footer\">\n").expect("write failed");
755 f.write(b"\t\t\t<table style=\"margin:0; padding:0; width:100%;\">\n").expect("write failed");
756 f.write(b"\t\t\t\t<tbody style=\"margin:0; padding:0; width:100%\">\n").expect("write failed");
757 f.write(b"\t\t\t\t\t<tr style=\"vertical-align: top; margin:0;\">\n").expect("write failed");
758 let temp_str = "\t\t\t\t\t\t<td width=\"100%\" style=\"margin:0; padding:0;\"><p class=\"header-p\"><!--<a href=\"https://strativusgroup.com\">--><img/>Produced efficiently with stanhope. See this document's first page for restrictions and distribution statements.<!--</a>--><span>".to_string() + "</p></td>\n";
760 f.write(temp_str.as_bytes()).expect("write failed");
761 let temp_str = "\t\t\t\t\t\t<td><p class=\"header-p\"><span>".to_string() + "</span><br/></p></td>\n";
763 f.write(temp_str.as_bytes()).expect("write failed");
764 f.write(b"\t\t\t\t\t</tr>\n").expect("write failed");
772 f.write(b"\t\t\t\t</tbody>\n").expect("write failed");
773 f.write(b"\t\t\t</table>\n").expect("write failed");
774 f.write(b"\t\t</div>\n").expect("write failed");
775}