let MuestreoController = {
	defaultStyles: null,
	typeColors: null,
	fontSize: null,
	fontName: null,
	isPerf: null,
	colorsHex: [],
	poll: '',
	idPoll: '',
	question: '',
	questionOrder: '',
	questionFlag: false,
	columnName: '',
	title: '',
	answersChart: {},
	answersData: '',
	wordCloud: false,
	wordCloudURL: '',
	primaryColor: '',
	secundaryColor: '',
	wordCloudImg: '',
	genderChart: {},
	genderData: '',
	ageChart: {},
	ageData: '',
	statesChart: {},
	statesData: '',
	NSEChart: {},
	NSEData: '',
	data: '',
	dataFlag: false,
	alert: null,
	user: null,
	reports: null,
	typeQuest: '',
	loadIMG: '',
	timestamp: '',
	numPregPerf: '',
	graphFilter: {},
	perfGraph: false,
	answersLabelsData: '',
	genderLabelsData: '',
	ageLabelsData: '',
	stateLabelsData: '',
	NSELabelsData: '',
	excelDataOpt: 0,
	participantsNumber: 0,
	splitCharacter: '',
	generatingReports: [],
	idTenant: '',
	questionId: [],
	questionIdOut: [],
	quest_type: '',
	numberWordsWordcloud: 0,
	idMission: '',
	project: '',
	briefingObject: {},
	stampMision: '',
	qidTieneCaptureOCR: '0',
	plantillaReportes: null,
	dateFormat: '',
	questionsSQ: {},
	isContinuing: '0',
	startDate: '',
	endDate: '',
	suffix: '',

	reset() {
		let self = this;

		self.defaultStyles = null;
		self.typeColors = null;
		self.fontSize = null;
		self.fontName = null;
		self.isPerf = null;
		self.colorsHex = [];
		self.poll = '';
		self.idPoll = '';
		self.question = '';
		self.questionOrder = '';
		self.questionFlag = false;
		self.columnName = '';
		self.title = '';
		self.answersChart = {};
		self.answersData = '';
		self.wordCloud = false;
		self.wordCloudURL = '';
		self.primaryColor = '';
		self.secundaryColor = '';
		self.wordCloudImg = '';
		self.genderChart = {};
		self.genderData = '';
		self.ageChart = {};
		self.ageData = '';
		self.statesChart = {};
		self.statesData = '';
		self.NSEChart = {};
		self.NSEData = '';
		self.data = '';
		self.dataFlag = false;
		self.alert = null;
		self.user = '';
		self.reports = {
			word: false,
			ppt: false,
			excel: false,
			wc: false,
			images: false
		};
		self.typeQuest = '';
		self.loadIMG = '';
		self.timestamp = Date.now();
		self.numPregPerf = '';
		self.graphFilter = {};
		self.perfGraph = false;
		self.answersLabelsData = '';
		self.genderLabelsData = '';
		self.ageLabelsData = '';
		self.stateLabelsData = '';
		self.NSELabelsData = '';
		self.excelDataOpt = 0;
		self.participantsNumber = 0;
		self.splitCharacter = '';
		self.generatingReports = [];
		self.idTenant = sessionStorage['STCMBackEnd:idTenant'];
		self.questionId = [];
		self.questionIdOut = [];
		self.quest_type = '';
		self.numberWordsWordcloud = 0;
		self.idMission = '';
		self.project = '';
		self.briefingObject = {};
		self.stampMision = '';
		self.qidTieneCaptureOCR = '0';
		self.plantillaReportes = null;
		self.dateFormat = '';
		self.questionsSQ = {};
		self.isContinuing = '0';
		self.startDate = '';
		self.endDate = '';
		self.suffix = '';
	},

	setEvents(suffix = '') {
		let self = this;
		self.reset();
		self.suffix = suffix;

		// Información de administrador
		self.user = sessionStorage['STCMBackEnd:user'];
		let userA = JSON.parse(self.user);
		let user = userA.email;
		let user_split = user.split('@');
		self.user = user_split[0].replace('.', '_');
		self.dateFormat = userA.formatoFecha;

		// Reducción de Header
		headerSectionHeight(0);

		let jsonsubopt = {};
		let nav = '';
		if(self.suffix === '') {
			// Añadir titulo
			$('#page-title').text(pf.const.language.RSC35);

			// Opciones de header
			jsonsubopt = {
				survey: 'poll',
				question: 'question',
				report: 'ddreport',
				startEndDate: {
					class: 'form-group m-0 ml-1',
					style: 'max-width: 145px; line-height: initial;'
				},
				startEndTime: {
					class: 'form-group m-0 ml-1',
					style: 'min-width: 105px; line-height: initial;'
				},
			};

			nav = `
				<div class="d-flex justify-content-end align-items-end row m-0">
					${createSubOptionSurvey(jsonsubopt.survey)}
					${createSubOptionQuestion(jsonsubopt.question)}
					${createSubOptionStartEndDateTime(jsonsubopt.startEndDate.class, jsonsubopt.startEndTime.class, jsonsubopt.startEndDate.style, jsonsubopt.startEndTime.style)}
					${createSubOptionGetReport(jsonsubopt.report)}
				</div>
			`;
		} else if(self.suffix === '-me-sam') {
			// Opciones de header
			jsonsubopt = {
				question: 'question',
				report: 'ddreport',
				startEndDate: {
					class: 'form-group m-0 ml-1',
					style: 'max-width: 145px; line-height: initial;'
				},
				startEndTime: {
					class: 'form-group m-0 ml-1',
					style: 'min-width: 105px; line-height: initial;'
				},
			};

			nav = `
				<div class="d-flex justify-content-end align-items-end row m-0">
					${createSubOptionQuestion(jsonsubopt.question)}
					${createSubOptionStartEndDateTime(jsonsubopt.startEndDate.class, jsonsubopt.startEndTime.class, jsonsubopt.startEndDate.style, jsonsubopt.startEndTime.style, self.suffix)}
					${createSubOptionGetReport(jsonsubopt.report)}
				</div>
			`;
		}

		// Acciones de página (flex-row-reverse)
		$('#page-actions' + self.suffix).html(nav);

		// Botón principal
		$('#ddreport').addClass('main-button');

		// Secciones ocultas al cargar
		$('#mGraphs').hide();
		$('#resultTableM').hide();
		$('#NSEChart').hide();
		$('#startTime' + self.suffix).parent().hide();
		$('#endTime' + self.suffix).parent().hide();
		$('#poll').parent().parent().removeClass('col-2');
		$('#poll').parent().parent().removeClass('col-sm-3');
		$('#question').parent().parent().removeClass('col-2');
		$('#question').parent().parent().removeClass('col-sm-3');
		$('#startDate' + self.suffix).parent().hide();
		$('#endDate' + self.suffix).parent().hide();

		// Inputs de fecha y hora
		let now = new Date();
		let nYear = now.getFullYear();
		let nMonth = now.getMonth() + 1;
		if(nMonth < 10) {
			nMonth = '0' + nMonth;
		}
		let nDay = now.getDate();
		if(nDay < 10) {
			nDay = '0' + nDay;
		}
		let today = nYear + '-' + nMonth + '-' + nDay;
		self.startDate = today;
		self.endDate = today;

		$('#startDate' + self.suffix).val(self.startDate);
		$('#endDate' + self.suffix).val(self.endDate);

		// Valores de configuración
		let config = JSON.parse(atob(sessionStorage.getItem('STCMBackEnd:config')));
		self.wordCloudURL = config.URLWordCloud;
		self.primaryColor = config.tenant[0].colorPrimario.replace('#', '');
		self.secundaryColor = config.tenant[0].colorSecundario.replace('#', '');
		self.loadIMG = config.URLEncuestas;
		self.numPregPerf = config.numPregPerfEnMostreo;
		self.splitCharacter = config.splitCharacter;
		self.numberWordsWordcloud = config.numWordSentenceWordCloud;

		if(self.numPregPerf >= 4) {
			// Gráfica NSE
			$('#NSEChart').show();
		}

		// Plantilla por defecto
		ajaxComunCallWithCallback('getPlantillaReportesByDefault', {}, function(ajaxReturn) {
			if(ajaxReturn) {
				self.defaultStyles = ajaxReturn.result[0];

				self.typeColors = self.defaultStyles.rangoColores;

				if(self.typeColors == "1") {
					self.colorsHex[0] = self.defaultStyles.colorInicio;
					self.colorsHex[1] = self.defaultStyles.colorFinal;
				} else {
					self.colorsHex = self.defaultStyles.coloresComponenRango;
				}

				self.fontSize = 16;
				self.fontName = 'Arial';
			}
		});

		self.loadLang();
		self.applyEvents();

		addEventArrowTableHeader();
	},

	loadLang() {
		pf.rsc.translateByTag('text');
		$('#poll').attr('placeholder', pf.const.language.RSC177);

		// TITLES
		$('.exportTitle').attr('title', pf.const.language.RSC47);
		$('.acceptTitle').attr('title', pf.const.language.RSC141);
	},

	applyEvents() {
		let self = this;

		// En caso de venir de edición de misiones
		if(self.suffix === '-me-sam') {
			$('#searchQuestion').prop('disabled', false);
			$('#ddreport').prop('disabled', false);
		}

		// Encuestas
		$('#searchPoll').on('click', function() {
			// Objeto poll
			if(self.poll === '') {
				let JSONuser = sessionStorage['STCMBackEnd:user'];
				let user = JSON.parse(JSONuser);
				let idCliente = user.idCliente;

				// Parámetro de cliente
				let parameters = {
					idCliente: idCliente
				}
				ajaxComunCallWithCallback('getAllSurveysWithMissions', parameters, function(ajaxReturn) {
					if(ajaxReturn) {
						self.poll = ajaxReturn.result;

						self.renderPoll(self.poll);
					}
				});
			} else {
				$('#pollTable').modal('show', true);
			}
		});

		// Preguntas
		$('#searchQuestion').on('click', function() {
			// Objeto question
			if(self.question === '') {
				let parameters = {
					survey: self.idPoll
				};
				ajaxComunCallWithCallback('getQuestionsSurvey', parameters, function(ajaxReturn) {
					if(ajaxReturn) {
						self.question = ajaxReturn.result;

						self.renderQuests(self.question);
					}
				});
			} else {
				$('#questTable').modal('show', true);
			}
		});

		// Selección de reportes a generar
		$('#ddreport').click(function() {
			self.timestamp = Date.now();

			self.reports = {
				word: false,
				ppt: false,
				excel: false,
				wc: false,
				images: false
			};

			let content = `
				<p>${pf.const.language.RSC59}</p>

				<div class="row mt-3 mx-0 mb-0">
					<div class="col-6 mb-3 pl-0">
						<!-- Word -->
						<label for="cbword" class="form-check form-check-inline option-box-check w-100 h-100 c-pointer">
							<input id="cbword" type="checkbox" class="form-check-input reportCheck" name="cbword">

							<div class="ml-2">
								<span class="fw-500">${pf.const.language.RSC536}</span><br>
								<span class="fs-14">${pf.const.language.RSC537}</span>
							</div>
						</label>
					</div>

					<div class="col-6 mb-3 pr-0">
						<!-- Wordcloud -->
						<label for="cbwc" class="form-check form-check-inline option-box-check w-100 h-100 c-pointer">
							<input id="cbwc" type="checkbox" class="form-check-input reportCheck" name="cbwc">

							<div class="ml-2">
								<span class="fw-500">${pf.const.language.RSC542}</span><br>
								<span class="fs-14">${pf.const.language.RSC543}</span>
							</div>
						</label>
					</div>

					<div class="col-6 mb-3 pl-0">
						<!-- Powerpoint -->
						<label for="cbppt" class="form-check form-check-inline option-box-check w-100 h-100 c-pointer">
							<input id="cbppt" type="checkbox" class="form-check-input reportCheck" name="cbppt">

							<div class="ml-2">
								<span class="fw-500">${pf.const.language.RSC2512}</span><br>
								<span class="fs-14">${pf.const.language.RSC539}</span>
							</div>
						</label>
					</div>

					<div class="col-6 mb-3 pr-0">
						<!-- Multimedia -->
						<label for="cbimages" class="form-check form-check-inline option-box-check w-100 h-100 c-pointer">
							<input id="cbimages" type="checkbox" class="form-check-input reportCheck" name="cbimages">

							<div class="ml-2">
								<span class="fw-500">${pf.const.language.RSC544}</span><br>
								<span class="fs-14">${pf.const.language.RSC545}</span>
							</div>
						</label>
					</div>

					<div class="col-6 mb-0 pl-0">
						<!-- Data -->
						<label for="cbexcel" class="form-check form-check-inline option-box-check w-100 c-pointer">
							<input id="cbexcel" type="checkbox" class="form-check-input reportCheck" name="cbexcel">

							<div class="ml-2">
								<span class="fw-500">${pf.const.language.RSC540}</span><br>
								<span class="fs-14">${pf.const.language.RSC541}</span>

								<div id="dataOptions" class="d-none">
									<div class="form-check p-0">
										<input id="cbexcelAnswers" type="radio" class="form-check-input" name="excelDataOpt" value="1" checked>
										<label for="cbexcelAnswers" class="form-check-label">
											${pf.const.language.RSC150}
										</label>
									</div>
									<div class="form-check p-0">
										<input id="cbexcelCodePrefix" type="radio" class="form-check-input" name="excelDataOpt" value="2">
										<label for="cbexcelCodePrefix" class="form-check-label">
											${pf.const.language.RSC997}
										</label>
									</div>
									<div class="form-check p-0">
										<input id="cbexcelCode" type="radio" class="form-check-input" name="excelDataOpt" value="3">
										<label for="cbexcelCode" class="form-check-label">
											${pf.const.language.RSC998}
										</label>
									</div>
								</div>
							</div>
						</label>
					</div>

					<div class="col-6 mb-0 pr-0">
						<!-- Todos -->
						<label for="allReports" class="form-check form-check-inline option-box-check w-100 c-pointer">
							<input id="allReports" type="checkbox" class="form-check-input" name="allReports">

							<div class="ml-2">
								<span class="fw-500">${pf.const.language.RSC119}</span><br>
								<span class="fs-14">${pf.const.language.RSC2513}</span>
							</div>
						</label>
					</div>
				</div>

				<script>
					$('#cbexcel').on('change', function() {
						if($('#cbexcel').prop('checked') == true) {
							$('#dataOptions').removeClass('d-none');
						} else {
							$('#dataOptions').addClass('d-none');
						}
					});
					$('#allReports').on('change', function() {
						if($('#allReports').prop('checked') == true) {
							$('#allReports').parent().addClass('option-box-check-selected');
							$('.reportCheck').prop('checked', true);
							$('.reportCheck').parent().addClass('option-box-check-selected');
							$('#dataOptions').removeClass('d-none');
						} else {
							$('#allReports').parent().removeClass('option-box-check-selected');
							$('.reportCheck').prop('checked', false);
							$('.reportCheck').parent().removeClass('option-box-check-selected');
							$('#dataOptions').addClass('d-none');
						}
					});
					$('.reportCheck').on('click', function() {
						if($(this).prop('checked') == false) {
							$('#allReports').prop('checked', false);
							$('#allReports').parent().removeClass('option-box-check-selected');
							$(this).parent().removeClass('option-box-check-selected');
						} else {
							$(this).parent().addClass('option-box-check-selected');
						}
					});
				</script>
			`;

			let objInfo = {
				accept: {
					text: pf.const.language.RSC60
				},
				cancel: {
					text: pf.const.language.RSC57
				}
			};

			let alertTitle = pf.const.language.RSC48;
			self.alert = pf.utils.showInfoDialogCustomWidthAcceptCancelNewStyle(alertTitle, content, objInfo, '750px', function() {
				self.reports.word = $('#cbword').prop('checked') ? true : false;
				self.reports.ppt = $('#cbppt').prop('checked') ? true : false;
				self.reports.excel = $('#cbexcel').prop('checked') ? true : false;
				self.reports.wc = $('#cbwc').prop('checked') ? true : false;
				self.reports.images = $('#cbimages').prop('checked') ? true : false;

				let noReports = true;
				for(let report in self.reports) {
					if(self.reports[report]) {
						noReports = false;
					}
				}
				if(noReports) {
					let warningTitle = pf.const.language.RSC1941;
					let warningContent = pf.const.language.RSC2391;
					pf.utils.showInfoDialog(warningTitle, warningContent);
					return false;
				}

				let excelDataOpt = $('input:radio[name=excelDataOpt]:checked').val();
				if(excelDataOpt != undefined) {
					self.excelDataOpt = excelDataOpt;
				} else {
					self.excelDataOpt = 0;
				}

				// En el caso de powerpoint recoger los valores de briefing del proyecto
				if(self.reports.ppt || self.reports.word) {
					let projectData = false;
					let missionData = false;

					addLoader();

					// Parámetros para datos de misión
					parameters = {
						stampMision: self.stampMision
					};
					ajaxComunCallWithCallback('getMision', parameters, function(ajaxReturn) {
						if(ajaxReturn) {
							let idPlantillaReportes = ajaxReturn.result[0].idPlantillaReportes;

							if(idPlantillaReportes != '0') {
								// Parámetros para datos de plantilla
								parameters = {
									id: idPlantillaReportes
								};
								ajaxComunCallWithCallback('getPlantillaReportesByID', parameters, function(ajaxReturn) {
									if(ajaxReturn) {
										let values = ajaxReturn.result[0];

										self.plantillaReportes = {
											rangoColores: values.rangoColores,
											colorInicio: values.colorInicio,
											colorFinal: values.colorFinal,
											coloresComponenRango: values.coloresComponenRango,
											tipoFuente: values.tipoFuente,
											tamanoFuente: values.tamanoFuente,
											colorTituloPortada: values.colorTituloPortada,
											colorTitulo: values.colorTitulo,
											plantillaPortada: values.plantillaPortada,
											plantilla: values.plantilla,
											logo: values.logo,
											answersOrder: values.answersOrder,
											// Valores de tipo de gráfica
											type3: values.type3,
											type4: values.type4,
											type5: values.type5,
											typeINTERROGANTE: values['type!'],
											typeL: values.typeL,
											typeO: values.typeO,
											typeY: values.typeY,
											typeM: values.typeM
										};

										if(self.plantillaReportes) {
											missionData = true;
											if(projectData && missionData) {
												removeLoader();
												self.executeNewReports();
											}
										}
									}
								});
							} else {
								// Plantilla por defecto
								self.plantillaReportes = {
									rangoColores: self.defaultStyles.rangoColores,
									colorInicio: self.defaultStyles.colorInicio,
									colorFinal: self.defaultStyles.colorFinal,
									coloresComponenRango: self.defaultStyles.coloresComponenRango,
									tipoFuente: self.defaultStyles.tipoFuente,
									tamanoFuente: self.defaultStyles.tamanoFuente,
									colorTituloPortada: self.defaultStyles.colorTituloPortada,
									colorTitulo: self.defaultStyles.colorTitulo,
									plantillaPortada: self.defaultStyles.plantillaPortada,
									plantilla: self.defaultStyles.plantilla,
									logo: self.defaultStyles.logo,
									answersOrder: self.defaultStyles.answersOrder,
									// Valores de tipo de gráfica
									type3: self.defaultStyles.type3,
									type4: self.defaultStyles.type4,
									type5: self.defaultStyles.type5,
									typeINTERROGANTE: self.defaultStyles['type!'],
									typeL: self.defaultStyles.typeL,
									typeO: self.defaultStyles.typeO,
									typeY: self.defaultStyles.typeY,
									typeM: self.defaultStyles.typeM
								};

								if(self.plantillaReportes) {
									missionData = true;
									if(projectData && missionData) {
										removeLoader();
										self.executeNewReports();
									}
								}
							}
						}
					}, false);

					// Parámetros para datos de proyecto
					parameters = {
						id: self.project
					};
					ajaxComunCallWithCallback('getCMBPProjects', parameters, function(ajaxReturn) {
						if(ajaxReturn) {
							let project = ajaxReturn.result[0];

							// Valores y títulos de briefing
							let briefingObject = {
								actionStandard: {
									title: pf.const.language.RSC2059,
									text: project.briefing[0].actionStandard
								},
								applicantName: {
									title: pf.const.language.RSC2053,
									text: project.briefing[0].applicantName
								},
								background: {
									title: pf.const.language.RSC2056,
									text: project.briefing[0].background
								},
								brandsInvolved: {
									title: pf.const.language.RSC2054,
									text: project.briefing[0].brandsInvolved
								},
								businessObjective: {
									title: pf.const.language.RSC2057,
									text: project.briefing[0].businessObjective
								},
								favorableResults: {
									title: pf.const.language.RSC2060,
									text: project.briefing[0].favorableResults
								},
								investigationObjective: {
									title: pf.const.language.RSC2058,
									text: project.briefing[0].investigationObjective
								},
								notFavorableResults: {
									title: pf.const.language.RSC2061,
									text: project.briefing[0].notFavorableResults
								},
								projectDescription: {
									title: pf.const.language.RSC2055,
									text: project.briefing[0].projectDescription
								}
							}

							self.briefingObject = briefingObject;

							projectData = true;
							if(projectData && missionData) {
								removeLoader();
								self.executeNewReports();
							}
						}
					}, false);
				} else {
					self.executeNewReports();
				}
			}, function() {});
		});

		// Fecha de inicio
		$('#startDate' + self.suffix).on('change', function() {
			self.startDate = $('#startDate' + self.suffix).val();
			if(self.startDate > self.endDate) {
				$('#startDate' + self.suffix).val(self.endDate);
				self.startDate = $('#startDate' + self.suffix).val();
			}
		});

		// Fecha de fin
		$('#endDate' + self.suffix).on('change', function() {
			self.endDate = $('#endDate' + self.suffix).val();
			if(self.endDate < self.startDate) {
				$('#endDate' + self.suffix).val(self.startDate);
				self.endDate = $('#endDate' + self.suffix).val();
			}
		});
	},

	renderPoll(poll) {
		let self = this;

		let table = `
			<thead>
				<tr>
					<th scope="col" title="${pf.const.language.RSC177}">${pf.const.language.RSC177}</th>
					<th scope="col" title="${pf.const.language.RSC176}">${pf.const.language.RSC176}</th>
					<th scope="col" title="${pf.const.language.RSC114}">${pf.const.language.RSC114}</th>
					<th scope="col" title="${pf.const.language.RSC116}">${pf.const.language.RSC116}</th>
					<th scope="col" title="${pf.const.language.RSC117}">${pf.const.language.RSC117}</th>
					<th scope="col" title="${pf.const.language.RSC549}">${pf.const.language.RSC549}</th>
				</tr>
			</thead>

			<thead class="filtersPoll">
				<tr>
					<td>mision</td>
					<td>proyecto</td>
					<td>active</td>
					<td>startdate</td>
					<td>expires</td>
					<td>country</td>
				</tr>
			</thead>

			<tbody>
		`;

		// Obtener países permitidos
		let allowedCountries = JSON.parse(atob(sessionStorage['STCMBackEnd:userCountries']));

		let size = poll.length;
		for(let i = 0; i < size; i++) {
			// Control de países permitidos
			if(poll[i].countries != '' && allowedCountries.indexOf(poll[i].countries) == -1) {
				continue;
			}

			if(poll[i].idmision == '') {
				continue;
			}

			// Formato de fecha, el servicio devuelve AAAA-MM-DD HH:MM:SS
			let startDate = '-';
			let startDateOrder = '';
			if(poll[i].startdate != '') {
				// Para ordenación en columna
				startDateOrder = poll[i].startdate.replace(' ', '');

				let dateTimeArrayStart = poll[i].startdate.split(' ');
				let dateStart = dateTimeArrayStart[0].replace(/-/g, '/');
				if(self.dateFormat === 'DDMMAAAA') {
					startDate = modifyDateFormat(dateStart);
				} else {
					startDate = dateStart;
				}
			}

			let endDate = '-';
			let endDateOrder = '';
			if(poll[i].expires != '') {
				// Para ordenación en columna
				endDateOrder = poll[i].expires.replace(' ', '');

				let dateTimeArrayEnd = poll[i].expires.split(' ');
				let dateEnd = dateTimeArrayEnd[0].replace(/-/g, '/');
				if(self.dateFormat === 'DDMMAAAA') {
					endDate = modifyDateFormat(dateEnd);
				} else {
					endDate = dateEnd;
				}
			}

			table += `
				<tr id="sid${poll[i].sid}" class="c-pointer" data-perf="${poll[i].perfilacion}" data-mission="${poll[i].idmision}" data-stamp="${poll[i].stampMision}" data-project="${poll[i].idProject}" data-surveyname="${poll[i].surveyls_title}" data-continuing="${poll[i].continuingMission}">
					<td class="text-truncate" title="${poll[i].idmision}">${poll[i].idmision}</td>
					<td class="text-truncate" title="${poll[i].NombreProyecto}">${poll[i].NombreProyecto}</td>
					<td class="text-center">
						<span class="d-none">${(poll[i].active == '1' ? pf.const.language.RSC120 : pf.const.language.RSC121)}</span>
						<input type="checkbox" disabled ${(poll[i].active == '1' ? 'checked' : '')}>
					</td>
					<td class="text-truncate" title="${startDate}">
						<span class="d-none">${startDateOrder}</span>
						${startDate}
					</td>
					<td class="text-truncate" title="${endDate}">
						<span class="d-none">${endDateOrder}</span>
						${endDate}
					</td>
					<td class="country text-truncate" title="${poll[i].countries}">${poll[i].countries}</td>
				</tr>
			`;
		}

		table += `
			</tbody>
		`;

		$('#tablePoll').html(table);

		// Setup - add a text input to each footer cell
		$('#tablePoll .filtersPoll td').each(function() {
			let title = $(this).text();
			let value = `<input class="form-control form-control-sm" type="text">`;

			if(title == 'active') {
				value = optionsSelectAllYesNo();
			}

			$(this).html(value);
		});

		let tablePoll = $('#tablePoll').DataTable({
			language: pf.const.language_table,
			scrollY: 300,
			scroller: false,
			paging: true,
			pageLength: 25,
			columnDefs: [
				{width: '60px', targets: 2}
			],
			autoWidth: false,
			aaSorting: []
		});

		// Prueba de reparación para Beb
		setTimeout(function() {
			tablePoll.columns.adjust();
		}, 200);

		// Ocultar botones de tabla
		hideTableButtons('tablePoll');

		// Apply the search
		applyTheSearch(tablePoll, 'filtersPoll');

		self.pollEvents();

		$('#tablePoll').on('draw.dt', function() {
			self.pollEvents();
		});
	},

	pollEvents() {
		let self = this;

		$('#tablePoll tbody').off().on('click', 'tr', function() {
			$('#searchQuestion').prop('disabled', false);
			$('#ddreport').prop('disabled', false);

			//Limpieza de question
			self.question = '';
			self.questionOrder = '';
			self.columnName = '';
			self.title = '';
			$('#question').val(pf.const.language.RSC111);

			// Misión continua
			if($(this).data('continuing') == '1') {
				self.isContinuing = '1';
				$('#startDate' + self.suffix).parent().show();
				$('#endDate' + self.suffix).parent().show();
			} else {
				self.isContinuing = '0';
				$('#startDate' + self.suffix).parent().hide();
				$('#endDate' + self.suffix).parent().hide();
			}

			self.idPoll = $(this).prop('id').replace('sid', '');
			self.isPerf = $(this).data('perf');
			self.idMission = $(this).data('mission');
			self.stampMision = $(this).data('stamp');
			self.project = $(this).data('project');
			$('#poll').val(self.idMission);

			$('#closePool').trigger('click');
		});
	},

	renderQuests(quests) {
		let self = this;

		if(self.questionFlag) {
			$('#tableQuest').dataTable().fnDestroy();
		} else {
			self.questionFlag = true;
		}

		let table = `
			<thead>
				<tr>
					<th scope="col" title="${pf.const.language.RSC1941}">
						<input type="checkbox" class="globalSelection" checked>
						${pf.const.language.RSC1941}
					</th>
					<th scope="col" title="${pf.const.language.RSC366}">${pf.const.language.RSC366}</th>
					<th scope="col" title="${pf.const.language.RSC122}">${pf.const.language.RSC122}</th>
					<th scope="col" title="${pf.const.language.RSC111}">${pf.const.language.RSC111}</th>
				</tr>
			</thead>

			<thead class="filtersQuest">
				<tr>
					<td>reports</td>
					<td>columnName</td>
					<td>section</td>
					<td>question</td>
				</tr>
			</thead>

			<tbody>
		`;

		// IDs de preguntas
		self.questionId = [];

		let size = quests.length;
		for(let i = 0; i < size; i++) {
			let question = quests[i].question.replace('/...', '');

			// Limpieza de marcas de html
			let textWithTags = quests[i].question;
			let tagsWithoutTags = textWithTags.replace(/<[^>]*>?/g, '');
			if(quests[i].type == '6' || quests[i].type == 'C' || quests[i].type == 'E' || quests[i].type == 'H' || quests[i].type == 'K' || quests[i].type == ';' || quests[i].type == ':') {
				let sizeK = quests[i].valuesSQ.length;
				for(let j = 0; j < sizeK; j++) {
					let valuesSQArray = quests[i].valuesSQ[j].split('|');
					let columnNameK = valuesSQArray[0];
					let questionK = tagsWithoutTags.trim() + '<br>' + valuesSQArray[1].replace(';', '');
					table += `
						<tr class="c-pointer" data-order="j${(i + 1)}" data-type="normal" data-quest_type="${quests[i].type}">
							<td class="text-center">
								<input type="checkbox" class="selectionReport" data-quest="${columnNameK}" checked>
							</td>
							<td id="${quests[i].title}" class="columnName selectQ">${columnNameK}</td>
							<td class="selectQ">${quests[i].group_name}</td>
							<td class="question selectQ">${questionK}</td>
						</tr>
					`;

					self.questionId.push(columnNameK);
				}
			} else {
				table += `
					<tr class="c-pointer" data-order="${(i + 1)}" data-type="normal" data-quest_type="${quests[i].type}">
						<td class="text-center">
							<input type="checkbox" class="selectionReport" data-quest="${quests[i].columnName}" checked>
						</td>
						<td id="${quests[i].title}" class="columnName selectQ">${quests[i].columnName}</td>
						<td class="selectQ">${quests[i].group_name}</td>
						<td class="question selectQ">${question}</td>
					</tr>
				`;
				self.questionId.push(quests[i].columnName);
			}
		}

		table += `
			</tbody>
		`;

		$('#tableQuest').html(table);

		// Setup - add a text input to each footer cell
		$('#tableQuest .filtersQuest td').each(function() {
			let title = $(this).text();
			let value = `<input class="form-control form-control-sm" type="text">`;

			if(title == 'reports') {
				value = `<input class="form-control form-control-sm" type="text" disabled>`;
			}

			$(this).html(value);
		});

		let tableQuest = $('#tableQuest').DataTable({
			language: pf.const.language_table,
			scrollY: 300,
			scroller: false,
			paging: true,
			pageLength: 25,
			columnDefs: [
				{width: '75px', orderable: false, targets: 0},
				{width: '45px', targets: 1}
			],
			autoWidth: false,
			aaSorting: []
		});

		// Prueba de reparación para Beb
		setTimeout(function() {
			tableQuest.columns.adjust();
		}, 200);

		// Ocultar botones de tabla
		hideTableButtons('tableQuest');

		// Apply the search
		applyTheSearch(tableQuest, 'filtersQuest');

		self.questsEvents();

		$('#tableQuest').on('draw.dt', function() {
			self.questsEvents();
		});

		$('#accept').off().on('click', function() {
			$('#closeQuest').trigger('click');
		});

		$('.globalSelection').off().on('change', function() {
			if($('.globalSelection').prop('checked')) {
				self.questionIdOut = [];

				$('.selectionReport').prop('checked', true);
			} else {
				self.questionIdOut = [];

				let size = self.questionId.length;
				for(let i = 0; i < size; i++) {
					self.questionIdOut.push(self.questionId[i]);
				}

				$('.selectionReport').prop('checked', false);
			}
		});

		$('.selectionReport').off().on('click', function() {
			let quest = $(this).data('quest');
			if($(this).prop('checked')) {
				let index = self.questionIdOut.indexOf(quest);
				self.questionIdOut.splice(index, 1);
			} else {
				self.questionIdOut.push(quest);
			}
		});
	},

	questsEvents() {
		let self = this;

		$('.selectQ').off().on('click', function() {
			self.columnName = $(this).parent().find('.columnName').text();
			let question = $(this).parent().find('.question').text();
			let questionObj = $(this).parent();
			self.quest_type = $(this).parent().data('quest_type');
			self.questionOrder = questionObj[0].dataset.order;

			self.title = $(this).parent().find('.columnName').attr('id');
			$('#question').val(question);
			$('#resp').text(question + ' (%)');

			$('#closeQuest').trigger('click');

			// Cargar tabla
			self.questionsSQ = {};
			let size = self.question.length;
			for(let i = 0; i < size; i++) {
				if(self.question[i].columnName == self.columnName && (self.question[i].type == 'A' || self.question[i].type == 'B' || self.question[i].type == 'F')) {
					let sizeK = self.question[i].valuesSQ.length;
					for(let j = 0; j < sizeK; j++) {
						let valuesSQArray = self.question[i].valuesSQ[j].split('|');

						self.questionsSQ[valuesSQArray[0]] = {
							name: valuesSQArray[1],
							data: []
						};
					}

					break;
				}
			}

			self.requestGraphs();
		});
	},

	requestGraphs() {
		let self = this;

		let preguntaSQ = '';

		let parameters = {
			survey: self.idPoll,
			question: self.columnName,
			param4: self.numPregPerf,
			title: self.title,
			isPerf: self.isPerf,
			preguntaSQ: preguntaSQ,
			continuingMission: self.isContinuing,
			startDate: self.startDate,
			endDate: self.endDate
		};
		ajaxComunCallWithCallback('getAnalyticsMuestra', parameters, function(ajaxReturn) {
			if(ajaxReturn) {
				// Número de participantes
				let participants = [];
				let pSize = 0;

				if(ajaxReturn.result.resultado.data != undefined) {
					pSize = ajaxReturn.result.resultado.data.length;
				}

				for(let i = 0; i < pSize; i++) {
					if(participants.indexOf(ajaxReturn.result.resultado.data[i].user) == -1) {
						participants.push(ajaxReturn.result.resultado.data[i].user);
					}
				}
				self.participantsNumber = participants.length;

				// Si no hay resultados en la encuesta/pregunta
				if(ajaxReturn.result.resultado.length == 0) {
					removeLoader();
					let errorTitle = pf.const.language.RSC35;
					let errorContent = pf.const.language.RSC529;
					pf.utils.showInfoDialog(errorTitle, errorContent);
					return;
				}

				// Labels y datos de las respuestas
				let answers = ajaxReturn.result.resultado.answers;
				self.answersLabelsData = answers;
				self.data = ajaxReturn.result.resultado.data;
				self.typeQuest = ajaxReturn.result.resultado.type;

				// Para gráficas Stacked
				let SQSize = Object.keys(self.questionsSQ).length;
				if(SQSize > 0) {
					let dSize = self.data.length;
					for(let i = 0; i < dSize; i++) {
						self.questionsSQ[self.data[i].question].data.push(self.data[i]);
					}

					// Rango de colores
					let gradient = [];
					if(SQSize == 2) {
						gradient = self.colorsHex;
					} else {
						if(self.typeColors == 1) {
							gradient = generateColors(self.colorsHex[0], self.colorsHex[1], SQSize);
						} else {
							gradient = arrayColors(self.colorsHex, SQSize);
						}
					}

					let labelsData = [];
					let lSize = self.answersLabelsData.labels.length;
					for(let j = 0; j < lSize; j++) {
						labelsData.push(0);
					}

					let datasetArray = [];
					let count = 0;
					for(let questionsSQ in self.questionsSQ) {
						let labelsDataSQ = [...labelsData];
						let dSizeSQ = self.questionsSQ[questionsSQ].data.length;
						for(let n = 0; n < dSizeSQ; n++) {
							//fix for trim chars into array labels
							// let index = self.answersLabelsData.labels.indexOf(self.questionsSQ[questionsSQ].data[n].answer);
							for (let ind = 0; ind < self.answersLabelsData.labels.length; ind++) {
								if (self.answersLabelsData.labels[ind].trim() == self.questionsSQ[questionsSQ].data[n].answer.trim()) {
									labelsDataSQ[ind]++;
									break;
								};
							}
						}

						for(let m = 0; m < lSize; m++) {
							labelsDataSQ[m] = (labelsDataSQ[m] * 100 / self.participantsNumber).toFixed(1);
						}

						let obj = {
							label: self.questionsSQ[questionsSQ].name,
							data: labelsDataSQ,
							backgroundColor: gradient[count]
						};

						datasetArray.push(obj);
						count++;
					}

					self.answersLabelsData.datasets = datasetArray;
					answers = self.answersLabelsData;
				} else if(self.typeQuest == 'R') {
					let labels = ajaxReturn.result.resultado.answers.labels;

					let labelsObj = [];
					let labelsLabels = [];
					for(let l = 0; l < labels.length; l++) {
						let labelsOptions = [];
						for(let l in labels) {
							labelsOptions.push(0);
						}

						let obj = {
							labelName: labels[l],
							ranking: labelsOptions
						};
						labelsObj.push(obj);
						labelsLabels.push(l + 1);
					}

					let labelsObjIndex = 0;
					let rankingControl = self.participantsNumber;
					let dSize = self.data.length;
					for(let i = 0; i < dSize; i++) {
						if(i == rankingControl) {
							rankingControl += self.participantsNumber;
							labelsObjIndex++;
						}

						let index = labels.indexOf(self.data[i].answer);
						labelsObj[labelsObjIndex].ranking[index]++;
					}

					// Rango de colores
					let gradient = [];
					if(labels.length == 2) {
						gradient = self.colorsHex;
					} else {
						if(self.typeColors == 1) {
							gradient = generateColors(self.colorsHex[0], self.colorsHex[1], labels.length);
						} else {
							gradient = arrayColors(self.colorsHex, labels.length);
						}
					}

					let datasetArray = [];
					let count = 0;
					for(let label in labelsObj) {
						for(let m = 0; m < labels.length; m++) {
							labelsObj[label].ranking[m] = (labelsObj[label].ranking[m] * 100 / self.participantsNumber).toFixed(1);
						}

						let obj = {
							label: labelsObj[label].labelName,
							data: labelsObj[label].ranking,
							backgroundColor: gradient[count]
						};

						datasetArray.push(obj);
						count++;
					}

					self.answersLabelsData.datasets = datasetArray;
					answers = self.answersLabelsData;
					self.answersLabelsData.labels = labelsLabels;
				}
				// Fin gráficas Stacked

				if(ajaxReturn.perf) {
					self.perfGraph = true;

					// Visibilidad de elementos
					$('#respWordCloud').hide();
					$('#respCarousel').hide();
					$('#ageChart').hide();
					$('#statesChart').hide();
					$('#genderChart').hide();
					$('#NSEChart').hide();
					$('#mGraphs').show();
					$('#respChart').show();
					self.wordCloud = false;

					// Gráfica de respuestas
					self.createGraphs(answers, 0);
				} else {
					$('#mGraphs').show();

					if(self.typeQuest == '|' || self.typeQuest == '7' || self.typeQuest == 'J') {
						$('#respChart').hide();

						if(self.data[0].qidTieneCaptureOCR != '0' && (self.data[0].tipoPregunta == '|' || self.data[0].tipoPregunta == '7' || self.data[0].tipoPregunta == 'J')) {
							$('#respWordCloud').show();
							self.qidTieneCaptureOCR = self.data[0].qidTieneCaptureOCR;
							self.wordCloud = true;
							if(!$.isEmptyObject(self.answersChart)) {
								self.answersChart.destroy();
								self.answersData = '';
							}
							let answerType = $('#resp').text();
							answerType = answerType.replace(' (%)', ' (WordCloud)');
							$('#titleWordCloud').text(answerType);
							self.printWordCloud();
						} else {
							$('#respWordCloud').hide();
						}

						// Visibilidad de elementos
						$('#respCarousel').show();
						$('#ageChart').show();
						$('#statesChart').show();
						$('#genderChart').show();

						self.carousel();
					} else if(self.typeQuest == 'P' || self.typeQuest == 'O') {
						// WordCloud
						$('#respWordCloud').show();
						$('#respCarousel').hide();
						$('#ageChart').show();
						$('#statesChart').show();
						$('#genderChart').show();
						self.wordCloud = true;
						if(!$.isEmptyObject(self.answersChart)) {
							self.answersChart.destroy();
							self.answersData = '';
						}
						let answerType = $('#resp').text();
						answerType = answerType.replace(' (%)', ' (WordCloud)');
						$('#titleWordCloud').text(answerType);
						self.printWordCloud();

						// Gráfica
						$('#respChart').show();
						self.wordCloud = true;
						self.createGraphs(answers, 0);
					} else if(answers.labels[0] === 'Others' && answers.labels.length === 1 && self.typeQuest !== ':') {
						// WordCloud
						$('#respChart').hide();
						$('#respWordCloud').show();
						$('#respCarousel').hide();
						$('#ageChart').show();
						$('#statesChart').show();
						$('#genderChart').show();
						self.wordCloud = true;
						if(!$.isEmptyObject(self.answersChart)) {
							self.answersChart.destroy();
							self.answersData = '';
						}
						let answerType = $('#resp').text();
						answerType = answerType.replace(' (%)', ' (WordCloud)');
						$('#titleWordCloud').text(answerType);
						self.printWordCloud();
					} else {
						// Gráfica
						$('#respChart').show();
						$('#respWordCloud').hide();
						$('#respCarousel').hide();
						$('#ageChart').show();
						$('#statesChart').show();
						$('#genderChart').show();
						self.wordCloud = false;

						// Gráfica de respuestas
						self.createGraphs(answers, 0);
					}

					// Gráfica de género
					let gender = ajaxReturn.result.resultado.gender;
					self.genderLabelsData = gender;
					self.createGraphs(gender, 1);

					// Gráfica de edad
					let age = ajaxReturn.result.resultado.ageRange;
					self.ageLabelsData = age;
					self.createGraphs(age, 2);

					// Gráfica de estados
					let states = ajaxReturn.result.resultado.states;
					self.stateLabelsData = states;
					self.createGraphs(states, 3);

					// Gráfica de NSE
					let nse = ajaxReturn.result.resultado.nse;
					self.NSELabelsData = nse;
					self.createGraphs(nse, 4);
				}

				// Eventos de gráficas
				self.graphsEvents();

				// Tabla de resultados
				self.renderData();
			}
		});
	},

	// GRÁFICAS
	createGraphs(data, n) {
		let self = this;

		let ctx;
		let quantity = data.labels.length;
		let gradient = [];
		if(quantity == 2) {
			gradient = self.colorsHex;
		} else {
			if(self.typeColors == 1) {
				gradient = generateColors(self.colorsHex[0], self.colorsHex[1], quantity);
			} else {
				gradient = arrayColors(self.colorsHex, quantity);
			}
		}

		data = self.answersOrderDataTemplate(data, self.typeQuest);

		let options = '';
		if(typeof data.options == 'object') {
			options = data.options;
		} else {
			options = JSON.parse(data.options);
		}

		options.title.display = true;
		options.title.text = pf.const.language.RSC443 + ': ' + self.participantsNumber;
		options.title.padding = 30;

		if((Object.keys(self.questionsSQ).length > 0 || self.typeQuest == 'R') && n == 0) {
			options.legend.display = true;
			options.scales.xAxes[0]['stacked'] = true;
			options.scales.yAxes[0]['stacked'] = true;
		}

		switch(n) {
			case 0:
				self.answersData = data;
				if(!$.isEmptyObject(self.answersChart)) {
					self.answersChart.destroy();
				}

				if(Object.keys(self.questionsSQ).length == 0 && self.typeQuest != 'R') {
					data.datasets.backgroundColor = gradient;
					if(data.labels[data.labels.length - 1] == '-oth-') {
						data.labels[data.labels.length - 1] = pf.const.language.RSC128;
					}
				}

				ctx = document.getElementById('graphAnswers').getContext('2d');
				break;
			case 1:
				self.genderData = data;
				if(!$.isEmptyObject(self.genderChart)) {
					self.genderChart.destroy();
				}
				data.datasets.backgroundColor = self.colorsHex;
				ctx = document.getElementById('graphGender').getContext('2d');
				break;
			case 2:
				self.ageData = data;
				if(!$.isEmptyObject(self.ageChart)) {
					self.ageChart.destroy();
				}
				data.datasets.backgroundColor = gradient;
				ctx = document.getElementById('graphAge').getContext('2d');
				break;
			case 3:
				self.statesData = data;
				if(!$.isEmptyObject(self.statesChart)) {
					self.statesChart.destroy();
				}
				data.datasets.backgroundColor = gradient;
				ctx = document.getElementById('graphStates').getContext('2d');
				break;
			case 4:
				self.NSEData = data;
				if(!$.isEmptyObject(self.NSEChart)) {
					self.NSEChart.destroy();
				}
				data.datasets.backgroundColor = gradient;
				ctx = document.getElementById('graphNSE').getContext('2d');
				break;
		}

		options['tooltips'] = {
			enabled: false
		};

		if(n == 1) {
			options['plugins'] = {
				datalabels: {
					color: 'black',
					font: {
						weight: 'bold',
						size: self.fontSize
					},
					clamp: true,
					formatter(value, context) {
						return value;
					}
				}
			};
		} else {
			// Control de tamaño máximo de columna
			options.scales.xAxes[0]['maxBarThickness'] = 150;

			if((Object.keys(self.questionsSQ).length > 0 || self.typeQuest == 'R') && n == 0) {
				options['plugins'] = {
					datalabels: {
						color: 'black',
						font: {
							weight: 'bold',
							size: self.fontSize
						},
						formatter(value, context) {
							return value;
						}
					}
				};
			} else {
				// Radio de ángulos
				options.cornerRadius = 6;

				options['plugins'] = {
					datalabels: {
						color: 'black',
						font: {
							weight: 'bold',
							size: self.fontSize
						},
						anchor: 'end',
						align: 'end',
						formatter(value, context) {
							return value;
						}
					}
				};
			}
		}

		if(n !== 1) {
			// Ancho de columnas
			options.scales.xAxes[0]['barPercentage'] = 0.5;

			// Ticks X en horizontal con salto de linea
			// Ancho del contenedor de la gráfica
			let divParentWidth = $('#graphAnswers').parent().css('width');
			// Número de columnas de la gráfica
			let nColumns = quantity;
			// Ancho del contenedor entre el número de columnas
			let maxwidth = Math.floor(parseInt(divParentWidth) / nColumns);
			// Ancho de la columna entre el tamaño de la fuente
			let maxwidthFont = Math.ceil(maxwidth / self.fontSize) + 2;

			// Etiquetas del eje X
			let xLabels = data.labels;
			// Comprobación de la primera palabra de los labels para ejecutar formato horizontal o diagonal
			let controlH = true;
			let xSize = xLabels.length;
			// Utilización de caracter de corte si lo hay
			if(self.splitCharacter != '') {
				for(let i = 0; i < xSize; i++) {
					if(xLabels[i] == null || xLabels[i] == undefined) {
						continue;
					}

					let indexCut = xLabels[i].toString().indexOf(self.splitCharacter);
					if(indexCut != -1) {
						xLabels[i] = xLabels[i].toString().slice(0, indexCut);
					}
				}
			}

			for(let i = 0; i < xSize; i++) {
				if(xLabels[i] == null || xLabels[i] == undefined) {
					continue;
				}

				let words = xLabels[i].toString().split(' ');
				let wSize = words.length;
				for(let j = 0; j < wSize; j++) {
					if(words[j].length > maxwidthFont) {
						controlH = false;
						break;
					}
				}
				if(!controlH) {
					break;
				}
			}

			if(controlH) {
				options.scales.xAxes[0].ticks['minRotation'] = 0;
				options.scales.xAxes[0].ticks['maxRotation'] = 0;

				options.scales.xAxes[0].ticks['callback'] = function(value, index, values) {
					let formmatedvalue = formatLabel(value, maxwidthFont);
					return formmatedvalue;
				}
			} else {
				options.scales.xAxes[0].ticks['callback'] = function(value, index, values) {
					if(value == null || value == undefined) {
						return value;
					} else if(value.length < 18) {
						return value;
					} else {
						return value.substr(0, 14) + '...';
					}
				};
			}
		}

		Chart.defaults.global.defaultFontSize = parseInt(self.fontSize);
		Chart.defaults.global.defaultFontFamily = self.fontName;

		let graphElement = {
			// The type of chart we want to create
			type: data.type,
			// The data for our dataset
			data: {
				datasets: (Object.keys(self.questionsSQ).length > 0 || self.typeQuest == 'R') && n == 0 ? data.datasets : [data.datasets],
				labels: data.labels
			},
			// Configuration options go here
			options: options
		};

		let graph;
		if(n != 5) {
			graph = new Chart(ctx, graphElement);
		}

		switch(n) {
			case 0:
				self.answersChart = graph;
				break;
			case 1:
				self.genderChart = graph;
				break;
			case 2:
				self.ageChart = graph;
				break;
			case 3:
				self.statesChart = graph;
				break;
			case 4:
				self.NSEChart = graph;
				break;
		}
	},

	// WORDCLOUD
	printWordCloud() {
		let self = this;

		// Los valores de survey y answer los recogerá de los atributos
		let survey = self.idPoll;
		let answer = self.columnName;
		let url = self.wordCloudURL;

		// Palabras (1) o frases (2)
		let wordsOrPhrases = 2;

		if(self.quest_type == 'S' || self.quest_type == 'Q') {
			wordsOrPhrases = 1;
		}

		let qidTieneCaptureOCR = '';
		let idProject = '';
		if(self.qidTieneCaptureOCR != '0' && (self.quest_type == '|' || self.quest_type == '7' || self.quest_type == 'J')) {
			wordsOrPhrases = 1;
			qidTieneCaptureOCR = self.qidTieneCaptureOCR;
			idProject = self.project;
		}

		/*
			a - survey *
			b - pregunta *
			c - proyecto *
			d - mision nombre
			e - fecha desde 
			f - fecha hasta
			g - color primario *
			h - color secundario *
			i - letras o frases *
			j - número de palabras *
			k - idcall
			l - ocr *
			m - stampmision *
		*/

		let wordcloud = url + '/?a=' + survey + '&b=' + answer + '&c=' + idProject + '&d=&e=&f=&g=' + self.primaryColor + '&h=' + self.secundaryColor + '&i=' + wordsOrPhrases + '&j=' + self.numberWordsWordcloud + '&k=&l=' + qidTieneCaptureOCR + '&m=' + self.stampMision + '&n=&o=';

		$('#wordcloud').attr('src', wordcloud);
	},

	// TABLA DE RESULTADOS
	renderData() {
		let self = this;

		if(self.dataFlag) {
			$('#registers' + self.suffix).dataTable().fnDestroy();
		} else {
			self.dataFlag = true;
		}

		let eyeHead = '';
		let eyeSearch = '';
		if(self.typeQuest == '|' || self.typeQuest == '7' || self.typeQuest == 'J') {
			eyeHead = `<th scope="col" title="${pf.const.language.RSC169}">${pf.const.language.RSC169}</th>`;
			eyeSearch = `<td data-name="visualizar">visualizar</td>`;
		}

		$('#resultTableM').show();
		let excelTitle = self.questionOrder + ' - ' + self.idMission + ' - ' + $('#question').val();

		let gdpr = sessionStorage['STCMBackEnd:GDPR'];

		let nameSurnameHead = `
			<th scope="col" title="${pf.const.language.RSC123}">${pf.const.language.RSC123}</th>
			<th scope="col" title="${pf.const.language.RSC1626}">${pf.const.language.RSC1626}</th>
			<th scope="col" title="${pf.const.language.RSC1627}">${pf.const.language.RSC1627}</th>
		`;
		let nameSurnameFilter = `
			<td data-name="userName">userName</td>
			<td data-name="userApellido">userApellido</td>
			<td data-name="userApellido2">userApellido2</td>
		`;

		// Control GDPR
		if(gdpr == '1') {
			nameSurnameHead = '';
			nameSurnameFilter = '';
		}

		let table = `
			<thead>
				<tr>
					${nameSurnameHead}
					<th scope="col" title="${pf.const.language.RSC136}">${pf.const.language.RSC136}</th>
					<th scope="col" title="${pf.const.language.RSC124}">${pf.const.language.RSC124}</th>
					<th scope="col" title="${pf.const.language.RSC309}">${pf.const.language.RSC309}</th>
					<th scope="col" title="${pf.const.language.RSC125}">${pf.const.language.RSC125}</th>
					<th scope="col" title="${pf.const.language.RSC126}">${pf.const.language.RSC126}</th>
					<th scope="col" title="${pf.const.language.RSC127}">${pf.const.language.RSC127}</th>
					<th scope="col" title="${pf.const.language.RSC128}">${pf.const.language.RSC128}</th>
					${eyeHead}
		`;

		$.each(self.data[0], function(key, value) {
			if(key.indexOf('perf') !== -1 && key.indexOf('Desc') !== -1) {
				table += `<th scope="col" title="${value}">${value}</th>`;
			}
		});

		table += `
				</tr>
			</thead>

			<thead class="filtersResult">
				<tr>
					${nameSurnameFilter}
					<td data-name="userEmail">userEmail</td>
					<td data-name="consejero">consejero</td>
					<td data-name="staff">staff</td>
					<td data-name="clabe">clabe</td>
					<td data-name="enabled">enabled</td>
					<td data-name="answer">answer</td>
					<td data-name="answerothers">answerothers</td>
					${eyeSearch}
		`;

		$.each(self.data[0], function(key, value) {
			if(key.indexOf('perf') !== -1 && key.indexOf('Desc') === -1 && key != 'perf002Range') {
				table += `<td data-name="${key}">${key}</td>`;
			}
		});

		table += `
				</tr>
			</thead>

			<tbody>
		`;

		let usersMailRanking = {};

		let size = self.data.length;
		for(let i = 0; i < size; i++) {
			if(self.data[i].question.indexOf('comment') != -1) {
				continue;
			}

			let eyeBody = '';
			if((self.typeQuest == '|' || self.typeQuest == '7' || self.typeQuest == 'J') && self.data[i].answerothers != '') {
				eyeBody = `
					<td class="text-center" data-file="${self.data[i].answerothers}">
						<span class="d-none">${pf.const.language.RSC120}</span>
						<button type="button" class="btn loadFile table-button main-color-text">
							${stcmbackend.svg.bigEyeWithoutColor}
						</button>
					</td>
				`;
			} else if(self.typeQuest == '|' || self.typeQuest == '7' || self.typeQuest == 'J') {
				eyeBody = `
					<td class="text-center">
						<span class="d-none">${pf.const.language.RSC121}</span>
					</td>
				`;
			}

			let answerothers = (self.data[i].answerothers == '' ? '-' : self.data[i].answerothers);

			// Control de puestos de preguntas tipo "R"
			if(self.typeQuest == 'R') {
				if(usersMailRanking[self.data[i].userEmail] == undefined) {
					usersMailRanking[self.data[i].userEmail] = 1;
				} else {
					usersMailRanking[self.data[i].userEmail]++;
				}
				answerothers = usersMailRanking[self.data[i].userEmail]; 
			}

			if(self.data[i].answer == '-oth-') {
				self.data[i].answer = pf.const.language.RSC128;
			}

			let nameSurnameBody = `
				<td class="text-truncate" title="${self.data[i].userName}">${self.data[i].userName}</td>
				<td class="text-truncate" title="${self.data[i].userApellido}">${self.data[i].userApellido}</td>
				<td class="text-truncate" title="${(self.data[i].userApellido2 != null ? self.data[i].userApellido2 : '-')}">${(self.data[i].userApellido2 != null ? self.data[i].userApellido2 : '-')}</td>
			`;

			// Control GDPR
			if(gdpr == '1') {
				nameSurnameBody = '';
			}

			// Respuesta para preguntas de array
			let answer = '';
			if(Object.keys(self.questionsSQ).length > 0) {
				answer = self.data[i].answer + ' - ' + self.questionsSQ[self.data[i].question].name;
			} else if(self.data[i].answer != 'Others') {
				answer = self.data[i].answer;
			}

			table += `
				<tr>
					${nameSurnameBody}
					<td class="text-truncate" title="${self.data[i].userEmail}">${self.data[i].userEmail}</td>
					<td class="text-center">
						<span class="d-none">${(self.data[i].consejero == '1' ? pf.const.language.RSC120 : pf.const.language.RSC121)}</span>
						<input type="checkbox" disabled ${(self.data[i].consejero == '1' ? 'checked' : '')}>
					</td>
					<td class="text-center">
						<span class="d-none">${(self.data[i].staff == '1' ? pf.const.language.RSC120 : pf.const.language.RSC121)}</span>
						<input type="checkbox" disabled ${(self.data[i].staff == '1' ? 'checked' : '')}>
					</td>
					<td class="text-center">
						<span class="d-none">${(self.data[i].clabe == '1' ? pf.const.language.RSC120 : pf.const.language.RSC121)}</span>
						<input type="checkbox" disabled ${(self.data[i].clabe == '1' ? 'checked' : '')}>
					</td>
					<td class="text-center">
						<span class="d-none">${(self.data[i].enabled == '1' ? pf.const.language.RSC120 : pf.const.language.RSC121)}</span>
						<input type="checkbox" disabled ${(self.data[i].enabled == '1' ? 'checked' : '')}>
					</td>
					<td class="text-truncate" title="${answer}">${answer}</td>
					<td class="text-truncate" title="${answerothers}">${answerothers}</td>
					${eyeBody}
			`;

			$.each(self.data[i], function(key, value) {
				if(key.indexOf('perf') !== -1 && key.indexOf('Desc') === -1 && key != 'perf002Range') {
					if(value == null) {
						value = '-';
					}
					table += `<td class="text-truncate" title="${value}">${value}</td>`;
				}
			});

			table += `
				</tr>
			`;
		}

		table += `
			</tbody>
		`;

		$('#registers' + self.suffix).html(table);
		// Setup - add a text input to each footer cell
		$('#registers' + self.suffix + ' .filtersResult td').each(function() {
			let title = $(this).text();
			let value = `<input type="text" class="form-control form-control-sm refresh">`;

			if(title == 'consejero' || title == 'staff' || title == 'clabe' || title == 'enabled') {
				value = `
					<select class="form-control form-control-sm refreshSel">
						<option value="">${pf.const.language.RSC119}</option>
						<option value="${pf.const.language.RSC121}">${pf.const.language.RSC121}</option>
						<option value="${pf.const.language.RSC120}">${pf.const.language.RSC120}</option>
					</select>
				`;
			} else if(title == 'visualizar') {
				value = `
					<select class="form-control form-control-sm visualize">
						<option value="">${pf.const.language.RSC119}</option>
						<option value="${pf.const.language.RSC121}">${pf.const.language.RSC121}</option>
						<option value="${pf.const.language.RSC120}">${pf.const.language.RSC120}</option>
					</select>
				`;
			} else if(title == 'answerothers') {
				value = `<input type="text" class="form-control form-control-sm others refresh">`;
			}

			$(this).html(value);
		});

		let columnDefs = [
			{width: '60px', targets: 4},
			{width: '40px', targets: 5},
			{width: '40px', targets: 6},
			{width: '40px', targets: 7}
		];

		// Visualizar imágenes
		if(self.typeQuest == '|' || self.typeQuest == '7' || self.typeQuest == 'J') {
			columnDefs.push({width: '60px', targets: 10});
		}

		// Control GDPR
		if(gdpr == '1') {
			columnDefs = [
				{width: '60px', targets: 1},
				{width: '40px', targets: 2},
				{width: '40px', targets: 3},
				{width: '40px', targets: 4}
			];

			// Visualizar imágenes
			if(self.typeQuest == '|' || self.typeQuest == '7' || self.typeQuest == 'J') {
				columnDefs.push({width: '60px', targets: 7});
			}
		}

		let dataTable = $('#registers' + self.suffix).DataTable({
			retrieve: true,
			language: pf.const.language_table,
			pageLength: 25,
			autoWidth: false,
			columnDefs: columnDefs,
			dom: 'Bfrtip',
			buttons: [{
				extend: 'excelHtml5',
				text: pf.const.language.RSC129,
				className: 'd-none',
				title: excelTitle,
				customize(xlsx) {
					dataTablesExcelCustomize(xlsx);
				}
			}],
			rowGroup: {
				endRender(rows, group) {
					// Paginado
					return group + ': ' + pf.const.language.RSC146 + ' (' + rows.count() + ')';
				},
				dataSrc: 0
			},
			order: [[0, 'asc']]
		});

		// Ocultar botones de tabla
		hideTableButtons('registers' + self.suffix);

		// Apply the search
		applyTheSearch(dataTable, 'filtersResult');

		dataTable.rowGroup().disable().draw();
		$('#nestBy').hide();

		// Creación de select principal de agrupamiento
		// Arrays de datos
		let name = [];

		$.each($('#registers' + self.suffix + ' thead th'), function() {
			name.push($(this).text());
		});

		let options1 = `<option value="-1">${pf.const.language.RSC130}</option>`;
		for(let i = 0; i < name.length; i++) {
			options1 += `<option value="${i}">${name[i]}</option>`;
		}
		$('#groupBy').html(options1);

		// Función de agrupamiento anidado
		function nestBy() {
			$('#nestBy').html('');
			let options2 = `<option value="-1">${pf.const.language.RSC131}</option>`;
			for(let i = 0; i < name.length; i++) {
				if(i == $('#groupBy').val()) {
					continue;
				} else {
					options2 += `<option value="${i}">${name[i]}</option>`;
				}
			}
			$('#nestBy').html(options2);

			// Evento de anidado
			$('#nestBy').off().on('change', function() {
				let valueGroup = $('#groupBy').val();

				if($('#nestBy').val() === '-1') {
					dataTable.rowGroup().dataSrc(valueGroup);
					dataTable.order([[valueGroup, 'asc']]).draw();
				} else {
					let valueNest = $('#nestBy').val();
					dataTable.rowGroup().dataSrc([valueGroup, valueNest]);
					dataTable.order([[valueGroup, 'asc'], [valueNest, 'asc']]).draw();
				}
			});
		}

		// Evento de agrupamiento
		$('#groupBy').on('change', function() {
			if($('#groupBy').val() === '-1') {
				dataTable.rowGroup().disable().draw();
				$('#nestBy').hide();
			} else {
				let value = $('#groupBy').val();

				dataTable.rowGroup().enable().draw();
				$('#nestBy').show();

				dataTable.rowGroup().dataSrc(value);
				dataTable.order([[value, 'asc']]).draw();

				// Recreación de agrupamiento secundario
				nestBy();
			}
		});

		$('#exportQuestion').off().on('click', function() {
			$('#resultTableM .buttons-excel').trigger('click');
		});

		// Carga de archivos
		self.fileLoad();

		// Carga de archivos con cambio de página
		$('#resultTableM').on('draw.dt', function() {
			self.fileLoad();
		});

		// Select de visualizar
		$('.visualize').on('change', function() {
			if($(this).val() == pf.const.language.RSC120) {
				$(this).parent().parent().find('.others').val('.');
			} else if($(this).val() == pf.const.language.RSC121) {
				$(this).parent().parent().find('.others').val('-');
			} else {
				$(this).parent().parent().find('.others').val('');
			}
			$('.others').trigger('keyup');
		});

		// Actualizar gráficas
		$('.refresh').keyup(delay(function(e) {
			self.refresGraphs();
		}, stcm.const.RefreshGraphsTime));
		$('.refreshSel').change(delay(function(e) {
			self.refresGraphs();
		}, stcm.const.RefreshGraphsTime));

		function delay(fn, ms) {
			let timer = 0
			return function(...args) {
				clearTimeout(timer);
				timer = setTimeout(fn.bind(this, ...args), ms || 0);
			}
		}
	},

	refresGraphs() {
		let self = this;

		self.graphFilter = {};
		$('#registers' + self.suffix + ' .filtersResult td').each(function() {
			let name = $(this).attr('data-name');
			let value = '';

			if(name == 'consejero' || name == 'staff' || name == 'clabe' || name == 'enabled' || name == 'visualizar') {
				value = $(this).find('select').val();
			} else {
				value = $(this).find('input').val();
			}

			self.graphFilter[name] = value;
		});

		// Registrar los diferentes labels para respuestas, género, edad y estados
		let updateGraph = new UpdateGraphs(self.data, self.graphFilter);
		updateGraph.filterData();
		// Actualizar los datos de respuestas
		let answersPercentdata = updateGraph.updateAnswersData(self.answersLabelsData);
		self.answersLabelsData.datasets.data = answersPercentdata;
		let answers = self.answersLabelsData;
		// Parametros para cuando no es a pantalla completa
		if(typeof answers.options == 'string') {
			answers.options = JSON.parse(answers.options);
		}
		answers.options.title.display = false;
		self.createGraphs(answers, 0);

		if(!self.perfGraph) {
			// Actualizar los datos de género
			let genderPercentdata = updateGraph.updateGenderData(self.genderLabelsData);
			self.genderLabelsData.datasets.data = genderPercentdata;
			let gender = self.genderLabelsData;
			// Parametros para cuando no es a pantalla completa
			if(typeof gender.options == 'string') {
				gender.options = JSON.parse(gender.options);
			}
			gender.options.title.display = false;
			self.createGraphs(gender, 1);

			// Actualizar los datos de edad
			let agePercentdata = updateGraph.updateAgeData(self.ageLabelsData);
			self.ageLabelsData.datasets.data = agePercentdata;
			let age = self.ageLabelsData;
			// Parametros para cuando no es a pantalla completa
			if(typeof age.options == 'string') {
				age.options = JSON.parse(age.options);
			}
			age.options.title.display = false;
			self.createGraphs(age, 2);

			// Actualizar los datos de estado
			let statePercentdata = updateGraph.updateStateData(self.stateLabelsData);
			self.stateLabelsData.datasets.data = statePercentdata;
			let state = self.stateLabelsData;
			// Parametros para cuando no es a pantalla completa
			if(typeof state.options == 'string') {
				state.options = JSON.parse(state.options);
			}
			state.options.title.display = false;
			self.createGraphs(state, 3);

			// Actualizar los datos de NSE
			let NSEPercentdata = updateGraph.updateNSEData(self.NSELabelsData);
			self.NSELabelsData.datasets.data = NSEPercentdata;
			let nse = self.NSELabelsData;
			// Parametros para cuando no es a pantalla completa
			if(typeof nse.options == 'string') {
				nse.options = JSON.parse(nse.options);
			}
			nse.options.title.display = false;
			self.createGraphs(nse, 4);
		}
	},

	fileLoad() {
		let self = this;

		$('.loadFile').off().on('click', function() {
			let file = $(this).parent().attr('data-file');
			self.fileShow(file);
		});
	},

	fileShow(file) {
		let self = this;

		$('#attachmentViewer').show();
		$('.attachmentContainer').html('');

		let url = self.loadIMG + `/upload/surveys/${self.idPoll}/files/`;
		let dot = file.lastIndexOf('.');
		let imgName = file.substring(0, dot);
		let ext = file.substring((dot + 1)).toLowerCase();
		let content = '';
		if(ext == 'mp4' || ext == 'mp3' || ext == 'avi' || ext == 'mov') {
			content = `<video id="videoRep" controls src="${url + imgName}" type="video/${ext}"></video>`;
		} else if(ext == 'pdf') {
			let src = url + imgName;

			content = `<embed src="${src}" width="100%" height="100%" type="application/pdf">`;
		} else {
			content = `<img id="imgCont" src="${url + imgName}"></img>`;
		}

		$('.attachmentContainer').html(content);

		$('#closeAttachment').off().on('click', function() {
			if(ext == 'mp4' || ext == 'mp3' || ext == 'avi' || ext == 'mov') {
				let vid = document.getElementById('videoRep');
				vid.pause();
			}
			$('.attachmentContainer').html('');
			$('#attachmentViewer').hide();
		});
	},

	// Gráfica o WordCloud a pantalla completa
	graphsEvents() {
		let self = this;

		let graph = '';
		let quantity = 0;

		$('#mGraphs .card-body').off().on('click', function() {
			graph = $(this).find('canvas').prop('id');

			if(graph === undefined && self.wordCloud) {
				$('#wordCloudViewer').show();

				// Los valores de survey y answer los recogerá de los atributos
				let survey = self.idPoll;
				let answer = self.columnName;
				let url = self.wordCloudURL;

				// Palabras (1) o frases (2)
				let wordsOrPhrases = 2;

				if(self.quest_type == 'S' || self.quest_type == 'Q') {
					wordsOrPhrases = 1;
				}

				let qidTieneCaptureOCR = '';
				let idProject = '';
				if(self.qidTieneCaptureOCR != '0' && (self.quest_type == '|' || self.quest_type == '7' || self.quest_type == 'J')) {
					wordsOrPhrases = 1;
					qidTieneCaptureOCR = self.qidTieneCaptureOCR;
					idProject = self.project;
				}

				wordcloud = url + '/?a=' + survey + '&b=' + answer + '&c=' + idProject + '&d=&e=&f=&g=' + self.primaryColor + '&h=' + self.secundaryColor + '&i=' + wordsOrPhrases + '&j=' + self.numberWordsWordcloud + '&k=&l=' + qidTieneCaptureOCR + '&m=' + self.stampMision + '&n=&o=';

				$('#wordcloudBig').attr('src', wordcloud);

				window.addEventListener('message', function(event) {
					self.wordCloudImg = event.data;
				});

				$('#downloadWordCloud').hide();
				setTimeout(function() {
					$('#downloadWordCloud').show();
				}, 8000);

				$('#downloadWordCloud').off().on('click', function() {
					let a = document.getElementById('downloadWordCloud');
					a.href = self.wordCloudImg;
				});

				$('#closeWordCloud').off().on('click', function() {
					$('#wordCloudViewer').hide();
				});
			} else {
				$('#graphicsViewer').show();
				let data = '';
				let titleText = '';
				let participants = pf.const.language.RSC443 + ': ' + self.participantsNumber;

				let ctx = document.getElementById('graphViewer').getContext('2d');
				switch(graph) {
					case 'graphAnswers':
						data = self.answersData;
						quantity = data.labels.length;
						if(typeof data.options === 'string') {
							data.options = JSON.parse(data.options);
						}
						data.options.title.display = true;
						titleText = $('#resp').text();
						data.options.title.text = [titleText, participants];
						data.options.title.padding = 26;
						data.options.layout.padding.top = 0;

						if(Object.keys(self.questionsSQ).length > 0 || self.typeQuest == 'R') {
							data.options.legend.display = true;
							data.options.scales.xAxes[0]['stacked'] = true;
							data.options.scales.yAxes[0]['stacked'] = true;
						}
						break;
					case 'graphGender':
						data = self.genderData;
						if(typeof data.options === 'string') {
							data.options = JSON.parse(data.options);
						}
						data.options.title.display = true;
						titleText = pf.const.language.RSC147 + ' (%)';
						data.options.title.text = [titleText, participants];
						data.options.title.padding = 26;
						data.options.layout.padding.top = 0;
						break;
					case 'graphAge':
						data = self.ageData;
						quantity = data.labels.length;
						if(typeof data.options === 'string') {
							data.options = JSON.parse(data.options);
						}
						data.options.title.display = true;
						titleText = pf.const.language.RSC148 + ' (%)';
						data.options.title.text = [titleText, participants];
						data.options.title.padding = 26;
						data.options.layout.padding.top = 0;
						break;
					case 'graphStates':
						data = self.statesData;
						quantity = data.labels.length;
						if(typeof data.options === 'string') {
							data.options = JSON.parse(data.options);
						}
						data.options.title.display = true;
						titleText = pf.const.language.RSC149 + ' (%)';
						data.options.title.text = [titleText, participants];
						data.options.title.padding = 26;
						data.options.layout.padding.top = 0;
						break;
					case 'graphNSE':
						data = self.NSEData;
						quantity = data.labels.length;
						if(typeof data.options === 'string') {
							data.options = JSON.parse(data.options);
						}
						data.options.title.display = true;
						titleText = pf.const.language.RSC1000 + ' (%)';
						data.options.title.text = [titleText, participants];
						data.options.title.padding = 26;
						data.options.layout.padding.top = 0;
						break;
					default:
						break;
				}

				data.options['tooltips'] = {
					enabled: false
				};

				if(graph == 'graphGender') {
					data.options['plugins'] = {
						datalabels: {
							color: 'black',
							font: {
								weight: 'bold',
								size: self.fontSize
							},
							clamp: true,
							formatter(value, context) {
								return value;
							}
						}
					};
				} else {
					// Control de tamaño máximo de columna
					data.options.scales.xAxes[0]['maxBarThickness'] = 150;

					if((Object.keys(self.questionsSQ).length > 0 || self.typeQuest == 'R') && graph == 'graphAnswers') {
						data.options['plugins'] = {
							datalabels: {
								color: 'black',
								font: {
									weight: 'bold',
									size: self.fontSize
								},
								formatter(value, context) {
									return value;
								}
							}
						};
					} else {
						// Radio de ángulos
						data.options.cornerRadius = 6;

						data.options['plugins'] = {
							datalabels: {
								color: 'black',
								font: {
									weight: 'bold',
									size: self.fontSize
								},
								anchor: 'end',
								align: 'end',
								formatter(value, context) {
									return value;
								}
							}
						};
					}
				}

				Chart.defaults.global.defaultFontSize = parseInt(self.fontSize);
				Chart.defaults.global.defaultFontFamily = self.fontName;

				if(graph != 'graphGender') {
					// Ancho de columnas
					data.options.scales.xAxes[0]['barPercentage'] = 0.5;
					// Ticks X en horizontal con salto de linea
					// Ancho del contenedor de la gráfica
					let divParentWidth = $('#graphViewer').parent().css('width');
					// Número de columnas de la gráfica
					let nColumns = quantity;
					// Ancho del contenedor entre el número de columnas
					let maxwidth = Math.floor(parseInt(divParentWidth) / nColumns);
					// Ancho de la columna entre el tamaño de la fuente
					let maxwidthFont = Math.ceil(maxwidth / self.fontSize) + 2;

					// Etiquetas del eje X
					let xLabels = data.labels;
					// Comprobación de la primera palabra de los labes para ejecutar formato horizontal o diagonal
					let controlH = true;
					let xSize = xLabels.length;
					// Utilización de caracter de corte si lo hay
					if(self.splitCharacter != '') {
						for(let i = 0; i < xSize; i++) {
							if(xLabels[i] == null || xLabels[i] == undefined) {
								continue;
							}

							let indexCut = xLabels[i].toString().indexOf(self.splitCharacter);
							if(indexCut != -1) {
								xLabels[i] = xLabels[i].toString().slice(0, indexCut);
							}
						}
					}

					for(let i = 0; i < xSize; i++) {
						if(xLabels[i] == null || xLabels[i] == undefined) {
							continue;
						}

						let words = xLabels[i].toString().split(' ');
						let wSize = words.length;
						for(let j = 0; j < wSize; j++) {
							if(words[j].length > maxwidthFont) {
								controlH = false;
								break;
							}
						}
						if(!controlH) {
							break;
						}
					}

					if(controlH) {
						data.options.scales.xAxes[0].ticks['minRotation'] = 0;
						data.options.scales.xAxes[0].ticks['maxRotation'] = 0;

						data.options.scales.xAxes[0].ticks['callback'] = function(value, index, values) {
							let formmatedvalue = formatLabel(value, maxwidthFont);

							return formmatedvalue;
						}
					}
				}

				if(screen.width < 380) {
					data.options.scales.xAxes[0].ticks.fontSize = 12;
				}

				chart = new Chart(ctx, {
					// The type of chart we want to create
					type: data.type,
					// The data for our dataset
					data: {
						labels: data.labels,
						datasets: (Object.keys(self.questionsSQ).length > 0 || self.typeQuest == 'R') && graph == 'graphAnswers' ? data.datasets : [data.datasets]
					},
					// Configuration options go here
					options: data.options
				});
			}
		});

		$('#downloadGraph').off().on('click', function() {
			/*Get image of canvas element*/
			let url_base64jp = document.getElementById('graphViewer').toDataURL('image/jpg');
			/*get download button (tag: <a></a>) */
			let a = document.getElementById('downloadGraph');
			/*insert chart image url to download button (tag: <a></a>) */
			a.href = url_base64jp;
		});

		$('#closeGraphic').off().on('click', function() {
			if(graph !== 'graphAnswers' || !self.wordCloud) {
				chart.destroy();
			}
			$('#graphicsViewer').hide();
		});
	},

	carousel() {
		let self = this;

		let carouselImgs = '';
		let url = self.loadIMG + `/upload/surveys/${self.idPoll}/files/`;
		let first = true;
		let size = self.data.length;

		if(size > stcm.const.numItemsPreview) {
			size = 6;
		}

		for(let i = 0; i < size; i++) {
			if(self.data[i].answerothers.trim() != '') {
				let dot = self.data[i].answerothers.lastIndexOf('.');
				let imgName = self.data[i].answerothers.substring(0, dot);
				let ext = self.data[i].answerothers.substring((dot + 1)).toLowerCase();
				if(first) {
					if(ext == 'mp4' || ext == 'mp3' || ext == 'avi' || ext == 'mov') {
						carouselImgs += `
							<div class="carousel-item active">
								<video preload="none" controls src="${url + imgName}" class="img-fluid d-inline-block"></video>
							</div>
						`;
					} else {
						carouselImgs += `
							<div class="carousel-item active">
								<img src="${url + imgName}" class="img-fluid d-inline-block">
							</div>
						`;
					}

					first = false;
				} else {
					if(ext == 'mp4' || ext == 'mp3' || ext == 'avi' || ext == 'mov') {
						carouselImgs += `
							<div class="carousel-item">
								<video preload="none" controls src="${url + imgName}" class="img-fluid d-inline-block"></video>
							</div>
						`;
					} else {
						carouselImgs += `
							<div class="carousel-item">
								<img src="${url + imgName}" class="img-fluid d-inline-block">
							</div>
						`;
					}
				}
			}
		}
		$('#carouselInner').html(carouselImgs);
		$('.carousel').carousel();
	},

	executeNewReports() {
		let self = this;

		let headersExcel = '';
		// En el caso de excel preparar los valores básicos de cabeceras
		if(self.reports.excel) {
			if(self.numPregPerf < 4) {
				/*
					RSC1436 = Rotación
					RSC123 = Nombre
					RSC999 = Folio
				*/
				headersExcel = pf.const.language.RSC1436 + ',' + pf.const.language.RSC123 + ',' + pf.const.language.RSC999 + ',Submit date,Date,Time,';

				/*
					RSC564 = Estado
					RSC601 = Región ABI
					RSC607 = Ciudad
					RSC565 = Edad
					RSC1917 = Rango de edad
					RSC151 = Género
					RSC1948 = Segmentación
					RSC560 = Asesor
					RSC126 = Activo
					RSC572 = Validación
				*/
				headersExcel += pf.const.language.RSC564 + ',' + pf.const.language.RSC601 + ',' + pf.const.language.RSC607 + ',' + pf.const.language.RSC565 + ',' + pf.const.language.RSC1917 + ',' + pf.const.language.RSC151 + ',' + pf.const.language.RSC1948 + ',' + pf.const.language.RSC560 + ',' + pf.const.language.RSC126 + ',' + pf.const.language.RSC572
			} else {
				/*
					RSC1436 = Rotación
					RSC123 = Nombre
					RSC999 = Folio
				*/
				headersExcel = pf.const.language.RSC1436 + ',' + pf.const.language.RSC123 + ',' + pf.const.language.RSC999 + ',Submit date,Date,Time,';

				/*
					RSC564 = Estado
					RSC601 = Región ABI
					RSC607 = Ciudad
					RSC565 = Edad
					RSC1917 = Rango de edad
					RSC151 = Género
					RSC598 = NSE
					RSC1990 = Rango NSE
					RSC1948 = Segmentación
					RSC560 = Asesor
					RSC126 = Activo
					RSC572 = Validación
				*/
				headersExcel += pf.const.language.RSC564 + ',' + pf.const.language.RSC601 + ',' + pf.const.language.RSC607 + ',' + pf.const.language.RSC565 + ',' + pf.const.language.RSC1917 + ',' + pf.const.language.RSC151 + ',' + pf.const.language.RSC598 + ',' + pf.const.language.RSC1990 + ',' + pf.const.language.RSC1948 + ',' + pf.const.language.RSC560 + ',' + pf.const.language.RSC126 + ',' + pf.const.language.RSC572
			}

			if(sessionStorage['STCMBackEnd:Consumer'] == 1) {
				headersExcel += ',' + pf.const.language.RSC1899; // Consumidor
			}
		}

		// Parámetros de reporte
		let parameters = {
			idTenant: sessionStorage['STCMBackEnd:idTenant'],
			user: self.user,
			timestamp: self.timestamp,
			survey: self.idPoll,
			idmision: self.idMission,
			nameMission: self.idMission.replace(/\//g, '-'),
			stampMision: self.stampMision,
			project: self.project,
			numPregPerf: self.numPregPerf,
			// Excel
			excelDataOpt: self.excelDataOpt,
			headersExcel: headersExcel,
			consumo: sessionStorage['STCMBackEnd:Consumer'],
			isContinuing: self.isContinuing,
			startDate: self.startDate,
			endDate: self.endDate,
			// Word y Powerpoint
			isPerf: self.isPerf,
			colorsHex: self.colorsHex,
			typeColors: self.typeColors,
			fontName: self.fontName,
			fontSize: self.fontSize,
			wordCloudURL: self.wordCloudURL,
			primaryColor: self.primaryColor,
			secundaryColor: self.secundaryColor,
			numberWordsWordcloud: self.numberWordsWordcloud,
			// Datos briefing
			briefing: JSON.stringify(self.briefingObject),
			questionIdOut: self.questionIdOut,
			// Datos de plantilla
			plantillaReportes: self.plantillaReportes ? JSON.stringify(self.plantillaReportes) : '0'
		};

		let reportGenerator = new ReportGeneratorController(self.reports, parameters);
		reportGenerator.executeReports();
		self.generatingReports.push(reportGenerator);
	},

	answersOrderDataTemplate(data, type) {
		let self = this;

		if (self.answersOrder == 'default' || self.answersOrder == undefined) return data;

		let orderType = '';
		let dataAux = data;

		switch (self.answersOrder) {
			case 'big_to_small':
				orderType = 'greater';
				break;
			case 'small_to_big':
				orderType = 'smaller';
				break;
		}

		let response;
		if (type == 'A' || type == 'B' || type == 'F') {
			response = self.sortWithSubquestions(data.datasets, orderType);
			self.setOrderSubquestions(data.datasets, response.indices);
		}
		else if (type == 'R') {
			return data;
		}
		else {
			response = self.sortWithIndexGeneric(data.datasets.data, orderType);
		}

		dataAux.labels = self.setOrderArray(response.indices, data.labels);
		dataAux.datasets.data = response.data;

		return dataAux;
	},

	setOrderSubquestions(array, indices) {
		let self = this;
		for (var i = 0; i < array.length; ++i) {
			array[i].data = self.setOrderArray(indices, array[i].data);
		}

		return array;
	},

	setOrderArray(indices, array) {
		let arrayResult = [];
		for (var i = 0; i < indices.length; i++) {
			arrayResult.push(array[indices[i]]);
		}

		return arrayResult;
	},

	sortWithIndexGeneric(array, type) {
		let indexedTest = array.map(function (e, i) { return { index: i, value: e } });

		if (type == 'greater') indexedTest.sort(function (x, y) { return x.value < y.value ? 1 : x.value == y.value ? 0 : -1 });
		else indexedTest.sort(function (x, y) { return x.value > y.value ? 1 : x.value == y.value ? 0 : -1 });

		let indices = indexedTest.map(function (e) { return e.index });

		return {
			data: indexedTest.map(function (e) { return e.value }),
			indices: indices
		}
	},

	singleSort(array, orderType) {
		if (orderType == 'greater') array.sort(function (x, y) { return x < y ? 1 : x == y ? 0 : -1 });
		else array.sort(function (x, y) { return x > y ? 1 : x == y ? 0 : -1 });

		return array;
	},

	sortWithSubquestions(array, orderType) {
		var self = this;
		let arrayAux = [];

		for (var i = 0; i < array.length; ++i) {
			for (var j = 0; j < array[i].data.length; ++j) {
				if (arrayAux[j] === undefined) {
					arrayAux[j] = 0;
				}
				arrayAux[j] += parseFloat(array[i].data[j]);
			}
		}

		for (var i = 0; i < arrayAux.length; ++i) {
			arrayAux[i] = parseFloat(arrayAux[i]).toFixed(1);
		}

		let result = arrayAux.map(i => parseFloat(i));

		return self.sortWithIndexGeneric(result, orderType);
	}

};