text:
 	package org.forpdi.core.company;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;

import org.apache.commons.io.IOUtils;
import org.forpdi.core.event.Current;
import org.forpdi.core.exception.RestoreException;
import org.forpdi.core.user.User;
import org.forpdi.core.user.UserBS;
import org.forpdi.dashboard.manager.LevelInstanceHistory;
import org.forpdi.planning.attribute.AggregateIndicator;
import org.forpdi.planning.attribute.Attribute;
import org.forpdi.planning.attribute.AttributeInstance;
import org.forpdi.planning.document.Document;
import org.forpdi.planning.document.DocumentAttribute;
import org.forpdi.planning.document.DocumentBS;
import org.forpdi.planning.document.DocumentSection;
import org.forpdi.planning.fields.FieldsBS;
import org.forpdi.planning.fields.OptionsField;
import org.forpdi.planning.fields.actionplan.ActionPlan;
import org.forpdi.planning.fields.attachment.Attachment;
import org.forpdi.planning.fields.budget.Budget;
import org.forpdi.planning.fields.budget.BudgetBS;
import org.forpdi.planning.fields.budget.BudgetElement;
import org.forpdi.planning.fields.schedule.Schedule;
import org.forpdi.planning.fields.schedule.ScheduleInstance;
import org.forpdi.planning.fields.schedule.ScheduleStructure;
import org.forpdi.planning.fields.schedule.ScheduleValues;
import org.forpdi.planning.fields.table.TableFields;
import org.forpdi.planning.fields.table.TableInstance;
import org.forpdi.planning.fields.table.TableStructure;
import org.forpdi.planning.fields.table.TableValues;
import org.forpdi.planning.plan.Plan;
import org.forpdi.planning.plan.PlanBS;
import org.forpdi.planning.plan.PlanDetailed;
import org.forpdi.planning.plan.PlanMacro;
import org.forpdi.planning.structure.Structure;
import org.forpdi.planning.structure.StructureBS;
import org.forpdi.planning.structure.StructureLevel;
import org.forpdi.planning.structure.StructureLevelInstance;
import org.forpdi.planning.structure.StructureLevelInstanceDetailed;
import org.forpdi.system.Archive;
import org.hibernate.Criteria;
import org.hibernate.criterion.Restrictions;
import org.json.simple.parser.ParseException;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import br.com.caelum.vraptor.boilerplate.HibernateBusiness;
import br.com.caelum.vraptor.boilerplate.util.GeneralUtils;
import br.com.caelum.vraptor.observer.upload.UploadedFile;
import br.com.caelum.vraptor.serialization.gson.GsonSerializerBuilder;

@RequestScoped
public class BackupAndRestoreHelper extends HibernateBusiness {

	private Gson gson;
	private static int quantity;
	private static int quantityTotal;

	@Inject private PlanBS planBS;
	@Inject private DocumentBS docBS;
	@Inject private StructureBS structureBS;
	@Inject private BudgetBS budgetBS;
	@Inject private CompanyBS companyBS;
	@Inject private UserBS userBS;
	@Inject	private FieldsBS fieldsBS;
	@Inject @Current private CompanyDomain domain;

	@Inject
	public BackupAndRestoreHelper(GsonSerializerBuilder gsonBuilder) {
		gsonBuilder.setWithoutRoot(true);
		gsonBuilder.indented();
		this.gson = gsonBuilder.create();
	}

	@Deprecated
	protected BackupAndRestoreHelper() {}

	/**
	 * consulta o banco e salva as informações em um arquivo
	 *
	 * @throws IOException
	 *
	 */
	public void export(Company company, OutputStream output) throws IOException {

		final ZipOutputStream zos = new ZipOutputStream(output);
		zipAdd(zos, Company.class.getSimpleName(), this.gson.toJson(company));
		zos.flush();

		final HashMap<Long, Structure> structuresMap = new HashMap<>();

		//Exportando os elementos orçamentários
		final List<BudgetElement> budgetElements = this.budgetBS.listAllBudgetElementsByCompany(company);
		if(!GeneralUtils.isEmpty(budgetElements)) {
			for(final BudgetElement budgetElement : budgetElements) {
				budgetElement.setCompany(null);
			}
			zipAdd(zos, BudgetElement.class.getSimpleName(), this.gson.toJson(budgetElements));
			zos.flush();
		}

		// Exportando labels customizadas da company
		final List<CompanyMessage> companyMessage = companyBS.retrieveMessages(company);
		if(!GeneralUtils.isEmpty(companyMessage)) {
			companyMessage.forEach(it -> {
				it.setCompany(null);
			});
			zipAdd(zos, CompanyMessage.class.getSimpleName(), this.gson.toJson(companyMessage));
			zos.flush();
		}

		//Exportando os Planos Macro
		final List<PlanMacro> plansMacro = this.planBS.listAllMacros(company);
		if(!GeneralUtils.isEmpty(plansMacro)) {
			for(final PlanMacro planMacro : plansMacro) {
				planMacro.setCompany(null);
			}
			zipAdd(zos, PlanMacro.class.getSimpleName(), this.gson.toJson(plansMacro));
			zos.flush();
		}

		//Exportando os documentos do PDI
		final List<Document> documents = this.docBS.listAllByPlansMacro(plansMacro);
		if(!GeneralUtils.isEmpty(documents)) {
			for (final Document document : documents) {
				document.setExportPlanMacroId(document.getPlan().getId());
				document.setPlan(null);
			}
			zipAdd(zos, Document.class.getSimpleName(), this.gson.toJson(documents));
			zos.flush();
		}

		//Exportando as seções dos documentos
		final List<DocumentSection> documentSections = this.docBS.listAllSectionsByDocuments(documents);
		if(!GeneralUtils.isEmpty(documentSections)) {
			for (final DocumentSection documentSection : documentSections) {
				documentSection.setExportDocumentId(documentSection.getDocument().getId());
				documentSection.setDocument(null);
				if (documentSection.getParent() != null) {
					documentSection.setExportDocumentSectionId(documentSection.getParent().getId());
					documentSection.setParent(null);
				}
			}
			zipAdd(zos, DocumentSection.class.getSimpleName(), this.gson.toJson(documentSections));
			zos.flush();
		}

		//Exportando os atributos das seções dos documentos
		final List<DocumentAttribute> documentAttributes = this.docBS.listAllAttributesBySections(documentSections);
		if(!GeneralUtils.isEmpty(documentAttributes)) {
			for (final DocumentAttribute attr : documentAttributes) {
				attr.setExportDocumentSectionId(attr.getSection().getId());
				attr.setSection(null);
			}
			zipAdd(zos, DocumentAttribute.class.getSimpleName(), this.gson.toJson(documentAttributes));
			zos.flush();
		}

		//Exportando os planos de metas
		final List<Plan> plans = this.planBS.listAllPlansForPlansMacro(plansMacro);
		if(!GeneralUtils.isEmpty(plans)) {
			for (final Plan plan : plans) {
				final Structure structure = plan.getStructure();
				plan.setExportPlanMacroId(plan.getParent().getId());
				plan.setExportStructureId(structure.getId());
				plan.setParent(null);
				plan.setStructure(null);
				if (!structuresMap.containsKey(structure.getId())) {
					structuresMap.put(structure.getId(), structure);
				}
			}
			zipAdd(zos, Plan.class.getSimpleName(), this.gson.toJson(plans));
			zos.flush();
		}

		//Exporta plano detalhado
		final List<PlanDetailed> plansDetailed = this.planBS.listAllPlansDetailed(plans);
		if(!GeneralUtils.isEmpty(plansDetailed)) {
			for (final PlanDetailed pd : plansDetailed) {
				pd.setExportPlanId(pd.getPlan().getId());
				pd.setPlan(null);
			}
			zipAdd(zos, PlanDetailed.class.getSimpleName(), this.gson.toJson(plansDetailed));
			zos.flush();
		}

		// Exportando estruturas
		final List<Structure> structures = new ArrayList<>(structuresMap.values());
		if (!GeneralUtils.isEmpty(structures)) {
			for (final Structure structure : structures) {
				structure.setCompany(null);
			}
			zipAdd(zos, Structure.class.getSimpleName(), this.gson.toJson(structures));
			zos.flush();
		}

		// Exportando níveis de estruturas
		final List<StructureLevel> structureLevels = this.structureBS.listAllStructuresLevels(structures);
		if (!GeneralUtils.isEmpty(structureLevels)) {
			for (final StructureLevel structureLevel : structureLevels) {
				structureLevel.setExportStructureId(structureLevel.getStructure().getId());
				structureLevel.setStructure(null);
			}
			zipAdd(zos, StructureLevel.class.getSimpleName(), this.gson.toJson(structureLevels));
			zos.flush();
		}

		// Exportando atributos
		final List<Attribute> attributes = this.structureBS.listAllAttributes(structureLevels);
		if (!GeneralUtils.isEmpty(attributes)) {
			for (final Attribute attribute : attributes) {
				attribute.setExportStructureLevelId(attribute.getLevel().getId());
				attribute.setLevel(null);
			}
			zipAdd(zos, Attribute.class.getSimpleName(), this.gson.toJson(attributes));
			zos.flush();
		}

		//Exportando as estruturas level instance necessárias.
		final List<StructureLevelInstance> structureLevelInstances = this.structureBS.listAllLevelInstanceByPlans(plans);
		if(!GeneralUtils.isEmpty(structureLevelInstances)) {
			for (final StructureLevelInstance sli : structureLevelInstances) {
				sli.setExportLevelId(sli.getLevel().getId());
				sli.setExportPlanId(sli.getPlan().getId());
				sli.setLevel(null);
				sli.setPlan(null);

				final AttributeInstance responsible = this.structureBS.listResponsibleAttributeByLevel(sli);
				if (responsible != null) {
					User user = this.userBS.existsByUser(Long.parseLong(responsible.getValue()));
					sli.setExportResponsibleMail(user.getEmail());
				}
			}
			zipAdd(zos, StructureLevelInstance.class.getSimpleName(), this.gson.toJson(structureLevelInstances));
			zos.flush();
		}

		//Exportando os detalhes das estruturas level instance.
		final List<StructureLevelInstanceDetailed> structureLevelInstancesDetailed =
			this.structureBS.listAllLevelInstancesDetailedByLevelInstances(structureLevelInstances);
		if(!GeneralUtils.isEmpty(structureLevelInstancesDetailed)) {
			for (final StructureLevelInstanceDetailed slid : structureLevelInstancesDetailed) {
				slid.setExportStructureLevelInstanceId(slid.getLevelInstance().getId());
				slid.setLevelInstance(null);
			}
			zipAdd(zos, StructureLevelInstanceDetailed.class.getSimpleName(), this.gson.toJson(structureLevelInstancesDetailed));
			zos.flush();
		}

		//Exportando o histórico das estruturas level instance.
		final List<LevelInstanceHistory> levelInstancesHistory =
			this.structureBS.listAllLevelInstancesHistoryByLevelInstances(structureLevelInstances);
		if(!GeneralUtils.isEmpty(levelInstancesHistory)) {
			for (final LevelInstanceHistory lih : levelInstancesHistory) {
				lih.setExportStructureLevelInstanceId(lih.getLevelInstance().getId());
				lih.setLevelInstance(null);
			}
			zipAdd(zos, LevelInstanceHistory.class.getSimpleName(), this.gson.toJson(levelInstancesHistory));
			zos.flush();
		}

		//Exportando os planos de ação
		final List<ActionPlan> actionPlans = this.structureBS.listAllActionPlansByLevelInstances(structureLevelInstances);
		if(!GeneralUtils.isEmpty(actionPlans)) {
			for (final ActionPlan actionPlan : actionPlans) {
				actionPlan.setExportStructureLevelInstanceId(actionPlan.getLevelInstance().getId());
				actionPlan.setLevelInstance(null);
			}
			zipAdd(zos, ActionPlan.class.getSimpleName(), this.gson.toJson(actionPlans));
			zos.flush();
		}

		//Exportando os indicadores agregados
		final List<AggregateIndicator> aggregateIndicators = this.structureBS.listAllAggregateIndicatorsByLevelInstances(structureLevelInstances);
		if(!GeneralUtils.isEmpty(aggregateIndicators)) {
			for (final AggregateIndicator aggregateIndicator : aggregateIndicators) {
				aggregateIndicator.setExportAggregateId(aggregateIndicator.getAggregate().getId());
				aggregateIndicator.setExportIndicatorId(aggregateIndicator.getIndicator().getId());
				aggregateIndicator.setAggregate(null);
				aggregateIndicator.setIndicator(null);
			}
			zipAdd(zos, AggregateIndicator.class.getSimpleName(), this.gson.toJson(aggregateIndicators));
			zos.flush();
		}

		//Exportando os anexos
		final List<Attachment> attachments = this.structureBS.listAllAttachmentsByLevelInstances(structureLevelInstances);
		if(!GeneralUtils.isEmpty(attachments)) {
			for (final Attachment attachment : attachments) {
				attachment.setExportStructureLevelInstanceId(attachment.getLevelInstance().getId());
				attachment.setLevelInstance(null);
				if (attachment.getAuthor() != null) {
					attachment.setExportAuthorMail(attachment.getAuthor().getEmail());
				} else {
					attachment.setExportAuthorMail("");
				}
				attachment.setAuthor(null);
			}
			zipAdd(zos, Attachment.class.getSimpleName(), this.gson.toJson(attachments));
			zos.flush();
		}

		//Exportando os orçamentos
		final List<Budget> budgets = this.budgetBS.listAllBudgetsByElementsAndLevelInstances(budgetElements, structureLevelInstances);
		if(!GeneralUtils.isEmpty(budgets)) {
			for(final Budget budget : budgets) {
				budget.setExportBudgetElementId(budget.getBudgetElement().getId());
				budget.setExportStructureLevelInstanceId(budget.getLevelInstance().getId());
				budget.setBudgetElement(null);
				budget.setLevelInstance(null);
			}
			zipAdd(zos, Budget.class.getSimpleName(), this.gson.toJson(budgets));
			zos.flush();
		}

		//Exportando as instância de atributos
		final List<AttributeInstance> attributeInstances = this.structureBS.listAllAttributeInstanceByLevelInstances(structureLevelInstances);
		if(!GeneralUtils.isEmpty(attributeInstances)) {
			for (final AttributeInstance attrInstance : attributeInstances) {
				attrInstance.setExportAttributeId(attrInstance.getAttribute().getId());
				attrInstance.setExportStructureLevelInstanceId(attrInstance.getLevelInstance().getId());
				attrInstance.setAttribute(null);
				attrInstance.setLevelInstance(null);
			}
			zipAdd(zos, AttributeInstance.class.getSimpleName(), this.gson.toJson(attributeInstances));
			zos.flush();
		}

		//Exportando as opções do select field
		final List<OptionsField> optionsFields = this.fieldsBS.listOptionsFieldsByAttrsAndDocAttrs(attributes, documentAttributes);
		if(!GeneralUtils.isEmpty(optionsFields)) {
			zipAdd(zos, OptionsField.class.getSimpleName(), this.gson.toJson(optionsFields));
			zos.flush();
		}

		//Exportando os cronogramas
		final List<Schedule> schedules = this.fieldsBS.listSchedulesByAttrsAndDocAttrs(attributes, documentAttributes);
		if(!GeneralUtils.isEmpty(schedules)) {
			for (Schedule schedule : schedules) {
				schedule.setScheduleInstances(null);
				schedule.setScheduleStructures(null);
			}
			zipAdd(zos, Schedule.class.getSimpleName(), this.gson.toJson(schedules));
			zos.flush();
		}

		//Exportando os instâncias de cronogramas
		final List<ScheduleInstance> scheduleInstances = this.fieldsBS.listAllScheduleInstancesBySchedules(schedules);
		if(!GeneralUtils.isEmpty(scheduleInstances)) {
			for (final ScheduleInstance scheduleInstance : scheduleInstances) {
				scheduleInstance.setExportScheduleId(scheduleInstance.getSchedule().getId());
				scheduleInstance.setSchedule(null);
			}
			zipAdd(zos, ScheduleInstance.class.getSimpleName(), this.gson.toJson(scheduleInstances));
			zos.flush();
		}

		//Exportando os estruturas de cronogramas
		final List<ScheduleStructure> scheduleStructures = this.fieldsBS.listAllScheduleStructuresBySchedules(schedules);
		if(!GeneralUtils.isEmpty(scheduleStructures)) {
			for (final ScheduleStructure scheduleStructure : scheduleStructures) {
				scheduleStructure.setExportScheduleId(scheduleStructure.getSchedule().getId());
				scheduleStructure.setSchedule(null);
			}
			zipAdd(zos, ScheduleStructure.class.getSimpleName(), this.gson.toJson(scheduleStructures));
			zos.flush();
		}

		//Exportando os valores de cronogramas
		if (!GeneralUtils.isEmpty(scheduleInstances) || !GeneralUtils.isEmpty(scheduleStructures)) {
			final List<ScheduleValues> scheduleValues = this.fieldsBS.listAllScheduleValuesByInstancesAndStructures(scheduleInstances, scheduleStructures);
			if(!GeneralUtils.isEmpty(scheduleValues)) {
				for (final ScheduleValues scheduleValue : scheduleValues) {
					scheduleValue.setExportScheduleInstanceId(scheduleValue.getScheduleInstance().getId());
					scheduleValue.setExportScheduleStructureId(scheduleValue.getScheduleStructure().getId());
					scheduleValue.setScheduleInstance(null);
					scheduleValue.setScheduleStructure(null);
				}
				zipAdd(zos, ScheduleValues.class.getSimpleName(), this.gson.toJson(scheduleValues));
				zos.flush();
			}
		}

		//Exportando as tabelas
		final List<TableFields> tableFields = this.fieldsBS.listTableFieldsByAttrsAndDocAttrs(attributes, documentAttributes);
		if(!GeneralUtils.isEmpty(tableFields)) {
			for (TableFields tableField : tableFields) {
				tableField.setTableInstances(null);
				tableField.setTableStructures(null);
			}
			zipAdd(zos, TableFields.class.getSimpleName(), this.gson.toJson(tableFields));
			zos.flush();
		}

		//Exportando os instâncias de tabelas
		final List<TableInstance> tableInstances = this.fieldsBS.listAllTableInstancesByTableFields(tableFields);
		if(!GeneralUtils.isEmpty(tableInstances)) {
			for (final TableInstance tableInstance : tableInstances) {
				tableInstance.setExportTableFieldsId(tableInstance.getTableFields().getId());
				tableInstance.setTableFields(null);
				tableInstance.setTableValues(null);
			}
			zipAdd(zos, TableInstance.class.getSimpleName(), this.gson.toJson(tableInstances));
			zos.flush();
		}

		//Exportando os estruturas de tabelas
		final List<TableStructure> tableStructures = this.fieldsBS.listAllTableStructuresByTableFields(tableFields);
		if(!GeneralUtils.isEmpty(tableStructures)) {
			for (final TableStructure tableStructure : tableStructures) {
				tableStructure.setExportTableFieldsId(tableStructure.getTableFields().getId());
				tableStructure.setTableFields(null);
			}
			zipAdd(zos, TableStructure.class.getSimpleName(), this.gson.toJson(tableStructures));
			zos.flush();
		}

		//Exportando os valores de tabelas
		if (!GeneralUtils.isEmpty(tableInstances) || !GeneralUtils.isEmpty(tableStructures)) {
			final List<TableValues> tableValues = this.fieldsBS.listAllTableValuesByInstancesAndStructures(tableInstances, tableStructures);
			if(!GeneralUtils.isEmpty(tableValues)) {
				for (final TableValues tableValue : tableValues) {
					tableValue.setExportTableInstanceId(tableValue.getTableInstance().getId());
					tableValue.setExportTableStructureId(tableValue.getTableStructure().getId());
					tableValue.setTableInstance(null);
					tableValue.setTableStructure(null);
				}
				zipAdd(zos, TableValues.class.getSimpleName(), this.gson.toJson(tableValues));
				zos.flush();
			}
		}

		zos.close();
	}

	/**
	 * adiciona dados ao banco a partir do arquivo
	 *
	 * @param file arquivo a ser importado
	 *
	 * @throws IOException
	 *
	 * @throws ParseException
	 *
	 */
	public void restore(UploadedFile file) throws IOException, ParseException {
		final Company company = this.domain.getCompany();
		if (company == null) {
			throw new IllegalArgumentException("Você precisa criar uma instituição e um domínio antes de importar dados.");
		}

		final Map<String, File> files = this.uncompress(file.getFile());
		final Map<Long, BudgetElement> budgetElements = new LinkedHashMap<>();
		final Map<Long, PlanMacro> plansMacro = new LinkedHashMap<>();
		final Map<Long, Document> documents = new LinkedHashMap<>();
		final Map<Long, DocumentSection> documentSections = new LinkedHashMap<>();
		final Map<Long, DocumentAttribute> documentAttributes = new LinkedHashMap<>();
		final Map<Long, Structure> structures = new LinkedHashMap<>();
		final Map<Long, StructureLevel> structureLevels = new LinkedHashMap<>();
		final Map<Long, Attribute> attributes = new LinkedHashMap<>();
		final Map<Long, Plan> plans = new LinkedHashMap<>();
		final Map<Long, StructureLevelInstance> structureLevelInstances = new LinkedHashMap<>();
		final Map<Long, Schedule> schedules = new LinkedHashMap<>();
		final Map<Long, ScheduleInstance> scheduleInstances = new LinkedHashMap<>();
		final Map<Long, ScheduleStructure> scheduleStructures = new LinkedHashMap<>();
		final Map<Long, TableFields> tableFields = new LinkedHashMap<>();
		final Map<Long, TableInstance> tableInstances = new LinkedHashMap<>();
		final Map<Long, TableStructure> tableStructures = new LinkedHashMap<>();

		this.dao.execute((session) -> {
			String content;

			// Importando elementos orçamentários
			content = this.readFromFile(files, BudgetElement.class);
			List<BudgetElement> budgetElementsList = this.gson.fromJson(content, new TypeToken<List<BudgetElement>>() {}.getType());
			if (!GeneralUtils.isEmpty(budgetElementsList)) {
				budgetElementsList.forEach((budgetElement) -> {
					final Long oldId = budgetElement.getId();
					budgetElement.setId(null);
					budgetElement.setCompany(company);
					session.persist(budgetElement);
					budgetElements.put(oldId, budgetElement);
				});
			}

			// Importando mensagens customizadas
			content = this.readFromFile(files, CompanyMessage.class);
			List<CompanyMessage> companyMessagesList = this.gson.fromJson(content, new TypeToken<List<CompanyMessage>>() {}.getType());
			if (!GeneralUtils.isEmpty(companyMessagesList)) {
				companyMessagesList.forEach((companyMessage) -> {
					this.companyBS.updateMessageOverlay(session, company, companyMessage.getMessageKey(), companyMessage.getMessageValue());
				});
			}

			// Importando os planos macro
			content = this.readFromFile(files, PlanMacro.class);
			List<PlanMacro> plansMacroList = this.gson.fromJson(content, new TypeToken<List<PlanMacro>>() {}.getType());
			if (!GeneralUtils.isEmpty(plansMacroList)) {
				plansMacroList.forEach((planMacro) -> {
					final Long oldId = planMacro.getId();
					planMacro.setId(null);
					planMacro.setCompany(company);
					session.persist(planMacro);
					plansMacro.put(oldId, planMacro);
				});
			}

			// Importando os documentos
			content = this.readFromFile(files, Document.class);
			List<Document> documentsList = this.gson.fromJson(content, new TypeToken<List<Document>>() {}.getType());
			if (!GeneralUtils.isEmpty(documentsList)) {
				documentsList.forEach((document) -> {
					final Long oldId = document.getId();
					document.setId(null);
					document.setPlan(plansMacro.get(document.getExportPlanMacroId()));
					session.persist(document);
					documents.put(oldId, document);
				});
			}

			// Importando as seções dos documentos
			content = this.readFromFile(files, DocumentSection.class);
			List<DocumentSection> documentSectionsList = this.gson.fromJson(content, new TypeToken<List<DocumentSection>>() {}.getType());
			if (!GeneralUtils.isEmpty(documentSectionsList)) {
				documentSectionsList.forEach((documentSection) -> {
					final Long oldId = documentSection.getId();
					documentSection.setId(null);
					documentSection.setDocument(documents.get(documentSection.getExportDocumentId()));
					session.persist(documentSection);
					documentSections.put(oldId, documentSection);
				});
				documentSectionsList.forEach((documentSection) -> {
					documentSection.setParent(documentSections.get(documentSection.getExportDocumentSectionId()));
					session.persist(documentSection);
				});
			}

			// Importando os atributos dos documentos
			content = this.readFromFile(files, DocumentAttribute.class);
			List<DocumentAttribute> documentAttributesList = this.gson.fromJson(content, new TypeToken<List<DocumentAttribute>>() {}.getType());
			if (!GeneralUtils.isEmpty(documentAttributesList)) {
				documentAttributesList.forEach((documentAttribute) -> {
					final Long oldId = documentAttribute.getId();
					documentAttribute.setId(null);
					documentAttribute.setSection(documentSections.get(documentAttribute.getExportDocumentSectionId()));
					session.persist(documentAttribute);
					documentAttributes.put(oldId, documentAttribute);
				});
			}

			// Importando as estruturas
			content = this.readFromFile(files, Structure.class);
			List<Structure> structuresList = this.gson.fromJson(content, new TypeToken<List<Structure>>() {}.getType());
			if (!GeneralUtils.isEmpty(structuresList)) {
				structuresList.forEach((structure) -> {
					final Long oldId = structure.getId();
					structure.setId(null);
					structure.setCompany(company);
					session.persist(structure);
					structures.put(oldId, structure);
				});
			}

			// Importando os níveis de estruturas
			content = this.readFromFile(files, StructureLevel.class);
			List<StructureLevel> structureLevelsList = this.gson.fromJson(content, new TypeToken<List<StructureLevel>>() {}.getType());
			if (!GeneralUtils.isEmpty(structureLevelsList)) {
				structureLevelsList.forEach((structureLevel) -> {
					final Long oldId = structureLevel.getId();
					structureLevel.setId(null);
					structureLevel.setStructure(structures.get(structureLevel.getExportStructureId()));
					session.persist(structureLevel);
					structureLevels.put(oldId, structureLevel);
				});
			}

			// Importando os atributos
			content = this.readFromFile(files, Attribute.class);
			List<Attribute> attributesList = this.gson.fromJson(content, new TypeToken<List<Attribute>>() {}.getType());
			if (!GeneralUtils.isEmpty(attributesList)) {
				attributesList.forEach((attribute) -> {
					final Long oldId = attribute.getId();
					attribute.setId(null);
					attribute.setLevel(structureLevels.get(attribute.getExportStructureLevelId()));
					session.persist(attribute);
					attributes.put(oldId, attribute);
				});
			}

			// Importando os planos
			content = this.readFromFile(files, Plan.class);
			List<Plan> plansList = this.gson.fromJson(content, new TypeToken<List<Plan>>() {}.getType());
			if (!GeneralUtils.isEmpty(plansList)) {
				plansList.forEach((plan) -> {
					final Long oldId = plan.getId();
					plan.setId(null);
					plan.setParent(plansMacro.get(plan.getExportPlanMacroId()));
					plan.setStructure(structures.get(plan.getExportStructureId()));
					session.persist(plan);
					plans.put(oldId, plan);
				});
			}

			// Importando os detalhes dos planos
			content = this.readFromFile(files, PlanDetailed.class);
			List<PlanDetailed> plansDetailedList = this.gson.fromJson(content, new TypeToken<List<PlanDetailed>>() {}.getType());
			if (!GeneralUtils.isEmpty(plansDetailedList)) {
				plansDetailedList.forEach((planDetailed) -> {
					planDetailed.setId(null);
					planDetailed.setPlan(plans.get(planDetailed.getExportPlanId()));
					session.persist(planDetailed);
				});
			}

			// Importando as instâncias de nível de estrutura
			content = this.readFromFile(files, StructureLevelInstance.class);
			List<StructureLevelInstance> structureLevelInstancesList = this.gson.fromJson(content, new TypeToken<List<StructureLevelInstance>>() {}.getType());
			if (!GeneralUtils.isEmpty(structureLevelInstancesList)) {
				structureLevelInstancesList.forEach((levelInstance) -> {
					final Long oldId = levelInstance.getId();
					levelInstance.setId(null);
					levelInstance.setLevel(structureLevels.get(levelInstance.getExportLevelId()));
					levelInstance.setPlan(plans.get(levelInstance.getExportPlanId()));

					if(levelInstance.getParent() != null) {
						StructureLevelInstance sli = structureLevelInstances.get(levelInstance.getParent());
						levelInstance.setParent(sli.getId());
					}

					session.persist(levelInstance);
					structureLevelInstances.put(oldId, levelInstance);
				});
			}

			// Importando os detalhes das instâncias de nível de estrutura
			content = this.readFromFile(files, StructureLevelInstanceDetailed.class);
			List<StructureLevelInstanceDetailed> structureLevelInstancesDetailedList = this.gson.fromJson(content, new TypeToken<List<StructureLevelInstanceDetailed>>() {}.getType());
			if (!GeneralUtils.isEmpty(structureLevelInstancesDetailedList)) {
				structureLevelInstancesDetailedList.forEach((levelInstanceDetailed) -> {
					levelInstanceDetailed.setId(null);
					levelInstanceDetailed.setLevelInstance(structureLevelInstances.get(levelInstanceDetailed.getExportStructureLevelInstanceId()));
					session.persist(levelInstanceDetailed);
				});
			}

			// Importando o histórico das instâncias de nível de estrutura
			content = this.readFromFile(files, LevelInstanceHistory.class);
			List<LevelInstanceHistory> levelInstancesHistoryList = this.gson.fromJson(content, new TypeToken<List<LevelInstanceHistory>>() {}.getType());
			if (!GeneralUtils.isEmpty(levelInstancesHistoryList)) {
				levelInstancesHistoryList.forEach((levelInstanceHistory) -> {
					levelInstanceHistory.setId(null);
					levelInstanceHistory.setLevelInstance(structureLevelInstances.get(levelInstanceHistory.getExportStructureLevelInstanceId()));
					session.persist(levelInstanceHistory);
				});
			}

			// Importando os planos de ação
			content = this.readFromFile(files, ActionPlan.class);
			List<ActionPlan> actionPlansList = this.gson.fromJson(content, new TypeToken<List<ActionPlan>>() {}.getType());
			if (!GeneralUtils.isEmpty(actionPlansList)) {
				actionPlansList.forEach((actionPlan) -> {
					actionPlan.setId(null);
					actionPlan.setLevelInstance(structureLevelInstances.get(actionPlan.getExportStructureLevelInstanceId()));
					session.persist(actionPlan);
				});
			}

			// Importando os indicadores agregados
			content = this.readFromFile(files, AggregateIndicator.class);
			List<AggregateIndicator> aggregateIndicatorsList = this.gson.fromJson(content, new TypeToken<List<AggregateIndicator>>() {}.getType());
			if (!GeneralUtils.isEmpty(aggregateIndicatorsList)) {
				aggregateIndicatorsList.forEach((aggregateIndicator) -> {
					aggregateIndicator.setId(null);
					aggregateIndicator.setAggregate(structureLevelInstances.get(aggregateIndicator.getExportAggregateId()));
					aggregateIndicator.setIndicator(structureLevelInstances.get(aggregateIndicator.getExportIndicatorId()));
					session.persist(aggregateIndicator);
				});
			}

			// Importando os anexos
			content = this.readFromFile(files, Attachment.class);
			List<Attachment> attachmentsList = this.gson.fromJson(content, new TypeToken<List<Attachment>>() {}.getType());
			if (!GeneralUtils.isEmpty(attachmentsList)) {
				attachmentsList.forEach((attachment) -> {
					attachment.setId(null);
					attachment.setLevelInstance(structureLevelInstances.get(attachment.getExportStructureLevelInstanceId()));
					final String authorEmail = attachment.getExportAuthorMail();
					final User author = this.userBS.existsByEmail(authorEmail);
					if (author != null) {
						attachment.setAuthor(author);
					} else {
						LOGGER.warnf("Ignoring unexistent attachment author: %s", authorEmail);
					}
					session.persist(attachment);
				});
			}

			// Importando os orçamentos
			content = this.readFromFile(files, Budget.class);
			List<Budget> budgetsList = this.gson.fromJson(content, new TypeToken<List<Budget>>() {}.getType());
			if (!GeneralUtils.isEmpty(budgetsList)) {
				budgetsList.forEach((budget) -> {
					budget.setId(null);
					budget.setBudgetElement(budgetElements.get(budget.getExportBudgetElementId()));
					budget.setLevelInstance(structureLevelInstances.get(budget.getExportStructureLevelInstanceId()));
					session.persist(budget);
				});
			}

			// Importando as instâncias de atributos
			final Set<String> emails = new LinkedHashSet<>();

			content = this.readFromFile(files, AttributeInstance.class);
			List<AttributeInstance> attributeInstancesList = this.gson.fromJson(content, new TypeToken<List<AttributeInstance>>() {}.getType());
			if (!GeneralUtils.isEmpty(attributeInstancesList)) {
				attributeInstancesList.forEach((attributeInstance) -> {
					attributeInstance.setId(null);
					attributeInstance.setAttribute(attributes.get(attributeInstance.getExportAttributeId()));
					attributeInstance.setLevelInstance(structureLevelInstances.get(attributeInstance.getExportStructureLevelInstanceId()));
					if ("Responsável".equals(attributeInstance.getAttribute().getLabel())) {
						User user = this.userBS.existsByEmail(attributeInstance.getLevelInstance().getExportResponsibleMail());
						if (user != null) {
							attributeInstance.setValue(user.getId().toString());
							attributeInstance.setValueAsNumber(user.getId().doubleValue());
						} else {
							if(!emails.contains(attributeInstance.getLevelInstance().getExportResponsibleMail())) {
								emails.add(attributeInstance.getLevelInstance().getExportResponsibleMail());
								LOGGER.warnf("Usuário responsável não encontrado: %s", attributeInstance.getLevelInstance().getExportResponsibleMail());
							}
						}
					}
					session.persist(attributeInstance);
				});
			}

			// Importando os campos de opções
			content = this.readFromFile(files, OptionsField.class);
			List<OptionsField> optionsFieldsList = this.gson.fromJson(content, new TypeToken<List<OptionsField>>() {}.getType());
			if (!GeneralUtils.isEmpty(optionsFieldsList)) {
				optionsFieldsList.forEach((optionsField) -> {
					optionsField.setId(null);
					if (optionsField.isDocument()) {
						optionsField.setAttributeId(documentAttributes.get(optionsField.getAttributeId()).getId());
					} else {
						optionsField.setAttributeId(attributes.get(optionsField.getAttributeId()).getId());
					}
					session.persist(optionsField);
				});
			}

			// Importando os cronogramas
			content = this.readFromFile(files, Schedule.class);
			List<Schedule> schedulesList = this.gson.fromJson(content, new TypeToken<List<Schedule>>() {}.getType());
			if (!GeneralUtils.isEmpty(schedulesList)) {
				schedulesList.forEach((schedule) -> {
					final Long oldId = schedule.getId();
					schedule.setId(null);
					if (schedule.isDocument()) {
						schedule.setAttributeId(documentAttributes.get(schedule.getAttributeId()).getId());
					} else {
						schedule.setAttributeId(attributes.get(schedule.getAttributeId()).getId());
					}
					session.persist(schedule);
					schedules.put(oldId, schedule);
				});
			}

			// Importando as instâncias de cronogramas
			content = this.readFromFile(files, ScheduleInstance.class);
			List<ScheduleInstance> scheduleInstancesList = this.gson.fromJson(content, new TypeToken<List<ScheduleInstance>>() {}.getType());
			if (!GeneralUtils.isEmpty(scheduleInstancesList)) {
				scheduleInstancesList.forEach((scheduleInstance) -> {
					final Long oldId = scheduleInstance.getId();
					scheduleInstance.setId(null);
					scheduleInstance.setSchedule(schedules.get(scheduleInstance.getExportScheduleId()));
					session.persist(scheduleInstance);
					scheduleInstances.put(oldId, scheduleInstance);
				});
			}

			// Importando as estruturas de cronogramas
			content = this.readFromFile(files, ScheduleStructure.class);
			List<ScheduleStructure> scheduleStructuresList = this.gson.fromJson(content, new TypeToken<List<ScheduleStructure>>() {}.getType());
			if (!GeneralUtils.isEmpty(scheduleStructuresList)) {
				scheduleStructuresList.forEach((scheduleStructure) -> {
					final Long oldId = scheduleStructure.getId();
					scheduleStructure.setId(null);
					scheduleStructure.setSchedule(schedules.get(scheduleStructure.getExportScheduleId()));
					session.persist(scheduleStructure);
					scheduleStructures.put(oldId, scheduleStructure);
				});
			}

			// Importando os valores de cronogramas
			content = this.readFromFile(files, ScheduleValues.class);
			List<ScheduleValues> scheduleValuesList = this.gson.fromJson(content, new TypeToken<List<ScheduleValues>>() {}.getType());
			if (!GeneralUtils.isEmpty(scheduleValuesList)) {
				scheduleValuesList.forEach((scheduleValue) -> {
					scheduleValue.setId(null);
					scheduleValue.setScheduleInstance(scheduleInstances.get(scheduleValue.getExportScheduleInstanceId()));
					scheduleValue.setScheduleStructure(scheduleStructures.get(scheduleValue.getExportScheduleStructureId()));
					session.persist(scheduleValue);
				});
			}

			// Importando as tabelas
			content = this.readFromFile(files, TableFields.class);
			List<TableFields> tableFieldsList = this.gson.fromJson(content, new TypeToken<List<TableFields>>() {}.getType());
			if (!GeneralUtils.isEmpty(tableFieldsList)) {
				tableFieldsList.forEach((tableField) -> {
					final Long oldId = tableField.getId();
					tableField.setId(null);
					if (tableField.isDocument()) {
						tableField.setAttributeId(documentAttributes.get(tableField.getAttributeId()).getId());
					} else {
						tableField.setAttributeId(attributes.get(tableField.getAttributeId()).getId());
					}
					session.persist(tableField);
					tableFields.put(oldId, tableField);
				});
			}

			// Importando as instâncias de tabelas
			content = this.readFromFile(files, TableInstance.class);
			List<TableInstance> tableInstancesList = this.gson.fromJson(content, new TypeToken<List<TableInstance>>() {}.getType());
			if (!GeneralUtils.isEmpty(tableInstancesList)) {
				tableInstancesList.forEach((tableInstance) -> {
					final Long oldId = tableInstance.getId();
					tableInstance.setId(null);
					tableInstance.setTableFields(tableFields.get(tableInstance.getExportTableFieldsId()));
					session.persist(tableInstance);
					tableInstances.put(oldId, tableInstance);
				});
			}

			// Importando as estruturas de tabelas
			content = this.readFromFile(files, TableStructure.class);
			List<TableStructure> tableStructuresList = this.gson.fromJson(content, new TypeToken<List<TableStructure>>() {}.getType());
			if (!GeneralUtils.isEmpty(tableStructuresList)) {
				tableStructuresList.forEach((tableStructure) -> {
					final Long oldId = tableStructure.getId();
					tableStructure.setId(null);
					tableStructure.setTableFields(tableFields.get(tableStructure.getExportTableFieldsId()));
					session.persist(tableStructure);
					tableStructures.put(oldId, tableStructure);
				});
			}

			// Importando os valores de tabelas
			content = this.readFromFile(files, TableValues.class);
			List<TableValues> tableValuesList = this.gson.fromJson(content, new TypeToken<List<TableValues>>() {}.getType());
			if (!GeneralUtils.isEmpty(tableValuesList)) {
				tableValuesList.forEach((tableValue) -> {
					tableValue.setId(null);
					tableValue.setTableInstance(tableInstances.get(tableValue.getExportTableInstanceId()));
					tableValue.setTableStructure(tableStructures.get(tableValue.getExportTableStructureId()));
					session.persist(tableValue);
				});
			}

		});
	}

	/**
	 * Recuperar Todos os arquivo do zip
	 *
	 * @param InputStream arquivo do upload
	 *
	 * @return List<File> lista de arquivos do zip
	 *
	 * @throws IOException
	 *
	 */
	private Map<String, File> uncompress(InputStream inputStream) throws IOException {
		Map<String, File> files = new LinkedHashMap<>(30);
		ZipInputStream zis = new ZipInputStream(inputStream);
		ZipEntry zipEntry = zis.getNextEntry();
		while (zipEntry != null) {
			final String filename = zipEntry.getName();
			LOGGER.infof("Reading zip entry: %s", filename);
			final String className = filename.split("\\.")[0];
			final File newFile = File.createTempFile(className, ".json");
			final FileOutputStream fos = new FileOutputStream(newFile);
			IOUtils.copy(zis, fos);
			fos.close();
			files.put(className, newFile);
			zis.closeEntry();
			zipEntry = zis.getNextEntry();
		}
		zis.close();

		return files;
	}

	private String readFromFile(Map<String, File> files, Class<?> clazz) {
		final File file = files.get(clazz.getSimpleName());
		if (file == null) {
			LOGGER.infof("Nenhum arquivo de dados para entidade: %s", clazz.getSimpleName());
			return "[]";
		}
		LOGGER.infof("Importing entity: %s", clazz.getSimpleName());
		try {
			final FileInputStream fis = new FileInputStream(file);
			final String content = IOUtils.toString(fis, StandardCharsets.UTF_8);
			fis.close();
			return content;
		} catch(IOException e) {
			throw new RestoreException(e);
		}
	}

	/**
	 * Adiciona arquivo no zip
	 *
	 * @param ZipOutputStream arquivo zip
	 *
	 * @param className       nome da classe
	 *
	 * @param content         json a ser salvo
	 *
	 * @throws IOException
	 *
	 */
	private void zipAdd(ZipOutputStream zos, String className, String content) throws IOException {
		LOGGER.infof("Writing JSON for %s...", className);
		ZipEntry entry = new ZipEntry(String.format("%s.json", className));
		zos.putNextEntry(entry);
		zos.write(content.getBytes("UTF-8"));
		zos.closeEntry();
	}

	public int getQuantity() {
		return quantity;
	}

	public int getPorcentagem(){
		if(getQuantityTotal()==0) {
			return -1;
		}
		return Math.floorDiv(100*getQuantity(), getQuantityTotal());
	}

	public int getQuantityTotal(){
		return quantityTotal;
	}

	public void setQuantityTotal(int q){
		quantityTotal = q;
	}

	public void resetQuantity() {
		quantity=0;
		quantityTotal=0;
	}

	public Archive listFilebyName(String fileName) {

		Criteria criteria = this.dao.newCriteria(Archive.class).add(Restrictions.eq("deleted", false))
				.add(Restrictions.eq("name", fileName));
		criteria.setMaxResults(1);

		Archive file=(Archive)criteria.uniqueResult();// this.dao.findByCriteria(criteria, Archive.class);

		return file;
	}
}


The Chuck Taylor is the world's first sneaker. At over 100 years old the Chuck Taylor Hi and Low are still America's most iconic sneaker. Dress them up, or wear them down, Chucks are a classic! Classic cotton construction with a vulcanized rubber midsole for comfort and durability.
The Converse Chuck Taylor All Star High Grade-School (Bosphorous Green/Bosphorous Green) is available at our store now. Welcome to buy and enjoy large discounts!


text:
Republican former Michigan governor endorses Clinton
Former Michigan Gov. William Milliken (R) is endorsing Hillary Clinton.
Former Michigan Gov. William Milliken (R) is endorsing Democratic presidential nominee Hillary Clinton.
"This nation has long prided itself on its abiding commitments to tolerance, civility and equality," Milliken said in a statement, according to the Detroit Free Press."We face a critically important choice in this year's presidential election that will define whether we maintain our commitment to those ideals or embark on a path that has doomed other governments and nations throughout history," he continued.
"I am saddened and dismayed that the Republican Party this year has nominated a candidate who has repeatedly demonstrated that he does not embrace those ideals."
Milliken said because he feels so "strongly" about the future of the country, he will be supporting the Democratic nominee over Donald Trump.
Milliken, who has endorsed Democrats in the past, joins a group of Republicans who have announced they don't plan to support their party's nominee.
Frank Lavin, who served as political director to former President Reagan, said Sunday he plans to vote for Clinton over Trump. In an op-ed published for CNN, Lavin called Trump an "emperor who wears no clothes."
"It might not be entirely clear that Hillary Clinton deserves to win the presidency, but it is thunderingly clear that Donald Trump deserves to lose," Lavin wrote.
Rep. Richard Hanna (N.Y.) became the first sitting GOP lawmaker to say he would vote for Clinton, and Rep. Scott Rigell (R-Va.) has said he plans to support Libertarian nominee Gary Johnson over Trump.
Photo Credit: Rawstory

redpajama_set_name: RedPajamaCommonCrawl


text:
'Timeless' 2×09/2×10: 18 Moments From "The General"/"Chinatown" We Can't Stop Talking About
Home » 'Timeless' 2×09/2×10: 18 Moments From "The General"/"Chinatown" We Can't Stop Talking About
Alyssa Barbieri
Is anyone still alive out there? Because I'm currently writing this article from my grave as days later I'm still grappling with the effects of Timeless' season 2 finale delivered with brute force.
That is how you deliver a season finale. A season finale with a cliffhanger that isn't simply shock value. There's intention and a plan behind it. There are questions left unanswered. There's a promise of so much more to come. There is so much more story left to be told.
Rufus isn't dead. He's just temporarily misplaced in time. Lyatt is endgame. Their journey is only just beginning. Jiya will not suffer for long. Rufus will be back, and she will find peace. Future Lucy and Wyatt are breathtaking. They're about to change everything as we know it.
There are no words for the epicness of Timeless' two-hour finale. It was emotional, thrilling, heart wrenching, frustrating, and far too short even for two hours. I refuse to believe that this is the last we see of Timeless. NB — Barry, if you're listening — please don't do anything stupid. You know you have to renew Timeless. Because if you don't, it'll cause pandemonium, and not the good kind. You know you have to renew Timeless. Because it's the right thing to do. So anytime now, really. We're ready.
Here are 18 moments from Timeless' breathtaking two-part season 2 finale, "The General" and "Chinatown," that we can't stop talking about:
1. Greetings, Future Lucy & Wyatt!
lyattgifs
*Enter Future Lucy and Wyatt looking like they walked straight out of Tomb Raider* "You guys wanna get Rufus back, or what?" Now THAT is how you cliffhanger. Everything changed in that moment. It was one of those literal jaw-dropping moments that is still talked about years later as the show evolves. You have to wonder what happened between Rufus dying *sob* in our time and the five(?) years it took for Future Lucy and Wyatt to find their way back to Our Lucy and Wyatt. They've finally found a way to go back into their own time! I am more than ready to bring my precious Rufus back to our timeline!
2. RUFUS IS NOT DEAD…HE'S JUST TEMPORARILY GONE.
Remember when I said I cried the hardest I ever had in 2×08? Well, obviously, Rufus' death brought forth a surprising amount of sobbing and dry heaving and was the hardest scene I've had to watch on this show. These writers are good. Just when we thought Rufus was in the clear — after Jiya shot his "killer" — Rufus was hit by one of Emma's bullets meant for Lucy. It raises the question that this show has asked for awhile: Is it fate or choice? Are some things just meant to be? Was Rufus meant to die? All I know is this: The Time Team will get him back. Screw fate. Rufus Carlin will live. #SaveRufus.
3. Wyatt Finally Admits His Feelings For Lucy: "I LOVE YOU."
and-i-believe-in-you
It's been a rough ride for Lucy and Wyatt this season. But, as Prince Charming once said, "True love is worth fighting for." This moment gives me hope for Lyatt. They're not giving up on each other. They're going to start over. They're going to rebuild their relationship — and Wyatt is going to have to work long and hard to earn Lucy's love back. And I really hope we get to see that. I love that Wyatt didn't expect anything in return. That's what I love about his character. He's not the same old guy, even when he f**ks up exponentially. He needed to say it because Lucy deserved to hear it and he finally stopped lying to himself. The fact that this moment, while about Lucy and Wyatt, also managed to incorporate Rufus was so damn beautiful that after I realized it I broke down in tears again. This was Wyatt telling Lucy that he loved yes long after he should've. Just like Rufus had told him to back in the season premiere. Wherever Rufus is right now — he's just temporarily missing — he's smiling and saying, "It's about damn time."
4. Jiya Breaks Down About Rufus: "He's alone and abandoned."
silvertons
While I sobbed my eyes until they were dry when Rufus died, I wasn't prepared for the scene between Jiya and Mason that hurt almost just as bad as Rufus' death. "He's alone and abandoned. No one to identify him, no one to bury him, no one to grieve him." This scene was so brilliantly acted by Claudia Doumit to the point where, for a moment, I forgot I was watching television. I felt her pain, I felt her despair, and I cried with her. Watching Jiya and Mason cry over losing Rufus, watching them embrace in their pain, and Jiya's plea of: "I can't lose you, too." It was all too much to bear. It'll be awhile before I can watch that again — and I'll always cry watching it.
5. Lucy goes after Emma: "What do you do to someone who has taken everyone that you love?"
Lucy Preston is the strongest person that I've grown to know on this show after this season. She has endured heartbreak and tragedy and faced every obstacle with grace and dignity and didn't manage to lose herself in the process. So the scene where she goes after Emma — ready to kill her — for killing Rufus and taking everything from her, it was so incredibly powerful. Lucy has lost a lot this season because of Emma: Her sister, her mother, Wyatt (to Jessica), and now Rufus. Lucy has every reason to kill this woman, and when she has the chance, she does pull the trigger. Only the gun is empty, which prompts a sensational fight between the two. But that moment where Lucy lets all of her rage and grief out…Abigail Spencer absolutely destroyed me.
6. Rufus Tries to Tell Jiya He Loves Her As He Dies.
kendrasaunders
Stab me in my f***ing heart, why don't you? Riya has become my everything, and watching as that was taken from me as Rufus was taken from us was truly heartbreaking. But watching Rufus' final moments — as Jiya and Wyatt held him and as Rufus tried to tell Jiya, one last time, that he loves her — I was a wreck. I couldn't see through the tears. I couldn't breathe through the tears. It took me a couple of times to watch the scene to really watch it because it was that level of emotion. Riya have stolen my heart this season, and it's their love for each other and how they're willing to sacrifice themselves for each other that gets me. Jiya was willing to stay in the past to save Rufus. Rufus was willing to die to make sure Jiya got home. MY EYES. THERE IS A BRANCH IN MY EYES.
7. Flynn Comforts Lucy After Fight With Emma & Rufus' Death.
wellwhataboutme
Sometimes we just need the comfort of someone who knows what we're going through. Someone that doesn't need to ask questions or fill the space with talking. That was what Flynn comforting Lucy was all about. I do not get a romantic sense in the slightest. We might be conditioned to view every male/female relationship that shows characters caring as romantic. But I have yet to get that vibe from Lucy and Flynn. But what I did get is this deep sense of care and concern from Flynn towards Lucy. These are two people that have both lost a great deal. Flynn lost his wife and daughter. Lucy lost her sister, her mom, and Rufus. Flynn, having read that journal and knowing that Lucy, feels connected through their shared loss. That moment isn't about romance. It's about their shared loss. Not everything has to be romantic.
8. Lucy Hugs Wyatt to Comfort Him.
katie-mcgraths
It's been a rough road for Lyatt this season, and this entire situation has left Wyatt in an impossible situation. He's not the first one to make a mistake. He would not have been the first one to put his faith in his lost loved one. If Lucy would've gotten her sister back, she'd have done the same. If Flynn has gotten his wife and daughter back, he'd have done the same. Wyatt's just the first to get the opportunity. I wouldn't be surprised if Flynn gets his chance next season. With that said, I loved the hug that Lucy gave Wyatt before everything went to shit. It wasn't meant to be romantic, but given everything that has transpired between them and the love they have for each other, it meant something. This was Lucy showing her support for Wyatt. This was Lucy showing that she still cares very deeply about Wyatt. And when Wyatt put his arms around her and pulled her closer, he was returning the sentiment.
9. Rufus & Jiya Reunited in the Past
stevesharington
There are no words to describe my Riya feelings this season, especially in this season finale, but I'm going to try my best. I appreciate how Rufus and Jiya were allowed to strengthen their relationship through ups and downs and realizations of what's important in life. Knowing Jiya was stuck in the past for three years, her reunion with Rufus made me feel all the feelings. Rufus' relief. Jiya's relief coupled with fear that he would die — because she saw this happen before in her visions. But the way they embraced…they were home. They're each other's home. There was something really beautiful about how they both showed just how much they love each other. Jiya was willing to stay in the past — alone — in order to ensure that Rufus would go on living. She refused to even entertain the idea…until he came back. And Rufus, well, he sacrificed his life to ensure that Jiya was able to return home.
10. Harriet Tubman is a badass.
c-sand
There have been so many amazing historical figures that have graced our screens on this beautiful show. I've loved getting to meet the strong women that have defined our history. And getting to meet and see Harriet Tubman in action was everything I could've wanted. The General was, as Rufus said, a badass that, more than most, deserved to get the happy ending we all wanted for her. But, as she tells Rufus: "My only desire is to live free. The rest will work itself out." It's the simple things in life we take for granted. It's the simple things in life Harriet didn't. It's why we need this show on television to remind us about our past and remind us of everything we have and to cherish it.
11. Carol Chooses Rittenhouse Over Her Daughter.
I knew that TImeless would aim for a redemption arc for Carol. I just didn't expect this. And, to be honest, I'm glad it played out the way it did. Up to this point, Carol remained loyal to one thing only: Rittenhouse. Even though she loved her daughter, I never doubted for a second that Carol would betray Lucy in their name. So it was fitting, as Carol was dying in Lucy's arms, for her concern to be about Lucy and Rittenhouse. She assumes that if she'd raised Lucy as Rittenhouse, things would be the way they should've been. It would've been what is right. Even to her dying breath, Carol proved that she cared more about Rittenhouse than her own daughter.
12. Harriet Tubman has visions!
c-sands
This was one of those Easter Eggs placed so beautifully in the story — even though it's something we'll never get to see pay off. As this episode focused on Jiya's finding answers about her visions, we learned that Harriet Tubman herself got visions! But not just the spiritual ones people get in their dreams. She saw the Time Team coming. Okay. But, get this, she saw them coming out of a big silver ball. UM WHAT. I need to know more about these visions: How does someone like Harriet Tubman get them without time machines? I NEED ANSWERS.
13. Emma Kills Carol and Nicholas.
loisslane
Emma is having none of anyone's crap. She's a villain with a purpose, and her purpose is to end the Time Team and carry out whatever she deems fit for Rittenhouse. She's got time for nothing and nobody. She makes that clear as Carol prevented her from killing Lucy. She shot Carol several times. She makes that clear as Nicholas objects. She shoots Nicholas. Emma was having none. Of. It. So now she's sorta the leader of Rittenhouse, which is a hell of a lot more terrifying than Nicholas leading things. Just saying.
14. Wyatt and Flynn Fight Side-by-Side.
onlymorelove
Wyatt and Flynn do not like each other. Never have. Most likely never will. Things got especially tense this season once Jessica returned, and Flynn took every chance to remind Wyatt that Lucy isn't his wife. Almost like Flynn was the older brother teasing his younger brother. While we saw the two finally have it out earlier in "Chinatown," when it came down to protecting the team, they put their game faces on. They fought side-by-side as soldiers and allies to give their friends a chance to escape. You have to admire that when it comes down to the serious, they fall in line. No questions asked.
15. Jiya Gets the Most Out of Her Bed Sheet.
Jiya is a badass with a brain. She's also a badass when it comes to escaping the villainous clutches of Rittenhouse with nothing other than a bed sheet. As Jiya was being held prisoner
by Rittenhouse and drugged, she managed to use her smarts and physical strength (go girl!) to fool a Rittenhouse worker into opening her door, strangling him with a bed sheet, and breaking his neck all as she escaped into the Lifeboat and away from Rittenhouse. JIYA IS THE BADASS.
16. Jessica Is Still Lying About Her Pregnancy.
silvetons
Look, I don't care what that Rittenbitch says. She's not pregnant. And that's not Wyatt's baby. There's no way she's not lying. She was drinking alcohol shortly after kidnapping Jiya. She was using it manipulate Wyatt. But say, on the off chance she is pregnant, it's not Wyatt's. Not this Wyatt. Maybe the Wyatt she knew that wasn't the Wyatt we know. But our Wyatt isn't the father. Because math makes too much sense.
17. Wyatt Stays With Rufus As He's Dying.
There's no BROTP like Wyatt and Rufus. They're brothers through and through. They've been through many troubles and come out stronger for it. So following their argument before Chinatown and after Rufus was shot and dying in the street, there was no way Wyatt could've left his side. While the Lyatt shipper in me wanted Wyatt to run after Lucy as she ran into danger, the Wyatt/Rufus in my loved it so very much that Wyatt didn't leave his side. This is his best friend, and he was not going to leave him dying without him by his side.
18. CAN WE TALK ABOUT THE ENDING AGAIN?
As far as cliffhangers go, that's about as EPIC as cliffhangers get. Where it's the idea of the possibilities that can come from it more than the initial shock value of it. This is how good cliffhangers are done. I NEED ALL THE ANSWERS. I WILL NOT BE ABLE TO GO ON LIVING WITHOUT MORE TIMELESS.
What were your favorite moments from Timeless' season finale?
Tags abigail spencer Chinatown Claudia Doumit Lyatt Malcolm Barrett matt lanter NBC Riya The General Timeless TV
Alyssa is the Managing Editor for Bears Wire. You can reach her at alyssaabarbieri@gmail.com or follow her on Twitter @AlyssaBarbieri
'The Flash' 4x22 Review: 'Think Fast'
From The Upfronts: 'Murphy Brown' Making Her Comeback
Fangirlish Feels of the Week: January 21 – January 27
'Law & Order: Organized Crime' 3×12 Review: "Partners In Crime"
'The Last of Us' Renewed for Season 2 & We're Already Terrified
'National Treasure: Edge Of History' 1×07 Review: 'Point Of No Return'


We do not know the exact origin of this variety, which bears the name of the city of Hamburg, where grapes were once grown in greenhouses.
From there, this Muscat travelled to England where it enjoyed considerable success from 1860.
A blue-black colour with purple tints, this is a round grape, scented and very sweet, offering a juicy flesh with a musky taste.


text:
Ollie to miss the CC Final
Free State Cheetahs prop Ollie le Roux will not be playing in the Absa Currie Cup Final, when his side meet the Golden Lions in Bloemfontein next Saturday, October 27.
The veteran front row forward on Monday revealed that the curtain has already come down on his South African career, with his last game having been when he came on as a replacement for the Cheetahs in their 11-6 semi-final win over the Blue Bulls at the weekend.
The 34-year-old Le Roux said he will be leaving this week to start a one-year deal with Irish province Leinster.
"My final game was on Saturday, I'm leaving on Wednesday for Dublin," Le Roux said.
"I've already had my last game, which is a bit of a pity I suppose."
Le Roux went on to say that the highlight of his career had been the 2005 season with the Cheetahs, when the side – who had come into the Currie Cup competition as underdogs – won the tournament for only the second time in their history.
"My whole experience with the Sharks [over 100 games] was incredible and there have been a lot of great games over the years. There have been so many highs, with the last season at the Cheetahs really adding shine to my time as a player in South Africa.
"The past two-and-a-half years with the Cheetahs have been great and it's sad to be leaving, but I'm looking forward to the new challenge."
Le Roux will arrive in Ireland with an impressive resume that includes 68 Springbok Test caps and over 250 first class games – in which he scored nine tries and even kicked a conversion.
After playing for the South African Schools team in 1991 and '92, he made his first class debut for the Cheetahs (then still just Free State) against Northern Transvaal (now Blue Bulls) in 1993. He made his Bok debut that same year.
By Gareth Green 365 Digital
← Previous Story Venter backs Lions in Final
Next Story → Boland rugby turns violent again


'Immigration has shaped the Australia we know today, it has made a strong Australia and will make a stronger Australia in the future. Immigration has been our past and has forged our present. The same challenges those who arrive today were faced by our ancestors. Leaving the place they knew, leaving the culture they knew. Coming to something which is uncertain, having to break into a new economy, a new way of life. To leave baggage behind and pick up new opportunities. Whether you did it in 1788 or you did it last week, the same human challenges present and the great story of immigration in Australia is it is a success.


My eight year old son was diagnosed at age two and one-half. His blood sugar is in fairly good control, but there are days when it bounces from low (68 mg/dl [3.8 mmol/L]) to high (300s mg/dl [16.7 mmol/L]) in a matter of four hours. We follow his diet and insulin regimen very carefully, adjusting when necessary, but these unexplained crazy days really have us baffled. No medical or emotional problems are evident. Help!
Daily fluctuations of blood sugar levels in an eight year old child with type 1 diabetes are often unpredictable. Besides the classical issues concerning insulin, food and exercise, some other issues could be active: variations of absorption of insulins from the different injection sites, different waiting times among meals, varying before-meal blood sugar levels, glycemic indexes of different foods, etc. Anyhow, these fluctuations are not dangerous if not frequent, and if the average HbA1c levels are fine.


Mito outplayed Tokyo Verdy in all ways but the one that counts. Since soccer isn't scored on judging, it's another loss and another three points in the divide between Mito and the rest of the field.
Unfortunately I couldn't see most of the game live because there was a massive crowd that filled Hitachinaka's stadium to beyond capacity. Since I was working the gate, I was going hard trying to keep nearly 4,000 fans in order going in and out of a single gate. There was too much to do until the final 10 minutes or so, unlike Kasamatsu which usually can allow watching from whistle to whistle. I had to see the recording at home late night after finishing stadium work.
Speaking of that crowd, the final number reached over 5,500 in a stadium that seats 5,000. (Well, "seats" are only in the higher priced section...) It marks the first time in 2007 that Mito's fan count was higher than another J. League game, and was in fact more than twice the size of Ehime's home game against Tokushima.
After the game, in the locker room area, I talked with a few Japanese players from both teams and tried to do the same with Hulk, but there was a language barrier there. As I headed back into the main hall from the locker room area, Tokyo coach Rui Ramos came out of the press room and walked just beside me. He seemed kind of shocked to see a white guy working in the back for Mito and after a brief exchange of greetings and the equivalent of "good game" on both sides, I wished him luck for the future. He honestly came off as very nice and personable, but then again he had just won a hard game against a team that had embarrassed him in the last meeting. He seemed in a hurry to leave so I resisted the urge to ask for a picture. I also resisted the urge to ask why he pitched a tantrum on the sidelines after his keeper refused to hold the ball at the end of the game. It was probably for the best.
He walked out of the front door to the waiting Tokyo fans who waited for player pictures and autographs. They were rabid and happy just to see them in person. On one hand, I was jealous that Tokyo had a fan base so rabid as to wait more than an hour just to see the players get on the bus. On the other, I felt bad for that fan base that the players seemed so inaccessable and untouchable, as if on a pedestal. I realized that different fan bases enjoy different teams in different ways. Mito's fans feel that they are closer to the team and know the players personally, supporting them one-on-one in addition to as a group. The downside is that if the team loses, the supporters don't just feel bad... The fans feel like losers, too.
After my roles were finished and I waited for the rest, those of us who were waiting grabbed a ball and headed out to the field, still pockmarked from the steps and slides of the match, and played around for a bit. A couple of others stood where the Tokyo front line had been less than two hours earlier, while I took goalkeeper Takeda's spot. Although I wasn't up against the top scorer in the division, I wish that Takeda had been as successful as I was for those few minutes.
Around three hours after the final whistle, I finally was able to head back to my car to make the drive home. As I put the key into the ignition, the lights on the field went out, and the first half of the season went dark. While no team can be mathematically eliminated from promotion at this point and thus hope must remain, it is clear that Mito is likely is headed to one of its worst season records ever despite playing some of its best quality games. I pondered that for a moment and came to the realization that it didn't matter. I feel so lucky to have this team and plan to do all I can to help it as much as possible.
I just kind of wish the wins would come along a little more often.
can I repost this on Soilent green?


text:
Q: how to present a user-defined widget in QTableview's cell (without using qml) These days I encounter a problem about qt.
There is a batch data which I want to show in my qt application with QTableview(not qml gridview, since my application use widgets). Each data item include a image and a image name. I need to let the image displayed on a qlabel and it's name displayed on another qlabel. These two widgets should be showed on  my self-defined frame. And then I will let the user-defined frame displayed in each QTableView's cell.
From BigBourin(who also ask the similar question), I know i should implement a self-defined delegate, and reimplement the painter function, just like this:

void PackageListItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index ) const
{

// here we have active painter provided by caller

// by the way - we can't use painter->save() and painter->restore()
// methods cause we have to call painter->end() method before painting
// the QWidget, and painter->end() method deletes
// the saved parameters of painter

// we have to save paint device of the provided painter to restore the painter
// after drawing QWidget
QPaintDevice* original_pdev_ptr = painter->device();

// example of simple drawing (selection) before widget
if (option.state & QStyle::State_Selected)
    painter->fillRect(option.rect, option.palette.highlight());

// creating local QWidget (that's why i think it should be fasted, cause we
// don't touch the heap and don't deal with a QWidget except painting)
PackageListItemWidget item_widget;

// Setting some parameters for widget for example
    // spec. params
item_widget.SetPackageName(index.data(Qt::DisplayRole).toString());
    // geometry
item_widget.setGeometry(option.rect);

// here we have to finish the painting of provided painter, cause
//     1) QWidget::render(QPainter *,...) doesn't work with provided external painter
//          and we have to use QWidget::render(QPaintDevice *,...)
//          which creates its own painter
//     2) two painters can't work with the same QPaintDevice at the same time
painter->end();

// rendering of QWidget itself
item_widget.render(painter->device(), QPoint(option.rect.x(), option.rect.y()), QRegion(0, 0, option.rect.width(), option.rect.height()), QWidget::RenderFlag::DrawChildren);

// starting (in fact just continuing) painting with external painter, provided
// by caller
painter->begin(original_pdev_ptr);

// example of simple painting after widget
painter->drawEllipse(0,0, 10,10);
};

my question is item_widget.SetPackageName(index.data(Qt::DisplayRole).toString());
the data come from where? can the data be user-defined data class?

redpajama_set_name: RedPajamaStackExchange


Suburban Veterinary Clinic believes that dental care is as important for your pet as it is for you. We have 2 fully equipped dental stations that feature ultrasonic scalers as well as hand scaling of teeth followed by thorough polishing.
Every dental procedure receives pre-anesthetic medication, a comprehensive oral exam, IV catheter, supportive fluids and full anesthetic monitoring by a licensed veterinary technician.


text:
How To Build an App Like Ola? Tips from Taxi App Developers
30.10.2017 Pavel Сherniavskiy
City traffic can drive anyone mad. If you have ever been in a frantic rush to a meeting across the city without a car of your own, you may know what we mean. Rejoice—an effective change has happened in India to avoid these inconveniences—Ola cab services.
How Ola Cabs Started
Ola is an on-demand taxi-hailing service that enables people to book a cab with a smartphone. Ola provides a platform for car owners to work and earn a decent living. As of Last Fund Raise the company was valued at more than 5 billion USD.
Ola, said to be India's most popular mobile app for cab booking, was launched on 3 December 2010 in Mumbai to solve the city's transportation problems.
In November 2014, Ola diversified to incorporate autos on a trial basis in Bangalore. After the trial phase, Ola Auto expanded to other cities like Delhi, Pune, Chennai, Hyderabad, and Kolkata in December 2014. In December 2015, Ola expanded its auto services in Mysore, Chandigarh, Indore, Ahmedabad, Jaipur, Guwahati, and Visakhapatnam. Ola was valued at 5 billion USD in September 2015.
As of 2017, the company has expanded to a network of more than 600,000 vehicles across 110 cities.
According to Truecaller, Ola Cabs made 42.5 million calls to its users, and 59.5 million calls were made by users, which accounted for 102 million calls between Ola Cabs and its users. Uber users received 13.6 million calls from the company and called the company 25.4 million times, for a total of 39 million calls.
The business model works on a very simple concept. OLA Cabs acts as a facilitator to provide cab services to customers through multiple channels. Customers can book cabs through the website, call center, or a popular app. OLA does not own any of the cabs. Only drivers with valid permits duly authorized and verified by transport authorities can sign up to drive for OLA and they can be either self-employed or work for an operator who owns multiple cars.
How Does Ola App Work?
As stated earlier, Ola has been through its own set of ups and downs, pivots and U-turns with respect to its Business and Revenue Model. The company started out as a taxi rental fleet business (the company owned the fleet). They had a call center that used to handle bookings for customers who wanted cabs. It was similar to Meru Cabs and others ( it was basically Radio Taxi, but it was unbranded and available on an 8hr 80 km type of billing). But later, the company pivoted to an app-based cab aggregation service, and the rest is history.
Ola offers two sides to its applications, one for passengers to choose a ride, and another for drivers to accept the requested ride. Once the ride is chosen by a passenger from his/her location, the drivers nearby will get information through their app. The driver who accepts the ride will pick the passenger up from his or her location, and at the end of the ride, the passenger pays for the ride. Ola supports both cash and cashless payment options with Ola money, credit, and debit cards. So how can an app like this be made? There are three key features that need to be considered:
Passenger App
Ola Passenger's App Features
You can directly register in the app using your social media profile or create a new one.
There are three types of booking: full day booking, advance booking, and normal booking. In full day booking, drivers can be hired for an entire day. With advance booking, a passenger can request a booking for a future time. Normal booking sends a request to all nearby drivers, and the driver app shows a call screen with a passenger review, stars, and pickup and drop-off addresses. Drivers will receive a call, and when the driver accepts the passenger, the passenger will see that a driver is coming on the map.
Adding this feature allows passengers to register their app and provide auto payment directly from the app.
This feature shows all the information about a trip when the driver accepts the request. It also contains the vehicle information such as model, passenger count, color, number of the car, and the estimated time of arrival.
Ride History
Shows a complete transcription of previous trips.
Fare Calculator
Helps calculate the cost of the trip.
Driver's review and rating
Shows customers' comments about the driver, his or her car, and the trip safety according to other passengers.
By using the built-in GPS module, you can pinpoint your exact location without typing an address.
Split Payments
Provides an option to separate payments among several passengers.
Provides an opportunity to choose another driver for the trip.
Interactive Map and Taxi Tracking
Shows all the cabs nearby and tracks the driver during the journey in real time.
In Chat, the passenger can chat with drivers and send them regular messages or audio messages. The passengers can also chat with multiple drivers.
This allows boosting customer acquisition and retention with badges, special offers, leadership boards, etc.
Gives a discount on trips by adding a code or digital coupon.
Enables the use of voice commands to hail a taxi.
Driver App Features
Some of the driver's app features will duplicate the passenger's—login, push notifications, support, and messaging.
Driver profile and status
Drivers are required to provide extra verification, e.g., their license and tax number, when they register. The status functionality should help them adjust their availability and schedule.
Order alert
Sends a push notification and information on the new booking—payment, route details, etc. It should also allow accepting and cancelling orders.
Suggests the best route for the passenger.
States the order price with discounts (if available).
Offer a quick glance at trip stats, earnings, and payroll.
The backend is for the driver, user, and ride stats and reports. It consists of three parts: the server, an application, and a database. You can file complaints against drivers or see active drivers. It allows you to see a live feed of events, and it has an integrated email system as well.
Backend App developed by VironIT
Backend allows one to:
Manage driver and customer accounts
Track booked rides
Observe driver movement through GPS system
Provide backup in case of a failure
Flag driver areas, i.e., boundary division
Assemble overall history and all data
Manage transactions
Add or remove vehicles
Examine valid driver and vehicle info
What is Ola technology stack?
So here's a question for you: on what technologies does Ola rely? Here is the basic technology stack used for many Ola apps:
Application and Data
TrackJS
If you want to receive a full tech stack for an Ola-like app, please do not hesitate to contact us at info@vironit.com.
How much money does Ola make?
Their revenue model is similar to Uber's with a couple of additions. The most significant contributor to Ola Cabs' revenue model is X% Commission from the total fare of the trip. It ranges from 15% to 20% depending on the city and type of vehicle. Ola, Uber's biggest competitor in India, received a total equity funding of $903 million and is currently valued at $5 billion.
Most of the money earned by Ola goes to anti-fraud efforts, credit-card processing, customer support, marketing, and software development.
The trip fare is a combination of:
Travel Time (In Minutes): Ola charges per Minute of Travel Time after X initial free minutes
Distance Cost: Ola charges Per KM of Travel after an initial fixed fare Distance (varies based on the type of cab)
Waiting Time: If you make the driver wait, additional waiting time charges are levied
Service Tax on the total trip fare
Assuming Travel Cost Per Minute: 5 INR (Travel time 40 mins)
Assuming Travel Cost Per KM: 15 INR
Assuming Service Tax: 14.5%
How much does it cost to build Ola?
If you are planning to develop an app like Ola, you must first realize its development cost. The cost depends on the following:
iOS and Android native app development
According to estimates of similar projects, on the low-cost side, a very basic, stripped down version of an app similar to Ola could cost between $15,000 and $35,000k to get an initial version of the product to market. A more robust app could cost more and completely depends on the designs and features you want to incorporated in the application.
Feel free to contact us to ask for a strategic session with our business analyst.
Where else can be an Ola-like app used?
This taxi app may not only prove helpful for transport companies like Ola or Uber but for other businesses too. For example:
The company can use a taxi app for its internal services like tracking the goods from the warehouse to the store. That way, the application can be useful tracking the driver in route. Contact details and tracking can also be automated.
The healthcare industry is that which needs to sync riders and drivers to the large extent.
The hospitality industry can thrive with the automation advances of taxi apps. The customers are better served by digital services in this digital world.
Have a plan to develop an Ola-like service? If so, you are in the right place. We at VironIT, a software development company, are here to help you launch superior quality iPhone and Android apps that will take your business to the next level.
Please, rate my article. I did my best!
Stay tuned. Monthly digest of the best stories.
Biometrics software development for business
The website development process: 7 steps to success
How to Create a Social Media App?
7 responses to "How To Build an App Like Ola? Tips from Taxi App Developers"
Rajesh Gosvi says:
It will definately help us to build app like OLA & earn money.
It's amazing for me to have a website, which is helpful for my experience. thanks, admin
Hi! This is kind of off topic but I need some guidance
from an established blog. Is it hard to set up your own blog?
I'm thinking about making my own but I'm not sure where to
begin. Do you have any tips or suggestions? With thanks
stefaniemerriam says:
I'm extremely impressed together with your writing abilities and also with the structure to your blog. Is this a paid theme or did you customize it yourself?
Anyway keep up the excellent quality writing,
it is rare to peer a nice blog like this one nowadays.
marcelakulikowski says:
Ahaa, its fastidious dialogue about this article at this place at this web site, I have read
all that, so at this time me also commenting at this place.
kylelittler says:
I am in fact glad to glance at this webpage posts
which includes tons of valuable information, thanks for providing such data.
johnettecameron says:
This is really attention-grabbing, You are a very skilled blogger.
I have joined your rss feed and stay up for in quest of extra of
your great post. Additionally, I've shared your site in my social networks


text:
Gabriel Kreuther
Gabriel Kreuther NYC
One of New York City's most celebrated chefs, James Beard award-winning and Michelin-starred chef Gabriel Kreuther offers delicious fare and impeccable service with a distinctly New York spirit at his eponymous restaurant, Gabriel Kreuther and its neighboring chocolate shop, Kreuther Handcrafted Chocolate.
A native of Alsace, France, Kreuther was born in a region whose history has produced one of the most renowned cuisines in France. Raised on a family farm in Niederschaeffolsheim, a small village north of Strasbourg, Kreuther grew up surrounded by fresh local produce and seasonal game and first learned the art of... READ MORE
A native of Alsace, France, Kreuther was born in a region whose history has produced one of the most renowned cuisines in France. Raised on a family farm in Niederschaeffolsheim, a small village north of Strasbourg, Kreuther grew up surrounded by fresh local produce and seasonal game and first learned the art of traditional Alsatian cuisine by cooking with his mother. During school vacations, Kreuther often visited his uncle, who owned a bustling hotel and restaurant in the nearby mountains, and at barely 12 years old, Kreuther helped out everywhere, soon discovering the kitchen.
In 1984 he enrolled in culinary school at École Hôtelière in Strasbourg, where he began his formal education and in 1987, won the prestigious "Concours National du Meilleur Apprenti Cuisinier de France – Fernand Point," a highly competitive national contest that determines the "Best Kitchen Apprentice in France" from among 170 nominees.
After embarking on a work-exchange program in Washington D.C. and working his way up the ranks of Michelin-starred kitchens in Germany, France, and Switzerland, Kreuther arrived in New York City in 1997, where he worked as sous chef at the much-lauded La Caravelle before becoming chef de cuisine at Jean-Georges. In 2002, Kreuther assumed the role of executive chef at Atelier at the Ritz Carlton's iconic Central Park South location, during which time he was named one of Food & Wine Magazine's "Best New Chefs." Under Kreuther, the restaurant was also nominated for "Best New Restaurant" by the James Beard Foundation, received a three-star rating from The New York Times, and also received The American Academy of Hospitality Sciences' coveted "Five Star Diamond" award.
In 2004, Kreuther joined Danny Meyer to open The Modern, where his cuisine garnered the restaurant critical acclaim and numerous accolades including "Best New Restaurant" from Esquire Magazine, one Michelin star, the title of "Top Rated Newcomer 2005" by Zagat Survey, and "Best New Restaurant" by Time Out New York. The Modern also received a glowing three-star review from The New York Times, and the 2006 James Beard Foundation Awards for "Best New Restaurant" and "Outstanding Restaurant Design." Having been nominated in 2006, 2007, and 2008, Kreuther himself won the James Beard Foundation Award for "Best Chef: New York City" in 2009.
After nearly a decade as executive chef of The Modern, he moved on to open Gabriel Kreuther in June 2015. Here, Kreuther combines his classic French training with his love of New York City dining to create a comfortably luxurious experience in the heart of Midtown Manhattan. Since opening, Gabriel Kreuther has received three stars from The New York Times and has been awarded two Michelin stars. In March 2017, the restaurant joined the distinguished list of Relais & Chateaux properties. In January 2020, the restaurant was inducted into the prestigious les Grandes Tables du Monde association.
In November 2016, Kreuther teamed up again with Gabriel Kreuther pastry chef Marc Aumont to open Kreuther Handcrafted Chocolate right next door to the restaurant. Here, guests can select from a dynamic menu of freshly made chocolates inspired by everything from the changing seasons of New York City to classic American flavor combinations.
When Kreuther isn't in the kitchen, he is a member of the Bocuse d'Or Culinary International Counsel, and was proud to be part of the 2015 coaching team for the silver medal-winning United States team and mentor for the 2017 gold world championship team.
Dinner at Gabriel Kreuther NYC with Gabriel Kreuther
sponsored by Caymus Vineyards


Do you adore stylish collars? Allow your beloved pet enjoy wearing such accessories on! Purchase this finest quality leather dog collar with studs from FDT Artisan. This gear is designed for those who just love fashion style. In this stunning collar, your doggie will have more strict, but beautiful look. Your cute four-legged friend will get the best treatment when wearing this collar. Full grain genuine leather is flexible and absolutely eco-friendly.
Chrome plated D-ring will stand out even the strongest pet pulling. Breathtaking adornments are chrome plated and have superior shining. Point up your dog's style, buy this Artisan exquisite natural leather accessory!
Full grain natural leather was chosen to provide maximum comfort and safety while wearing. The material is carefully oiled that saves it from cracking. Among the best features of full grain leather are perfect adjustability, tear-resistance and strength. The layer of leather is quite thick that prevents the tool damage. It helps you to walk even big and tough dog safely. Rounded and smooth edges of the FDT Artisan collar are non-cutting and don't rub the pet's skin. Besides, genuine leather doesn't include any toxic elements being absolutely eco-friendly.
Look at the adornments, they are exclusive! Catchy studs are set along the leather strap. These studs are chrome plated and, thus shine with stylish glittering. The decorated design of this gear is inimitable and individual. Due to these studs, this full grain leather dog collar has a spark. That means your canine will have his individual and exquisite style.
As for the hardware of this embellished natural leather accessory, it is chrome plated. It matches perfectly with the studs. This covering provides the best protection for the details as it prevents rust. The set of hardware includes a classic elegant buckle and durable D-ring for leash attachment. These fittings are easy to use and reliable in service they provide. Add more zest to your four-legged friend's outlook, order this attractive leather collar!
When ordering this studded dog collar, you will get a gift package along with it! Don't miss your chance to praise your impressive dog with unique collar made of full grain leather. This is an unique offer available for our customers! A gift package makes your order look like a present for the pet.


Posted on September 22, 2014. Brought to you by judysbook.
We are naturopathic holistic healers working with you body to help it overcome its shortcomings. We work with you on all major health issues including anxiety, dementia, alzheimers, Parkinsons, pain, osteoporsis, arthritis, digestive issues, allergies, infertility, cancer, nutrition, CFS, and many others.
We specialize in doing extensive research to find the latest advances of functional, proven healing techniques and substances. for example, we use pulsed electro magnetic frequencies to heal the most complex issues. Naturally, we use only high quality laboratory tested products to ensure that you get what you expect and avoid any product contamination so common today.


JM Envirofuels, part of the Jack Moody Group was formed in 2005. and is based near Wolverhampton, with depots throughout the West Midlands and Shropshire.
Jack Moody Group, was formed in 1963, began recycling timber in 1996. When, in late 2000, the wood fuel market emerged in the UK, the company began to develop recycled wood fuel products specifically for heating and power generation.
The company has subsequently become a key player in the wood fuel market, not only in the Midlands, but nationally, with annual sales of over 100,000 tonnes, and an expanding customer base. In addition to our clean recycled fuel, we also offer fuel made from virgin timber, for those customers who may prefer it.
The primary aim of JM Envirofuels, as with all of the group companies, is to develop long-term relationships with our customers by offering exemplary products and service, throughout the UK.
We have been processing wood products since 1996, with experience and a track record which is second to none.
We fully understand the importance of fuel quality - we use wood fuel ourselves at our own premises.
We have secure and long-term access to hundreds of thousands of tonnes of woody biomass material suitable for conversion into fuel.
We have a vehicle fleet 99 strong, which includes wood chip blowers and wood pellet delivery tankers, managed by an experienced transport management team and with friendly, helpful and knowledgeable drivers.
We have a strong sales management and administration team.
We are a secure and profitable business which has invested heavily in wood fuel and is, therefore, committed to the long-term satisfaction of our customers.


If you're committed to making big paydays from your online marketing efforts (instead of dribs and drabs of income), then giving new leads and customers a phone call is a great way to sell high-ticket products and services—and make big sales you would not otherwise have.
What keeps a lot of people from doing this is that it can be very uncomfortable—but mostly when you're doing it wrong. When it's done right, it's less frustrating and very rewarding. And once you see the results, you'll get even more motivated to keep it up.
To help you earn as much as you can from phone sales, I have a few tips for you that I've learned while training and watching our own team of phone salespeople in action.
Once you've been notified of a new lead or sale, research shows that the faster you respond, the more likely it is you will close a sale. This is because if you take too long, people will forget what they asked for, lose interest, or get in touch with your competitors instead.
Don't lose the sale to the other guys! Marketing research shows that responding within 7 minutes, when possible, will maximize your chances of success. Set the habit of getting back to people quickly.
Also, the best times of day to contact people by phone are 8:00 – 10:00 in the morning and 2:00 – 5:00 in the afternoon. Between 7:00 – 9:00pm is also a good time to reach people at home. Schedule blocks of time for phone calls when people are available, and make your callbacks or prospecting calls then.
Remind them what they saw on your website and what they bought or opted-in to receive. It's funny, but people quickly forget! Let them know in a straightforward manner you're getting back to them to answer any questions they have, to personally thank them, or to give them the information they need.
You don't need to dominate the conversation or be afraid of the prospect and what might go wrong. Remember, they contacted you about something they want.
So relax and keep your cool. Just have a straightforward conversation with them as you would with a friend. If you appear too nervous, people get suspicious or skeptical and that can damage your sale.
Another ninja tip is to speak in the same tone of voice and pace as they do. This is called mirroring and matching. If someone speaks quickly, they probably don't want to waste time and will respect you more for doing the same (people like those who are similar to them). The same is true for people who speak slowly. Try it and see!
There's not much to say or sell until you find out some important information from them first. Then, you can tailor your responses to be as effective and relevant as possible.
Ideally, you and your prospect will both be speaking 50% of the time. Get them talking by asking questions, such as confirming their reason or motivation for contacting you or placing an order with you in the first place.
Learn their story. Then you'll know what to say and how to say it when it's your turn to speak and persuade.
Once you've made a connection, built rapport, and found out their motivations and needs, now is the time to make suggestions to them.
You can recommend more information, a front-end product that's ideal for their situation, or begin to describe how purchasing a high-ticket product or service such as a course, seminar, coaching, or mastermind group can help them get what they want (and change their life).
So there's the basic structure of each phone sales call you make. I see it work over and over again as I watch my own salespeople call my new leads and sell our higher-ticket programs.
Speaking of which, if you still don't quite feel like spending the time and energy calling prospects yourself, my phone team can make the calls and close sales FOR YOU…with you standing to make $1,000, $3,000, or $5,000 each time.
For more details on how to enroll in our Done-For-You marketing system to promote high-end products click below..


Have you seen missing Gary Sanders?
Police are growing increasingly concerned for the welfare of missing Gary Sanders from Huntingdon.
Gary, 43, who was last seen in Huntingdon town centre, has not been seen since 2:30pm on Wednesday, December 23.
He is believed to be wearing a Lee Cooper black coat, a black t-shirt and dark jeans.
Anyone who may have seen Gary or knows of his whereabouts is asked to contact police on 101.
We would also appeal directly to Gary to get in touch to let us know he is okay.


"It's the perfect medium for fine-art printers and photographers. It has every feature our customers have been asking for in a canvas ? image fidelity is top-notch, it's easy to finish, and, like all of our Sunset fine-art materials, it meets the Fine Art Trade Guild Standards for Limited Edition Prints," said Alex Ried, LexJet's product manager.
LexJet Sunset Select Matte Canvas can be stretched, mounted, or finished with grommets. It is compatible with popular dye- and pigment-based inkjet printers, including Epson, Roland, Mimaki, Hewlett-Packard, Canon, ColorSpan, and Encad.
"The high-quality, water-resistant poly cotton blend features an unsurpassed white point, and an inkjet coating that's pH neutral and acid free for consistent and accurate printing," explains Chris Cudzilo, LexJet's vice president.
LexJet's new 11 mil Sunset Photo eSatin 300g paper answers photographers' requests for a heavier, more substantial photo paper, with excellent ink retention characteristics and a color gamut that is second to none. This paper maintains a traditional E surface finish, providing an elegant texture consistent to that of a dark room.


text:
Arquivos de tags: sceptic
Vaccine sceptic NFL star Aaron Rodgers denies having 'Covid toe'
The Green Bay Packers quarterback had appeared to suggest his foot injury was related to his Covid infection, but on Wednesday he held up his foot to cameras to prove that was 'disinformation'
American football player and vacina sceptic Aaron Rodgers has denied claims that he has "Covid toe" and insisted his foot injury has nothing to do with coronavirus.
The Green Bay Packers quarterback, who refused to be vaccinated against Covid-19 and recently returned to play after becoming infected with it, had appeared to suggest in interview with radio host Pat McAfee on Tuesday that his injury was Covid-related.
But in a press conference on Wednesday, he said that comment had been a joke and that the real cause was an ordinary fracture, holding up his foot to show reporters that it was seemingly free of lesions.
"Covid toe" is a colloquial name for chilblains or inflammations on the toes, sometimes suffered as collateral damage from the immune system's battle with coronavirus.
"Oh! Oh, there's no lesions whatsoever! Oh, what a surprise!" said the 37-year-old sarcastically as he bared his sole for the cameras. "Não, that's actually called disinformation, when you perpetuate false information about individuals.
Qual é o Plano B para enfrentar a Covid no Reino Unido neste inverno?
Traga de volta máscaras obrigatórias para se defender contra um surto de Covid no inverno
Os turistas podem precisar de três doses para viajar para o exterior no próximo verão
"I have a fractured toe … não, I'd never heard of Covid toe before. Pat made a joke about it on the show, and I mentioned yesterday that it's worse than a 'turf toe', and it must be a bone issue.
"I can't believe I have to come on here and talk about my medical information. Mas sim, I have a fractured toe, I've never heard of Covid toe before, I have no lesions on my feet. That's just a classic case of disinformation."
Mr Rodgers' ailment forced him to leave the pitch during Sunday's match against the Minnesota Vikings, having recently returned from 10 days out of play due to a positive Covid test.
News of his results in early November caused a furore because Mr Rodgers was subject to the safety protocol for unvaccinated players despite having claimed in August that he was "immunised".
The quarterback reacted by ranting against "cancel culture" e a "woke mob", declaring that he was not an "anti-vax flat earther" but a "critical thinker" and quoting civil rights leader Martin Luther King Jr.
Sobre 9 novembro, Contudo, he admitted that he had "misled some people about [seu] status", and was fined $14,650 (£10,991) by the National Football League (NFL) for attending a Halloween party while unvaccinated in violation of the league's rules. The Packers
Ben Roethlisberger: NFL Covid outbreak continues as Steelers QB added to reserve list
Aaron Rodgers cleared to play after unvaccinated QB's Covid diagnosis
Psaki hits out at Rodgers Covid misinformation in first briefing after being infected
In his Wednesday interview, Mr Rodgers said he "Espero[s] a full apology" from Molly Knight, an American journalist, e "whoever her editors were". Yet Ms Knight had only tweeted a link to a Wall Street Journal's report about his comments, and appeared to have had no role in the story.
Após, Ms Knight said that Mr Rodgers' fans had harassed her on social media and asked them to stop. "I have no idea why Aaron Rodgers said my name in a press conference," she tweeted on Wednesday. "This is so surreal. Please stop harassing me. I did not write the article."
Esta entrada foi publicada em ligar e marcado Aaron, Covid, denies, tendo, Rodgers, sceptic, vacina sobre 11/25/2021 de ligar.