PageSourceSearch

https://bin.fuvest.br/js/fuv_id1f.js

js fuvest.br collected 2026-09-24 09:41:35 UTC 39,670 bytes, 963 lines download raw bytes

1class FuvID1F {
2	constructor(id, folder, onclose, forca_modal = false) {
3		var t = this, i = folder.indexOf("/id1f/");
4		
5		t.version = '202405221945';
6		
7		t.editalFolder = folder.substr(i + 6);
8		
9		i = t.editalFolder.indexOf("/");
10		t.ano = t.editalFolder.substr(i + 1, 4);
11		t.editalFolder = t.editalFolder.substr(0, i);
12	
13		t.baseURL = 'https://bin.fuvest.br';
14		
15		t.getCSS(`${t.baseURL}/css/estatisticas.css?version=${t.version}`);
16				
17		t.id = "idID1F_" + (new Date().valueOf());
18		t.folder = folder;
19		
20		t.dados = {};
21		t.codigo_atual = 'tot';
22		t.questao = 1;
23		t.ordemPesquisa = 'iad';
24		
25		t.loadClass(
26			typeof FuvInterfaceGeral == "undefined", 
27			t.baseURL + `/js/interface_geral.js?version=${t.version}`, 
28			() => {
29				t.ig = new FuvInterfaceGeral(t.id, t.baseURL, (s) => s.replace('%qtd_quest%', t.dados[t.codigo_atual].questoes.length), () => jQuery('.esBubble').remove());
30				t.ig.loadXLSClasses();
31				t.ig.montaDialogoEstatistica(forca_modal);
32				t.ig.defineRetangulosAjuda('retangulo_ajuda', '_canvas', 4);
33				t.ig.setListaAjuda([
34					['altera_edital', 0, '<p>Altera Edital</p>Apresenta uma lista contendo todos os editais para os quais esta análise está disponível, permitindo visualizá-lo.', 'pointer'],
35					['seleciona_grupo', 0, '<p>Seleciona Grupo</p>Apresenta, para seleção, uma lista contendo todos os agrupamentos de candidatos disponíveis, permitindo pesquisa por descrição. Esta lista pode ser ordenada alfabeticamente, por índice de acerto da questão ou por índice de discriminação.', 'pointer'], 
36					['download_xls', 0, '<p>Download XLSX</p>Realiza download de uma planilha com os dados deste agrupamento, para todas as questões da prova.', 'pointer'], 
37					['download_pdf', 0, '<p>Download PDF</p>Realiza download do relatório estatístico em PDF deste agrupamento, para todas as questões da prova.', 'pointer'], 
38					['questao_anterior', 0, '<p>Questão Anterior</p>Apresenta informações sobre a questão anterior.', 'pointer'], 
39					['imagem_questao', 0, '<p>Imagem da Questão</p>Apresenta a questão a qual as informações se referem.', 'pointer'],
40					['proxima_questao', 0, '<p>Próxima Questão</p>Apresenta informações sobre a próxima questão.', 'pointer'], 
41					['questao_gabarito', 0, '<p>Gabarito</p>Esta é a resposta oficial esperada para esta questão. Quando a questão for anulada, considararemos que todos os candidatos a acertaram. Neste caso, não existirão índices de acerto ou discriminação definidos para ela.', ''], 
42					['inscritos', 0, '<p>Inscritos</p>Número de candidatos inscritos neste grupo.', ''], 
43					['ausentes', 0, '<p>Ausentes</p>Número de candidatos inscritos neste grupo que não estiveram presentes no dia da aplicação da prova.', ''], 
44					['media', 0, '<p>Média</p>Nota média dos candidatos, deste grupo, que estiveram presentes no dia da aplicação da prova. Este valor está entre 0 e %qtd_quest%.', ''], 
45					['max_qi', 0, '<p>Nota Máxima Quartil Inferior</p>O quartil inferior é o conjunto dos 25% dos candidatos que tiveram a pior habilidade (nota) na prova. Este valor apresentado corresponde à maior nota neste conjunto.', ''], 
46					['min_qs', 0, '<p>Nota Mínima Quartil Superior</p>O quartil superior é o conjunto dos 25% dos candidatos que tiveram a maior habilidade (nota) na prova. Este valor apresentado corresponde à menor nota neste conjunto.', ''], 
47					['funcao_logistica', 0, '<p>Função Logística</p>A função logística TRI de três parâmetros é utilizada para modelar a probabilidade de um indivíduo acertar um item (como uma questão de prova) com base em sua habilidade. Essa função gera uma curva sigmoide que representa como a probabilidade de acerto varia com a habilidade do indivíduo.', ''], 
48					['funcao_logistica_a', 0, '<p>Função Logística - Parâmetro A</p>A é o parâmetro de discriminação, que indica quão bem o item distingue entre diferentes níveis de habilidade.', ''], 
49					['funcao_logistica_b', 0, '<p>Função Logística - Parâmetro B</p>B é o parâmetro de dificuldade, que indica o nível de habilidade necessário para se ter 50% de chance de acerto, desconsiderando o chute.', ''], 
50					['funcao_logistica_c', 0, '<p>Função Logística - Parâmetro C</p>C é o parâmetro de acerto ao acaso, que é a probabilidade de se acertar, por sorte, uma questão em uma prova de múltipla escolha.', ''],
51					['retangulo_ajuda', 0, '<p>Quartil Inferior</p>Apresenta, para os 25% candidatos de pior habilidade, qual a distribuição dada das respostas. A barra mais escura corresponde à alternativa correta. Sob cada barra, está apresentado qual a porcentagem de candidatos que escolheu esta alternativa.', ''],
52					['retangulo_ajuda', 1, '<p>Grupo Completo</p>Apresenta qual a distribuição dada das respostas para todos os candidatos presentes à prova. A barra mais escura corresponde à alternativa correta. Sob cada barra, está apresentado qual a porcentagem de candidatos que escolheu esta alternativa.', ''],
53					['retangulo_ajuda', 2, '<p>Quartil Superior</p>Apresenta, para os 25% candidatos de melhor habilidade, qual a distribuição dada das respostas. A barra mais escura corresponde à alternativa correta. Sob cada barra, está apresentado qual a porcentagem de candidatos que escolheu esta alternativa.', ''],
54					['retangulo_ajuda', 3, '<p>Distribuição Habilidades</p>Esta é a distribuição da quantidade de acertos para cada candidato presente na prova. Os pequenos pontos pretos correspondem à probabilidade de acerto da questão naquela habilidade, a linha contínua representa a aproximação da função logística de três parâmetros.', '']
55				]);
56				
57				t.ig.insereInformacaoAcesso(`${t.folder}/id1f.json`, resposta => {
58					t.acessos = t.ig.formatNumber(resposta.acessos);
59					console.log(resposta);
60					t.loadClass(
61						t.ig.mobile && !jQuery.mobile,
62						t.baseURL + '/js/jquery.mobile.js', 
63						() => t.carrega_dados(t.ano, () => {}, () => alert("falha ao carregar os dados")),
64						() => {}
65					);
66				});
67				
68				
69			}, 
70			() => alert('Falha ao carregar interface_geral.js')
71		);
72		
73	}
74	
75	loadClass(doLoad, url, ok, fail) {
76		if (doLoad) {
77			var script = document.createElement('script');
78			script.src = url;
79			script.async = true;
80			script.onload = () => ok();
81			script.onerror = () => fail();
82			document.body.append(script);
83		}
84		else {
85			ok();
86		}
87	}
88
89	getScript(url, ok, fail) {
90		jQuery.getScript(url).done(function() {
91			ok();
92		}).fail(function() {
93			fail();
94		});
95	}
96	
97	async getCSS(url) {
98		jQuery.get(url, function() {
99			jQuery('<link>', {rel:'stylesheet', type:'text/css', 'href':url}).appendTo('head');
100		});
101	}
102	
103	async carrega_dados(ano, ok, fail) {
104		var t = this, i, d, r;
105		
106		await t.ig.carregaFontesEstatisticas();
107		
108		if (!t.editaisDisponiveis) {
109			r = await fetch(`${t.baseURL}/json/id1f/${t.editalFolder}/editais.json`, { method: "GET" });
110			d = await r.text();
111			t.editaisDisponiveis = JSON.parse(d);
112		}
113		
114		if (!t.gabarito) {
115			r = await fetch(`${t.folder}/id1f_gab.json`, { method: "GET" });
116			d = await r.text();
117			t.gabarito = JSON.parse(d);
118		}
119
120		if (!t.indiceDados) {
121			r = await fetch(`${t.folder}/id1f.json`, { method: "GET" });
122			d = await r.text();
123			t.indiceDados = JSON.parse(d);
124		}
125		
126
127		if (!t.dados[t.codigo_atual]) {
128			r = await fetch(`${t.folder}/id1f_${t.codigo_atual}.json`, { method: "GET" });
129			d = await r.text();
130			t.dados[t.codigo_atual] = JSON.parse(d);
131		}
132		
133		t.desenha();
134	}
135	
136	realizaTransicao(transicao) {
137		var t = this;
138		if (document.startViewTransition) {
139			jQuery(`#${t.id}`).css({"view-transition-name": transicao});
140			document.startViewTransition(() => t.desenha());
141		}
142		else {
143			t.desenha();
144		}
145	}
146	
147	pegaValores(momento, tipo) {
148		var t = this;
149		for(var i = 0; i < t.dados.length; i++) {
150			var o = t.dados[i];
151			if ((o) && (o?.momento == momento) && (o?.tipo == tipo)) {
152				return o.valores;
153			}
154		}
155		return null;
156	}
157	
158	pegaIndiceGrupo(v, val) {
159		if ((v) && (Array.isArray(v)) && (v.length > 0) && (Array.isArray(v[0]))) {
160			for(var i = 0; i < v.length; i++) {
161				if (v[i][0] == val) {
162					return i;
163				}
164			}
165		}
166		return null;
167	}
168	
169	centerText(ctx, x1, y, x2, s) {
170		var w = ctx.measureText(s).width;
171		ctx.fillText(s, x1 + (x2 - x1 - w) / 2, y);
172	}
173	
174	rightText(ctx, s, x, y) {
175		var w = ctx.measureText(s).width;
176		ctx.fillText(s, x  - w, y);
177	}
178
179	
180	desenha() {
181		var t = this, $ = jQuery, c = '', dados = t.dados[t.codigo_atual], q = dados.questoes[t.questao - 1], gab = t.gabarito[t.questao - 1], nGab = -1, i, j, param,
182				logist = function(theta) {
183					return param.C + (1 - param.C) / (1 + Math.exp(-param.A * (theta - param.B)));
184				};
185		
186		
187		if (gab.gabarito == 'A') {
188			nGab = 0;
189		}
190		else if (gab.gabarito == 'B') {
191			nGab = 1;
192		}
193		else if (gab.gabarito == 'C') {
194			nGab = 2;
195		}
196		else if (gab.gabarito == 'D') {
197			nGab = 3;
198		}
199		else if (gab.gabarito == 'E') {
200			nGab = 4;
201		}
202		
203		if (nGab >= 0) {
204			param = q.parametros[nGab];
205		}
206		
207		c =	`<div id="${t.id}_container_principal" style="overflow:hidden;height:100%;">` +
208					`<div style="padding:10px;">` +
209						
210						`<div id="${t.id}_fechar_janela" style="position:absolute;top:12px;right:12px;font-family:FontAwesome;font-size:24px;cursor:pointer;color:var(--est_cor_bronze_fuvest);">\uf00d</div>` +
211						
212						`<div id="${t.id}_ajuda" style="position:absolute;top:12px;right:40px;padding:4px;font-size:18px;cursor:pointer;color:white;background-color:var(--est_cor_bronze_fuvest);border-radius:8px;">
212ajuda <span style="font-family:FontAwesome;">\uf059</span></div>` +
213						
214						`<div id="${t.id}_altera_edital" style="cursor:pointer;">` +
215							`<div class="esTitulo" style="font-size:18px;font-weight:800;">${t.indiceDados.nome_edital}</div>` + 
216							`<div class="esTitulo" style="font-size:16px;padding:4px 0px;margin-top:-8px;">Análise Questões 1ª Fase</div>` + 
217						`</div>` +
218						`<div style="position:relative;">` +
219						
220							`<div id="${t.id}_download_xls" style="position:absolute;top:0px;right:44px;width:32px;height:32px;padding:4px;border-radius:4px;color:white;background-color:var(--est_cor_bronze_fuvest);text-align:center;cursor:pointer;">` +
221								`<div style="font-size:12px;">xlsx</div>` +
222								`<div style="font-family:FontAwesomeEstat;">\uf019</div>` +
223							`</div>` +
224							
225							`<div id="${t.id}_download_pdf" style="position:absolute;top:0px;right:0px;width:32px;height:32px;padding:4px;border-radius:4px;color:white;background-color:var(--est_cor_bronze_fuvest);text-align:center;cursor:pointer;">` +
226								`<div style="font-size:12px;">pdf</div>` +
227								`<div style="font-family:FontAwesomeEstat;">\uf019</div>` +
228							`</div>` +
229							`<div id="${t.id}_seleciona_grupo" style="display:flex;gap:4px;padding:4px 4px;min-height:32px;margin-right:86px;border-radius:4px;background-color:rgba(240,240,240,0.25);border:solid 1px rgba(240,240,240,0.75);cursor:pointer;">` + 
230								`<div id="${t.id}_seleciona_grupo_icone" style="flex-grow:0;flex-shrink:0;" class="esFa">\uf078</div>` +
231								`<div style="flex-grow:1;">` + 
232									`<div style="font-size:16px;font-weight:600;">${dados.nome}</div>` + 
233									`<div style="font-size:12px;font-weight:500;">${dados.detalhe || ''}</div>` + 
234								`</div>` +
235							`</div>` +
236						`</div>` +
237						`<div class="e" style="position:relative;margin-top:4px;padding:8px;height:16px;border-radius:4px;background-color:rgba(240,240,240,0.25);border:solid 1px rgba(240,240,240,0.75);">` +
238							`<div id="${t.id}_questao_anterior" class="esFa" style="position:absolute;cursor:pointer;top:8px;left:8px;font-size:16px;">\uf0d9</div>` +
239							`<div id="${t.id}_imagem_questao" style="position:absolute;cursor:pointer;top:8px;left:28px;"><span class="esFa">\uf03e</span> <span style="margin-left:20px;">Questão ${t.questao}</span></div>` +
240							`<div id="${t.id}_proxima_questao" class="esFa" style="position:absolute;cursor:pointer;top:8px;right:8px;font-size:16px;">\uf0da</div>` +
241						`</div>` +
242						`<div style="display:flex;gap:4px;padding:4px 0px 0px 0px;">` +
243							`<div id="${t.id}_questao_gabarito" class="esDataContainer esLightBlue">` + 
244								`<div class="esDataCaption">Gabarito</div>` +
245								`<div class="esDataVal"><span style="font-size:20px;padding-bottom:4px;font-weight:600;">${gab.gabarito}</span></div>` +
246							`</div>` +
247							`<div id="${t.id}_inscritos" class="esDataContainer esLightBlue">` + 
248								`<div class="esDataCaption">Inscritos</div>` +
249								`<div class="esDataVal"><span>${t.ig.formatNumber(dados.inscritos)}</span></div>` +
250							`</div>` +
251							`<div id="${t.id}_ausentes" class="esDataContainer esLightBlue">` + 
252								`<div class="esDataCaption">Ausentes</div>` +
253								`<div class="esDataVal"><span>${t.ig.formatNumber(dados.ausentes)}</span></div>` +
254							`</div>` +
255							
256							`<div id="${t.id}_media" class="esDataContainer esLightBlue">` + 
257								`<div class="esDataCaption">Média</div>` +
258								`<div class="esDataVal"><span>${t.ig.formatFloat(dados.media, 2)}</span></div>` +
259							`</div>` +
260							
261							`<div id="${t.id}_max_qi" class="esDataContainer esLightBlue">` + 
262								`<div class="esDataCaption">Nota Máxima</div>` +
263								`<div class="esDataCaption">Quartil Inferior</div>` +
264								`<div class="esDataVal"><span>${t.ig.formatNumber(dados.maxQI)}</span></div>` +
265							`</div>` +
266							
267							`<div id="${t.id}_min_qs" class="esDataContainer esLightBlue">` + 
268								`<div class="esDataCaption">Nota Mínima</div>` +
269								`<div class="esDataCaption">Quartil Superior</div>` +
270								`<div class="esDataVal"><span>${t.ig.formatNumber(dados.minQS)}</span></div>` +
271							`</div>` +
272						`</div>` +
273						`<div style="display:flex;gap:4px;padding:4px 0px 4px 0px;height:50px;">` +
274							`<div id="${t.id}_funcao_logistica" class="esDataContainer esLightBlue">` + 
275								`<div class="esDataVal"><span><img style="height:40px;" src="${t.baseURL}/images/estatisticas/tri_3param.png"></span></div>` +
276							`</div>` +
277							`<div id="${t.id}_funcao_logistica_a" class="esDataContainer esLightBlue">` + 
278								`<div class="esDataCaption">Parâmetro&nbsp;A</div>` +
279								`<div class="esDataVal"><span>${t.ig.formatFloat(param.A, 3)}</span></div>` +
280							`</div>` +
281							`<div id="${t.id}_funcao_logistica_b" class="esDataContainer esLightBlue">` + 
282								`<div class="esDataCaption">Parâmetro&nbsp;B</div>` +
283								`<div class="esDataVal"><span>${t.ig.formatFloat(param.B, 3)}</span></div>` +
284							`</div>` +
285							`<div id="${t.id}_funcao_logistica_c" class="esDataContainer esLightBlue">` + 
286								`<div class="esDataCaption">Parâmetro&nbsp;C</div>` +
287								`<div class="esDataVal"><span>${t.ig.formatFloat(param.C, 3)}</span></div>` +
288							`</div>` +
289						`</div>` +
290						`<canvas id="${t.id}_canvas" style="width:100%;height:10px;"></canvas>` +
291					`</div>` +
292				`</div>`;
293		
294		$(`#${t.id}`).html(c);
295		
296		t.ig.atualizaDadosBotoes();
297		
298		// redimensionar o canvas
299		var canvas = $(`#${t.id}_canvas`), y = canvas.position().top, h = $(`#${t.id}_container`).height(), w = canvas.width(), cv = canvas[0], hist = [], wg, hg = 200, rmax = 4 * w / 667;
300		
301		h = h - y - 10;
302		
303		canvas.height(h);
304		
305		wg = (w - 25) / 3;
306		if (wg > 200) {
307			wg = 200;
308		}
309		if (hg > wg) {
310			hg = wg;
311		}
312		
313		cv.width = w;
314		cv.height = h;
315		var ctx = cv.getContext('2d');
316		
317		ctx.imageSmoothingEnabled = true;
318		
319		for(j = 0; j < 3; j++) {
320			hist[j] = [0, 0, 0, 0, 0, 0, 0];
321		}
322		
323		for(i = 0; i < q.hb.length; i++) {
324			for(j = 0; j < 5; j++) {
325				hist[1][5] += q.hb[i][1][j][1];
326				hist[1][j] += q.hb[i][1][j][1];
327				if (hist[1][j] > hist[1][6]) {
328					hist[1][6] = hist[1][j];
329				}
330				
331				if (i <= dados.maxQI) {
332					hist[0][5] += q.hb[i][1][j][1];
333					hist[0][j] += q.hb[i][1][j][1];
334					if (hist[0][j] > hist[0][6]) {
335						hist[0][6] = hist[1][j];
336					}
337				}
338				
339				if (i >= dados.minQS) {
340					hist[2][5] += q.hb[i][1][j][1];
341					hist[2][j] += q.hb[i][1][j][1];
342					if (hist[2][j] > hist[2][6]) {
343						hist[2][6] = hist[2][j];
344					}
345				}
346			}
347		}
348		
349		var id = q.iaqs - q.iaqi;
350		
351		if (id < 0) {
352			id = 0;
353		}
354		
355		const titulos = ['quartil inferior', 'grupo completo', 'quartil superior'],
356					valores = [`ia: ${t.ig.formatFloat(q.iaqi)}%`, `ia: ${t.ig.formatFloat(q.ia)}% | id: ${t.ig.formatFloat(id)}%`, `ia: ${t.ig.formatFloat(q.iaqs)}%`];
357		
358		for(j = 0; j < 3; j++) {
359			var x = 5 + (w / 3) * j, y = 5, hb = hg - 80, wb = (wg - 20) / 5;
360			
361			ctx.beginPath();
362			ctx.strokeStyle = "rgba(128,128,128,0.5)";
363			ctx.fillStyle = "rgba(255,255,255,0.25)";
364			ctx.roundRect(x, y, wg, hg, [20]);
365			ctx.stroke();
366			ctx.fill();
367			t.ig.iniciaRetanguloAjuda(j, 17 + j, [x, y, x + wg, y + hg]);
368			
369			ctx.fillStyle = "black";
370			ctx.font = "600 12px BalooEst";
371			t.centerText(ctx, x, y + 15, x + wg, titulos[j]);
372			
373			ctx.font = "600 12px BalooEst";
374			t.centerText(ctx, x, y + 30, x + wg, valores[j]);
375			
376			for(i = 0; i < 5; i++) {
377				var xb = x + (i * wb) + 10, yb = y + hg - 30, hbi = hb * hist[j][i] / hist[j][6];
378				ctx.beginPath();
379				ctx.strokeStyle = "silver";
380				if (nGab == i) {
381					ctx.fillStyle = ["rgb(255,0,0)","rgb(0,255,0)","rgb(0,0,255)"][j];
382				}
383				else {
384					ctx.fillStyle = ["rgb(255,164,164)","rgb(164,255,164)","rgb(164,164,255)"][j];
385				}
386				
387				ctx.rect(xb, yb - hbi, wb, hbi);
388				ctx.stroke();
389				ctx.fill();
390				
391				ctx.font = "bold 12px Arial";
392				t.centerText(ctx, xb, y + hg - 14, xb + wb, 'ABCDE'[i]);
393				
394				ctx.font = "8px Arial";
395				t.centerText(ctx, xb, y + hg - 4, xb + wb, t.ig.formatFloat(100 * hist[j][i] / hist[j][5]));
396			}
397		}
398		var x = 5, yb = h - 32, wb = (w - 40) / dados.hist.length, hb = h - hg - 80, max = 0, xold = 0;
399		
400		t.ig.iniciaRetanguloAjuda(3, 20, [x, yb - hb, x + w, yb + 32]);
401
402		for(i = 0; i < dados.hist.length; i++) {
403			if (dados.hist[i] > max) {
404				max = dados.hist[i];
405			}
406		}
407		
408		ctx.fillStyle = "black";
409		ctx.font = "bold 10px helvetica";
410		t.centerText(ctx, 0, h - 4, w, '\u03b8 - habilidade do candidato na prova - corresponde ao número de acertos');
411		
412		var s = 'P(\u03b8) - probabilidade de acerto da questão', ws = ctx.measureText(s).width;
413		ctx.fillStyle = "rgb(184,110,24)";
414		ctx.font = "bold 10px helvetica";
415		ctx.save();
416		ctx.translate(x, yb - (hb - ws) / 2);
417		ctx.rotate(-Math.PI / 2);
418		ctx.fillText(s, 0, 5);
419		ctx.restore();
420		
421		ctx.fillStyle = "black";
422		ctx.font = "bold 10px helvetica";
423		s = 'Número de Candidatos';
424		ws = ctx.measureText(s).width;
425		ctx.save();
426		ctx.translate(x + w - 20, yb - (hb - ws) / 2);
427		ctx.rotate(-Math.PI / 2);
428		ctx.fillText(s, 0, 5);
429		ctx.restore();
430		
431		ctx.font = "8px helvetica";
432		ctx.strokeStyle = "rgb(184,110,24)";
433		for(i = 0; i < 11; i++) {
434			var hbi = hb * i / 10;
435			ctx.beginPath();
436			ctx.moveTo(x + (0 * wb + (wb / 2)) + 10, yb - hbi);
437			ctx.lineTo(x + (dados.hist.length * wb + (wb / 2)) + 10, yb - hbi);
438			ctx.stroke();
439			
440			ctx.fillStyle = "rgb(184,110,24)";
441			ctx.fillText((i * 10) + '%', x + (0 * wb + (wb / 2)) + 12, yb - hbi - 2);
442			
443			ctx.fillStyle = "black";
444			t.rightText(ctx, Math.round(max * i / 10), x + (dados.hist.length * wb + (wb / 2)) + 5, yb - hbi - 2);
445		}
446		
447		
448		for(i = 0; i < dados.hist.length; i++) {
449			var xb = x + (i * wb) + 10, hbi = hb * dados.hist[i] / max;
450
451			if ((i % 5) == 0) {
452				ctx.strokeStyle = "silver";
453				ctx.beginPath();
454				ctx.moveTo(xb + (0.5 * wb), yb);
455				ctx.lineTo(xb + (0.5 * wb), yb - hb);
456				ctx.stroke();
457			}
458
459			ctx.beginPath();
460			ctx.strokeStyle = "silver";
461			ctx.fillStyle = "rgb(220,220,255)";
462			ctx.rect(xb, yb - hbi, wb, hbi);
463			ctx.stroke();
464			ctx.fill();
465			
466			if ((xb - xold) > 20) {
467				ctx.fillStyle = "black";
468				ctx.font = "bold 10px Arial";
469				t.centerText(ctx, xb, h - 18, xb + wb, i);
470				xold = xb;
471			}
472		}
473		
474		if (nGab >= 0) {
475			for(i = 0; i < q.hb.length; i++) {
476				if (q.hb[i][1][nGab][1] > 0) {
477					var peso = 0;
478					for(var j = 0; j < 6; j++) {
479						peso += q.hb[i][1][j][1];
480					}
481
482					var v = q.hb[i][1][nGab][0], xb = x + (i * wb + (wb / 2)) + 10, hbi = hb * v, r = (max == 0) ? 1 : rmax * q.hb[i][1][nGab][1] / max;
483					
484					if (r < 0.5) {
485						r = 0.5;
486					}
487					
488					ctx.beginPath();
489					ctx.fillStyle = "black";
490					ctx.arc(xb, yb - hbi, r, 0, 2 * Math.PI);
491					ctx.fill();
492				}
493			}
494			
495			ctx.strokeStyle = "gray";
496			ctx.beginPath();
497			for(i = 0; i < q.hb.length; i++) {
498				var xb = x + (i * wb + (wb / 2)) + 10, hbi = hb * logist(i);
499				if (i == 0) {
500					ctx.moveTo(xb, yb - hbi);
501				}
502				else {
503					ctx.lineTo(xb, yb - hbi);
504				}
505			}
506			ctx.stroke();
507		}
508		
509		
510		$(`#${t.id}_questao_anterior`).click(function(e) {
511			if (!t.ig.ajuda(e, this)) {
512				--t.questao;
513				if (t.questao < 1) {
514					t.questao = dados.questoes.length;
515				}
516				t.realizaTransicao(t.ig.mobile ? "slide_right" : "");
517			}
518		});
519		
520		$(`#${t.id}_proxima_questao`).click(function(e) {
521			if (!t.ig.ajuda(e, this)) {
522				++t.questao;
523				if (t.questao > dados.questoes.length) {
524					t.questao = 1;
525				}
526				t.realizaTransicao(t.ig.mobile ? "slide_left" : "");
527			}
528			e.stopPropagation();
529		});
530
531				
532		$(`#${t.id}_ajuda`).click(e => t.ig.entraModoAjuda(e));
533		
534		$(`#${t.id}_altera_edital`).click(function(e) {
535			if (!t.ig.ajuda(e, this)) {
536				var p = $(this), win = $(window), o = p.offset(), w = 320, y = o.top + p.height() - win.scrollTop(), x = o.left, c = '', id = t.id + "_altera_edital_dialogo";
537				
538				for(var i = 0; i < t.editaisDisponiveis.length; i++) {
539					if (t.editaisDisponiveis[i][2] != t.ano) {
540						c += `<div id="${id}_opcao_${i}" data-indice="${i}" style="padding:8px 4px;
540cursor:pointer;">${t.editaisDisponiveis[i][0]}</div>`;
541					}
542				}
543				
544				c +=	`<div id="${id}_background" style="position:fixed;inset:0px;background-color:var(--est_cor_background);z-index:var(--help_zindex);"></div>` +
545							`<div id="${id}" class="esNoSelect" style="position:fixed;left:${x}px;top:${y}px;width:${w}px;background-color:white;z-index:var(--help_zindex);border-radius:8px;box-shadow:0 3px 3px rgba(0,0,0,0.2);">` + 
546								`<div class="e" style="position:absolute;top:0px;left:0px;width:100%;height:16px;font-weight:600;background-color:var(--es_caption_background);color:white;text-align:center;padding:8px 0px;border-top-left-radius:8px;border-top-right-radius:8px;">` +
547									`Analisar Outro Edital` +
548									`<div id="${id}_close" class="esFa" style="position:absolute;top:4px;right:8px;color:white;font-size:20px;cursor:pointer;">\uf00d</div>` +
549								`</div>` +
550								`<div class="esSmall" style="margin-top:30px;max-height:240px;overflow:auto;"><div style="padding:4px;">${c}</div></div>` +
551							`</div>`;
552				$('body').append(c);
553				
554				$(`[id^='${id}_opcao_']`).click(function() {
555					var b = $(this), indice = b.data('indice');
556					t.ano = t.editaisDisponiveis[indice][2];
557					t.folder = t.baseURL + '/json/id1f/' + t.editaisDisponiveis[indice][1];
558					t.dados = {};
559					t.gabarito = null;
560					t.indiceDados = null;
561					t.codigo_atual = 'tot';
562					t.questao = 1;
563					$(`#${id}_close`).click();
564					t.carrega_dados(t.ano, () => {}, () => alert("falha ao carregar os dados"))
565				});
566				
567				$(`#${id}_close`).click(() => $(`#${id}_background`).click());
568				
569				$(`#${id}_background`).click(() => {
570					$(`#${id}_background`).remove();
571					$(`#${id}`).remove();
572				});
573			}
574		});
575		
576		$(`#${t.id}_questao_gabarito`).click(function(e) { t.ig.ajuda(e, this) });
577		
578		$(`#${t.id}_inscritos`).click(function(e) { t.ig.ajuda(e, this) });
579		
580		$(`#${t.id}_ausentes`).click(function(e) { t.ig.ajuda(e, this) });
581		
582		$(`#${t.id}_media`).click(function(e) { t.ig.ajuda(e, this) });
583		
584		$(`#${t.id}_max_qi`).click(function(e) { t.ig.ajuda(e, this) });
585		
586		$(`#${t.id}_min_qs`).click(function(e) { t.ig.ajuda(e, this) });
587		
588		$(`#${t.id}_funcao_logistica`).click(function(e) { t.ig.ajuda(e, this) });
589		
590		$(`#${t.id}_funcao_logistica_a`).click(function(e) { t.ig.ajuda(e, this) });
591		
592		$(`#${t.id}_funcao_logistica_b`).click(function(e) { t.ig.ajuda(e, this) });
593		
594		$(`#${t.id}_funcao_logistica_c`).click(function(e) { t.ig.ajuda(e, this) });
595		
596		$(`#${t.id}_fechar_janela`).click(() => t.ig.fechar());
597		
598		if ((t.ig.mobile) && (jQuery.mobile)) {
599			// habilitar o swipe
600			$(`#${t.id}_container`).off("swipe").on("swipe", e => {
601				if (e.swipestart.coords[0] > e.swipestop.coords[0]) {
602					$(`#${t.id}_proxima_questao`).click();
603				}
604				else {
605					$(`#${t.id}_questao_anterior`).click();
606				}
607			});
608		}
609
610		$(`#${t.id}_imagem_questao`).click(function(e) {
611			if (t.ig.ajuda(e, this)) {
612				return;
613			}
614			
615			var c = `<div id="${t.id}_imagem_questao_background" class="esSmallBar" style="position:fixed;inset:0px;background-color:rgba(0,0,0,0.75);overflow:auto;padding:10px;z-index:30001;text-align:center;">`;
616			
617			c += `<div id="${t.id}_imagem_questao_background_close" style="position:fixed;
617font-family:FontAwesome;font-size:24px;top:10px;right:20px;color:red;cursor:pointer;">\uf00d</div>`;
618			
619			c += '<div style="background-color:white;margin:auto;padding:4px;max-width:75%;">';
620			for(var i = 0; i < gab.imagem.length; i++) {
621				if (gab.imagem[i] != '') {
622					c += `<img style="width:100%;" src="${t.folder}/prova11/${gab.imagem[i]}">`;
623				}
624			}
625			c += '</div>';
626			
627			c += '</div>';
628			
629			$('body').append(c);
630			
631			$(`#${t.id}_imagem_questao_background_close`).click(() => {
632				$(`#${t.id}_imagem_questao_background`).remove();
633			});
634		});
635	
636	
637		$(`#${t.id}_seleciona_grupo`).click(function(e) {
638			if (t.ig.ajuda(e, this)) {
639				return;
640			}
641			
642			// apresenta combo de grupos disponíveis
643			var id = t.id + '_select_group', b = $(this), win = $(window), x = b.offset().left - win.scrollLeft(), y = b.offset().top - win.scrollTop() + 20, c,
644					orderIcon = function(i, v1, v2) {
645						if (i == v1) {
646							return '<span style="font-family:FontAwesomeEstat;font-size:12px;">\uf062</span> ';
647						}
648						else if (i == v2) {
649							return '<span style="font-family:FontAwesomeEstat;font-size:12px;">\uf063</span> ';
650						}
651						else {
652							return '';
653						}
654					},
655					alteraOrdemPesquisa = function() {
656						if ((t.ordemPesquisa == 'ia') || (t.ordemPesquisa == 'iad') || (t.ordemPesquisa == 'id') || (t.ordemPesquisa == 'idd')) {
657							var mult = ((t.ordemPesquisa == 'iad') || (t.ordemPesquisa == 'idd')) ? 1 : -1, idx = ((t.ordemPesquisa == 'ia') || (t.ordemPesquisa == 'iad')) ? 0 : 1;
658							t.indiceDados.grupos.sort((a, b) => {
659								if ((a.ia.length > 0) && (b.ia.length > 0)) {
660									return mult * (b.ia[t.questao - 1][idx] - a.ia[t.questao - 1][idx]);
661								}
662								else {
663									return 0;
664								}
665							});
666						}
667						else if ((t.ordemPesquisa == 'nome') || (t.ordemPesquisa == 'nomed')) {
668							var mult = (t.ordemPesquisa == 'nomed') ? 1 : -1;
669							t.indiceDados.grupos.sort((a, b) => {
670								return mult * (b.nome.localeCompare(a.nome));
671							});
672						}
673					},
674					match = function(a, s) {
675						for(var i = 0; i < a.length; i++) {
676							if (s.indexOf(a[i]) < 0) {
677								return false;
678							}
679						}
680						return true;
681					},
682					refresh = function() {
683						var c = '', filtro = t.ig.formatSearch($(`#${id}_filtro`).val()).replace(',', ' ').replace('.', ' ').replace('-', ' '), aFiltro = filtro.split(' ');
684						
685						$(`#${id}_cabecalho_pesquisa`).html(
686							`<div id="${id}_ordem_nome" style="flex:0 1 calc(100% - 80px);cursor:pointer;">${orderIcon(t.ordemPesquisa, 'nome', 'nomed')}Nome da Carreira</div>` + 
687							`<div id="${id}_ordem_ia" style="flex:0 0 40px;text-align:right;border-left:dotted 1px gray;cursor:pointer;">${orderIcon(t.ordemPesquisa, 'ia', 'iad')}ia</div>` + 
688							`<div id="${id}_ordem_id" style="flex:0 0 40px;text-align:right;border-left:dotted 1px gray;cursor:pointer;">${orderIcon(t.ordemPesquisa, 'id', 'idd')}id</div>`
689						);
690						
691						$(`#${id}_ordem_nome`).click(() => {
692							if (t.ordemPesquisa == 'nome') {
693								t.ordemPesquisa = 'nomed';
694							}
695							else {
696								t.ordemPesquisa = 'nome';
697							}
698							alteraOrdemPesquisa();
699							refresh();
700						});
701						
702						$(`#${id}_ordem_ia`).click(() => {
703							if (t.ordemPesquisa == 'ia') {
704								t.ordemPesquisa = 'iad';
705							}
706							else {
707								t.ordemPesquisa = 'ia';
708							}
709							alteraOrdemPesquisa();
710							refresh();
711						});
712						
713						$(`#${id}_ordem_id`).click(() => {
714							if (t.ordemPesquisa == 'id') {
715								t.ordemPesquisa = 'idd';
716							}
717							else {
718								t.ordemPesquisa = 'id';
719							}
720							alteraOrdemPesquisa();
721							refresh();
722						});
723						
724						for(var i = 0; i < t.indiceDados.grupos.length; i++) {
725							var g = t.indiceDados.grupos[i], s = g.nome;
726							if ((filtro == '') || match(aFiltro, t.ig.formatSearch(s))) {
727								var v = (g.ia.length > 0) ? g.ia[t.questao - 1] : [0, 0];
728								if (t.codigo_atual == g.codigo.toLowerCase()) {
729									s += '<div style="position:absolute;top:4px;right:3px;font-family:FontAwesome;font-size:16px;">\uf00c</div>';
730								}
731								
732								c +=	`<div id="${id}_grupo_item_${i}" data-grupo="${i}" class="esMenuItem" style="display:flex;gap:2px;">` + 
733												`<div style="flex:0 1 calc(100% - 80px);position:relative;">${s}</div>` + 
734												`<div style="flex:0 0 40px;text-align:right;border-left:dotted 1px gray;font-size:12px;">${t.ig.formatFloat(v[0])}</div>` + 
735												`<div style="flex:0 0 40px;text-align:right;border-left:dotted 1px gray;font-size:12px;">${t.ig.formatFloat(v[1])}</div>` + 
736											`</div>`;
737							}
738						}
739						$(`#${id}_dlg_content`).html(c);
740						
741						$(`[id^='${id}_grupo_item_']`).click(function() {
742							t.codigo_atual = t.indiceDados.grupos[$(this).data('grupo')].codigo;
743							$(`#${id}_back`).click();
744							t.carrega_dados(t.ano, () => {}, () => {});
745						});
746					};
747					
748			alteraOrdemPesquisa();
749			
750			$(`#${t.id}_seleciona_grupo_icone`).html('\uf077');
751
752			c = `<div id="${id}_back" style="position:fixed;inset:0px;background-color:rgba(0,0,0,0.5);"></div>` +
753					`<div id="${id}_dlg" class="esDialogo" style="left:${x}px;top:${y}px;width:320px;height:420px;">` +
754						`<div style="padding:10px;height:calc(100% - 20px);">` +
755							`<div style="height:54px;text-align:right;">` + 
756								`<div style="font-family:FontAwesome;">` + 
757									`\uf0b0</span> `+
758									`<input id="${id}_filtro" class="esFiltro" type="TEXT" placeholder="-- filtro --" style="width:100px;">`+
759								`</div>` +
760								`<div id="${id}_cabecalho_pesquisa" style="display:flex;padding:4px 0px;gap:2px;font-size:14px;font-weight:600;text-align:center;margin-top:2px;border-bottom:dotted 1px gray;border-top:dotted 1px gray;margin-right:20px;"></div>` +
761							`</div>` +
762							`<div id="${id}_dlg_content" class="sb" style="border-radius:4px;width:100%;height:calc(100% - 64px);background-color:#f7f7f7;overflow:auto;">conteúdo</div>` +
763						`</div>` +
764					`</div>`;
765			$(`#${t.id}`).append(c);
766			
767			refresh();
768			
769			$(`#${id}_filtro`).keyup(() => refresh());
770			
771			
772			$(`#${id}_back`).click(function() {
773				$(`#${t.id}_seleciona_grupo_icone`).html('\uf078');
774				$(`#${id}_back`).remove();
775				$(`#${id}_dlg`).remove();
776			});
777
778			
779		});
780
781	
782		$(`#${t.id}_download_pdf`).click(function(e) {
783			if (!t.ig.ajuda(e, this)) {
784				window.location.href = `${t.folder}/pdf/${dados.file_name}`;
785			}
786		});
787	
788		$(`#${t.id}`).click(() => t.ig.encerraModoAjuda());
789
790		$(`#${t.id}_download_xls`).click(function(e) {
791			if (t.ig.ajuda(e, this)) {
792				return;
793			}
794			
795			var title = 'planilha', workbook = excelbuilder.createWorkbook(),
796					filename = dados.nome + (dados.detalhe ? ('_' + dados.detalhe) : '');
797					
798			if (true) {
799				var sheet1 = workbook.createSheet('resumo prova', 10, dados.hist.length + 30), lin = 10;
800				
801				sheet1.width(1, 30);
802				sheet1.width(2, 30);
803				t.ig.colVal(sheet1, 1, 1, t.indiceDados.nome_edital, {align: 'center', bold: true, colFim: 2, bold: true, borderStyle:{}});
804				t.ig.colVal(sheet1, 1, 2, 'Análise Questões 1ª Fase', {align: 'center', bold: true, colFim: 2, bold: true, borderStyle:{}});
805				
806				t.ig.colVal(sheet1, 1, 4, 'Inscritos', {bold: 'true', borderStyle:{}});
807				t.ig.colVal(sheet1, 2, 4, t.ig.formatNumber(dados.inscritos), {align: 'right', borderStyle:{}});
808				
809				t.ig.colVal(sheet1, 1, 5, 'Ausentes', {bold: 'true', borderStyle:{}});
810				t.ig.colVal(sheet1, 2, 5, t.ig.formatNumber(dados.ausentes), {align: 'right', borderStyle:{}});
811				
812				t.ig.colVal(sheet1, 1, 6, 'Média', {bold: 'true', borderStyle:{}});
813				t.ig.colVal(sheet1, 2, 6, t.ig.formatFloat(dados.media, 2), {align: 'right', borderStyle:{}});
814				
815				t.ig.colVal(sheet1, 1, 7, 'Nota Máxima Quartil Inferior', {bold: 'true', borderStyle:{}});
816				t.ig.colVal(sheet1, 2, 7, t.ig.formatNumber(dados.maxQI), {align: 'right', borderStyle:{}});
817				
818				t.ig.colVal(sheet1, 1, 8, 'Nota Mínima Quartil Superior', {bold: 'true', borderStyle:{}});
819				t.ig.colVal(sheet1, 2, 8, t.ig.formatNumber(dados.minQS), {align: 'right', borderStyle:{}});
820				
821				lin = 10;
822				t.ig.colVal(sheet1, 1, lin, 'habilidade', {align: 'center', bold: true});
823				t.ig.colVal(sheet1, 2, lin, 'candidatos', {align: 'center', bold: true});
824
825				++lin;
826				for(i = 0; i < dados.hist.length; i++) {
827					t.ig.colVal(sheet1, 1, lin + i, i, {align: 'right', bold: true});
828					t.ig.colVal(sheet1, 2, lin + i, dados.hist[i], {align: 'right'});
829				}
830			}
831					
832			for(var questao = 0; questao < dados.questoes.length; ++questao) {
833				var	col, lin, cols = 10, q = dados.questoes[questao], gab = t.gabarito[questao], nGab = -1,
834						sheet1 = workbook.createSheet('questão ' + (questao + 1), 10, q.hb.length + 30),
835						bgHeader = {type:'solid',fgColor:'FF92D050',bgColor:'64'},
836						bgData = {type:'solid',fgColor:'FFFFC0C0',bgColor:'64'},
837						borderHeader = {left:'medium',top:'medium',right:'thin',bottom:'medium'},
838						borderData = {left:'thin',top:'thin',right:'thin',bottom:'thin'},
839						border = function(coluna, linha, warning = false) {
840							sheet1.border(coluna, linha, borderData);
841							if (warning) {
842								sheet1.fill(coluna, linha, bgData);
843							}
844						},
845						d = function(hab, o) {
846							var soma = o[5][1];
847							t.ig.colVal(sheet1, 1, lin, hab, {align: 'right', bold: true});
848							for(var i = 0; i < 5; i++) {
849								var fillStyle = (nGab == i) ? bgData : {};
850								t.ig.colVal(sheet1, i + 2, lin, o[i][1], {align: 'right', fillStyle: fillStyle});
851								soma += o[i][1];
852							}
853							t.ig.colVal(sheet1, 7, lin, soma, {align: 'right', fontColor: "FFFF0000"});
854							++lin;
855						};
856						
857				if (gab.gabarito == 'A') {
858					nGab = 0;
859				}
860				else if (gab.gabarito == 'B') {
861					nGab = 1;
862				}
863				else if (gab.gabarito == 'C') {
864					nGab = 2;
865				}
866				else if (gab.gabarito == 'D') {
867					nGab = 3;
868				}
869				else if (gab.gabarito == 'E') {
870					nGab = 4;
871				}
872				
873				var id = q.iaqs - q.iaqi;
874				
875				if (id < 0) {
876					id = 0;
877				}
878				
879				sheet1.width(1, 20);
880				
881				t.ig.colVal(sheet1, 1, 1, t.indiceDados.nome_edital, {align: 'center', bold: true, colFim: 7, bold: true, borderStyle:{}});
882				t.ig.colVal(sheet1, 1, 2, 'Análise Questões 1ª Fase', {align: 'center', bold: true, colFim: 7, bold: true, borderStyle:{}});
883				t.ig.colVal(sheet1, 1, 3, 'Questão ' + (questao + 1), {align: 'center', bold: true, colFim: 7, bold: true, borderStyle:{}});
884				
885				t.ig.colVal(sheet1, 1, 4, 'Gabarito', {bold: 'true', borderStyle:{}});
886				t.ig.colVal(sheet1, 2, 4, gab.gabarito, {align: 'right', borderStyle:{}});
887				
888				t.ig.colVal(sheet1, 1, 5, 'IA Quartil Inferior', {bold: 'true', borderStyle:{}});
889				t.ig.colVal(sheet1, 2, 5, t.ig.formatFloat(q.iaqi, 2), {align: 'right', borderStyle:{}});
890				
891				t.ig.colVal(sheet1, 1, 6, 'IA', {bold: 'true', borderStyle:{}});
892				t.ig.colVal(sheet1, 2, 6, t.ig.formatFloat(q.ia, 2), {align: 'right', borderStyle:{}});
893				
894				t.ig.colVal(sheet1, 1, 7, 'IA Quartil Superior', {bold: 'true', borderStyle:{}});
895				t.ig.colVal(sheet1, 2, 7, t.ig.formatFloat(q.iaqs, 2), {align: 'right', borderStyle:{}});
896				
897				t.ig.colVal(sheet1, 1, 8, 'ID', {bold: 'true', borderStyle:{}});
898				t.ig.colVal(sheet1, 2, 8, t.ig.formatFloat(id, 2), {align: 'right', borderStyle:{}});
899				
900				if (nGab >= 0) {
901					var param = q.parametros[nGab];
902					t.ig.colVal(sheet1, 1, 9, 'Parâmetros Função Logística', {bold: 'true', borderStyle:{}});
903					t.ig.colVal(sheet1, 2, 9, 'A', {bold: 'true', borderStyle:{}});
904					t.ig.colVal(sheet1, 3, 9, t.ig.formatFloat(param.A, 2), {align: 'right', borderStyle:{}});
905					t.ig.colVal(sheet1, 4, 9, 'B', {bold: 'true', borderStyle:{}});
906					t.ig.colVal(sheet1, 5, 9, t.ig.formatFloat(param.B, 2), {align: 'right', borderStyle:{}});
907					t.ig.colVal(sheet1, 6, 9, 'C', {bold: 'true', borderStyle:{}});
908					t.ig.colVal(sheet1, 7, 9, t.ig.formatFloat(param.C, 2), {align: 'right', borderStyle:{}});
909				}
910				
911				lin = 11;
912				t.ig.colVal(sheet1, 1, lin, 'habilidade', {align: 'center', bold: true, linFim: lin + 1});
913				t.ig.colVal(sheet1, 2, lin, 'quantos responderam', {align: 'center', bold: true, colFim: 6});
914				t.ig.colVal(sheet1, 2, lin + 1, 'A', {align: 'center', bold: true});
915				t.ig.colVal(sheet1, 3, lin + 1, 'B', {align: 'center', bold: true});
916				t.ig.colVal(sheet1, 4, lin + 1, 'C', {align: 'center', bold: true});
917				t.ig.colVal(sheet1, 5, lin + 1, 'D', {align: 'center', bold: true});
918				t.ig.colVal(sheet1, 6, lin + 1, 'E', {align: 'center', bold: true});
919				t.ig.colVal(sheet1, 7, lin, 'total respostas', {align: 'center', bold: true, linFim: lin + 1, wrap: 'true'});
920
921				
922				++lin;
923				++lin;
924				for(i = 0; i < q.hb.length; i++) {
925					d(i, q.hb[i][1]);
926				}
927			}
928			
929			filename = filename.toLowerCase().replace(/ /g, '_')+'.xlsx';
930			
931			workbook.generate(function (err, jszip) {
932				if (err) return callback(err);
933
934				jszip.generateAsync({type: "blob", mimeType: 'application/vnd.ms-excel;'}).then(function (blob) {
935					if (navigator.msSaveBlob) { // IE 10+
936						navigator.msSaveBlob(blob, filename);
937					} 
938					else {
939						var link = document.createElement("a");
940						if (link.download !== undefined) { // feature detection
941							// Browsers that support HTML5 download attribute
942							var url = URL.createObjectURL(blob);
943							link.setAttribute("href", url);
944							link.setAttribute("download", filename);
945							link.style.visibility = 'hidden';
946							document.body.appendChild(link);
947							link.click();
948							document.body.removeChild(link);
949						}
950					}
951				});
952			});
953      
954		});
955	
956		canvas.
957			mousemove(e => t.ig.retanguloMouseMove(canvas, e)).
958			click(e => t.ig.retanguloClick(canvas, e));
959
960	}
961	
962	
963}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.