keys = [];
anyKeys = [];
userDetails = (userDetails || {});
userDetails.firstName = userDetails.firstName || ({"value":null}).value;
userDetails.lastName = userDetails.lastName || ({"value":null}).value;
userDetails.email = userDetails.email || ({"value":null}).value;
userDetails.phone = userDetails.phone || ({"value":null}).value;
userDetails.country = userDetails.country || ({"value":null}).value;
userDetails.birthDate = userDetails.birthDate || ({"value":null}).value;
$component('global').userDetails = userDetails;
resets = {};
restart = () => {
$db('shirah').write('saved-calculator-info-visit', null).then(() => $$form($refs.removeCheckpointForm).submit());
};
resetDetails = () => {
let mapped = {};
Object.keys(resets).forEach((key) => (mapped[key] = resets[key]()));
setDetails(mapped);
};
resetDetail = (key) => {
const static = $static;
const value = ((key in $native(resets)) ? resets[key]() : null);
if (Array.isArray(value)){
if (Array.isArray(details[key]) && details[key].length == 0){
return;
}
$nextTick(() => (details[key] = value));
}
else{
details[key] = value;
}
static();
};
setDetails = (value) => {
const state = $component('global');
details = value;
state.calculatorDetails = null;
state.calculatorRecommendation = null;
};
resolveValue = (key, checkAny) => {
if (checkAny && anyKeys.includes(key)){
return 'any';
}
return (Array.isArray(details[key]) ? JSON.stringify(details[key]) : details[key]);
};
composeScenarioKey = (checkAny) => {
let scenarioKey = '';
keys.forEach((key) => {
if (key in $native(details) && ((Array.isArray(details[key]) && details[key].length != 0) || (!Array.isArray(details[key]) && details[key]))){
const value = resolveValue(key, checkAny);
scenarioKey = (scenarioKey ? `${scenarioKey}.` : scenarioKey);
scenarioKey += `${key}.${value}`;
}
});
return scenarioKey;
};
getResolvedUrl = () => {
return `/calculator/visit/recommendations/${resolvedScenario}?email=${encodeURI(userDetails.email)}`;
};
getResolvedScenario = () => {
const activeKeys = keys.filter((key) => (key in $native(details) && ((Array.isArray(details[key]) && details[key].length != 0) || (!Array.isArray(details[key]) && details[key]))));
for (const scenario of scenarios){
let totalQuestions = Object.keys(scenario.questionsAndAnswers).length, matchedQuestions = 0;
for (const key of activeKeys){
if ((key in $native(scenario.questionsAndAnswers)) && (scenario.questionsAndAnswers[key] === 'any' || scenario.questionsAndAnswers[key] === details[key])){
matchedQuestions += 1;
}
else if (key in $native(scenario.questionsAndAnswers)){
matchedQuestions = 0;
break;
}
}
if (matchedQuestions == totalQuestions){
return scenario.value;
}
}
return null;
};
proceedToRecommendation = () => {
if (resolvedScenario){
const state = $component('global');
state.calculatorRecommendation = resolvedScenario;
state.calculatorDetails = details;
$nextTick(() => $$form($refs.checkpointForm).submit());
}
};
updateCalculatorSaveDisallowed = (disallowed) => {
if (!!disallowed != !!calculatorSaveDisallowed){
$db('shirah').write('calculator-save-disallowed', (calculatorSaveDisallowed = !!disallowed)).then(() => loadData());
}
};
userDetailsAreValid = () => {
const requiredKeys = ['firstName', 'lastName', 'email', 'phone', 'country', 'birthDate'];
for (const key of requiredKeys){
if (!(key in userDetails) || !userDetails[key]){
return false;
}
}
checkBirthDate();
if (!validBirthDate){
return false;
}
return true;
};
afterLoad = () => {
if (!userDetailsAreValid()){
return;
}
if (validEmail){
setProceed().then(() => proceedToRecommendation());
}
};
loadData = () => {
$db('shirah').read('saved-calculator-info-visit').then((data) => {
if (!data){
ready = true;
$db('shirah').read('calculator-fields').then((fields) => {
loaded = true;
if (!fields){
return;
}
dbFields = fields;
userDetails.firstName = (userDetails.firstName || fields.userDetails.firstName);
userDetails.lastName = (userDetails.lastName || fields.userDetails.lastName);
userDetails.email = (userDetails.email || fields.userDetails.email);
userDetails.phone = (userDetails.phone || fields.userDetails.phone);
userDetails.country = (userDetails.country || fields.userDetails.country);
userDetails.birthDate = (userDetails.birthDate || fields.userDetails.birthDate);
afterLoad();
});
}
else{
calculatorSaveDisallowed = true;
loaded = true;
userDetails.firstName = userDetails.firstName || data.userDetails.firstName;
userDetails.lastName = userDetails.lastName || data.userDetails.lastName;
userDetails.email = userDetails.email || data.userDetails.email;
userDetails.phone = userDetails.phone || data.userDetails.phone;
userDetails.country = userDetails.country || data.userDetails.country;
userDetails.birthDate = userDetails.birthDate || data.userDetails.birthDate;
resolvedScenario = data.resolvedScenario;
afterLoad();
}
});
};
saveData = () => {
if (calculatorSaveDisallowed || !loaded){
return;
}
$db('shirah').write('calculator-fields', {
userDetails: $native(userDetails),
});
};
showVisibleTarge = () => {
showVisibleRequested = false;
visibleTarget && visibleTarget.scrollIntoView({
behavior: 'smooth',
block: 'end',
});
visibleIndex = -1;
visibleTarget = null;
};
setVisibleIndex = (index, target) => {
const static = $static;
if ((!visibleIndex && visibleIndex !== 0) || visibleIndex < index){
visibleIndex = index;
visibleTarget = target;
if (!showVisibleRequested){
showVisibleRequested = true;
$nextTick(() => showVisibleTarge());
}
}
static();
};
checkBirthDate = () => {
if (!loaded){
return;
}
const diff = (Date.now() - (userDetails.birthDate ? new Date(userDetails.birthDate) : Date.now())), ageDate = new Date(diff);
if (!(validBirthDate = $rel.ge((userDetails.age = Math.abs(ageDate.getUTCFullYear() - 1970)), 16))){
if (userDetails.birthDate !== $static(oldBirthDate)){
$alert.notify({
type: 'warning',
title: 'Invalid Date',
message: 'You must be 16 years or older to continue',
toast: true,
});
}
}
else{
details.age = ($rel.lt(userDetails.age, 30) ? '29' : '30');
}
oldBirthDate = userDetails.birthDate;
};
setProceed = (clicked) => {
if (proceed || proceeding || !clicked){
return Promise.resolve();
}
proceeding = true;
return new Promise((resolve) => {
afterUser = () => {
proceeding = false;
proceed = true;
resolve();
afterUser = null;
};
$$form($$scope(this.parentElement).userForm).submit();
});
};
validEmail = false;
oldValidEmail = validEmail;
$component('global').calculatorOptions = {};
userDetails && saveData();
resolvedScenario && setVisibleIndex(999, proceedButtonContainer);
emailCheckHandler = (isValid, hasPassword) => {
if (!(validEmail = (isValid || !hasPassword))){
oldValidEmail != validEmail && $alert.notify({
type: 'warning',
title: 'Account Exists',
message: `Account already exists.Please ${hasPassword ? 'sign in' : 'set your password'} to continue.`,
toast: true,
});
const email = encodeURI(userDetails.email);
authUrl = `modal://auth?email=${email}`;
passwordSet = hasPassword;
}
else{
authUrl = null;
if (loaded && isFirstCheck && userDetailsAreValid()){
setProceed().then(() => proceedToRecommendation());
}
}
isFirstCheck = false;
oldValidEmail = validEmail;
};
if ($static(oldEmail) !== userDetails.email){
oldEmail = userDetails.email;
userDetails.email && emailInput.validity.valid && $$form(emailForm).submit();
}
userDetails.birthDate;
checkBirthDate();
scenarios = [];
$nextTick(() => {
const joinedScenarios = {};
joinedScenarios[`family.yes.invite.yes.proof.yes.rejected.no`] = 'apply';
joinedScenarios[`family.yes.invite.no.conference.yes.proof.yes.rejected.no`] = 'apply';
joinedScenarios[`family.no.conference.yes.proof.yes.rejected.no`] = 'apply';
joinedScenarios[`family.yes.invite.yes.proof.no.rejected.no`] = 'strategy';
joinedScenarios[`family.yes.invite.no.conference.yes.proof.no.rejected.no`] = 'strategy';
joinedScenarios[`family.no.conference.yes.proof.no.rejected.no`] = 'strategy';
joinedScenarios[`family.no.conference.no.proof.yes.rejected.no`] = 'strategy';
joinedScenarios[`family.no.conference.no.proof.no.rejected.no`] = 'strategy';
joinedScenarios[`family.yes.invite.no.conference.no.proof.yes.rejected.no`] = 'strategy';
joinedScenarios[`family.yes.invite.no.conference.no.proof.no.rejected.no`] = 'strategy';
joinedScenarios[`family.yes.invite.yes.proof.yes.rejected.yes.gcms.yes`] = 'reapply';
joinedScenarios[`family.yes.invite.yes.proof.yes.rejected.yes.gcms.no`] = 'reapply';
joinedScenarios[`family.yes.invite.yes.proof.no.rejected.yes.gcms.yes`] = 'reapply';
joinedScenarios[`family.yes.invite.yes.proof.no.rejected.yes.gcms.no`] = 'reapply';
joinedScenarios[`family.yes.invite.no.conference.yes.proof.yes.rejected.yes.gcms.yes`] = 'reapply';
joinedScenarios[`family.yes.invite.no.conference.yes.proof.yes.rejected.yes.gcms.no`] = 'gcms';
joinedScenarios[`family.yes.invite.no.conference.yes.proof.no.rejected.yes.gcms.yes`] = 'reapply';
joinedScenarios[`family.yes.invite.no.conference.yes.proof.no.rejected.yes.gcms.no`] = 'gcms';
joinedScenarios[`family.no.conference.no.proof.yes.rejected.yes.gcms.yes`] = 'reapply';
joinedScenarios[`family.no.conference.no.proof.yes.rejected.yes.gcms.no`] = 'gcms';
joinedScenarios[`family.no.conference.no.proof.no.rejected.yes.gcms.yes`] = 'reapply';
joinedScenarios[`family.no.conference.no.proof.no.rejected.yes.gcms.no`] = 'gcms';
joinedScenarios[`family.yes.invite.no.conference.no.proof.yes.rejected.no.rejected.yes.gcms.yes`] = 'reapply';
joinedScenarios[`family.yes.invite.no.conference.no.proof.yes.rejected.no.rejected.yes.gcms.no`] = 'gcms';
joinedScenarios[`family.yes.invite.no.conference.no.proof.no.rejected.no.rejected.yes.gcms.yes`] = 'reapply';
joinedScenarios[`family.yes.invite.no.conference.no.proof.no.rejected.no.rejected.yes.gcms.no`] = 'gcms';
Object.entries(joinedScenarios).forEach(([key, value]) => {
const questionsAndAnswers = {}, questionAndAnswerPairs = key.split('.');
for (let i = 0; i < questionAndAnswerPairs.length; i += 2){
questionsAndAnswers[questionAndAnswerPairs[i]] = questionAndAnswerPairs[i + 1];
}
scenarios.push({
questionsAndAnswers,
value,
});
});
});
resetDetails();
resolvedScenario = getResolvedScenario();
if (oldResolvedScenario == resolvedScenario){
return;
}
oldResolvedScenario = resolvedScenario;
if (resolvedScenario){
$db('shirah').write('saved-calculator-info-visit', {
resolvedScenario: resolvedScenario,
userDetails: $native(userDetails),
details: $native(details),
}).then(() => proceedToRecommendation());
}
else{
$db('shirah').write('saved-calculator-info-visit', null);
}
$db('shirah').read('calculator-save-disallowed').then((disallowed) => {
calculatorSaveDisallowed = !!disallowed;
const state = $component('global');
if (state.calculatorRestart){
state.calculatorRestart = false;
state.userDetails = state.userDetails || {};
userDetails = userDetails || {};
userDetails.firstName = (userDetails.firstName || state.userDetails.firstName);
userDetails.lastName = (userDetails.lastName || state.userDetails.lastName);
userDetails.email = (userDetails.email || state.userDetails.email);
userDetails.phone = (userDetails.phone || state.userDetails.phone);
userDetails.country = (userDetails.country || state.userDetails.country);
userDetails.birthDate = (userDetails.birthDate || state.userDetails.birthDate);
restart();
}
!calculatorSaveDisallowed && !loaded && loadData();
});
Enter your email to continue
Before you get started, we require your email to ensure you can pick up from where you stop.
“Shirah has been an amazing partner on my journey of moving from Nigeria to Canada for studies. Honestly, I wasn’t sure how to get started with anything but after I went through Shirah’s Predictive Calculator, everything was clearer.”
Jasmin Nwankwo
keys.push('family');
familyOptions = [];
$component('global').calculatorOptions.familyOptions = familyOptions;
(details && (true)) && setVisibleIndex(0, this.parentElement);
keys.push('invite');
inviteOptions = [];
$component('global').calculatorOptions.inviteOptions = inviteOptions;
Do you have family or close friends inviting you to Canada?
$scope.deselectAll = (except) => {
$$scope(this.parentElement).columns.forEach(column => ((column !== except) && ($$scope(column).checked = false)));
};
$parent.columns.push(this.parentElement);
familyOptions.push('yes');
$parent.columns.push(this.parentElement);
familyOptions.push('no');
(details && (details.family === 'yes')) && setVisibleIndex(1, this.parentElement);
keys.push('conference');
conferenceOptions = [];
$component('global').calculatorOptions.conferenceOptions = conferenceOptions;
Are they willing to provide you with a commissioned letter of invitation for your visitor’s visa application?
$scope.deselectAll = (except) => {
$$scope(this.parentElement).columns.forEach(column => ((column !== except) && ($$scope(column).checked = false)));
};
$parent.columns.push(this.parentElement);
inviteOptions.push('yes');
$parent.columns.push(this.parentElement);
inviteOptions.push('no');
(details && ($log.or(details.family === 'no', details.invite === 'no'))) && setVisibleIndex(2, this.parentElement);
keys.push('proof');
proofOptions = [];
$component('global').calculatorOptions.proofOptions = proofOptions;
Do you have a conference, short course or group trip to attend?
$scope.deselectAll = (except) => {
$$scope(this.parentElement).columns.forEach(column => ((column !== except) && ($$scope(column).checked = false)));
};
$parent.columns.push(this.parentElement);
conferenceOptions.push('yes');
$parent.columns.push(this.parentElement);
conferenceOptions.push('no');
(details && ($log.or(details.invite === 'yes', details.conference))) && setVisibleIndex(3, this.parentElement);
keys.push('rejected');
rejectedOptions = [];
$component('global').calculatorOptions.rejectedOptions = rejectedOptions;
Do you have at least $5,000 CAD to show as proof of funds either from you or a sponsor?
$scope.deselectAll = (except) => {
$$scope(this.parentElement).columns.forEach(column => ((column !== except) && ($$scope(column).checked = false)));
};
$parent.columns.push(this.parentElement);
proofOptions.push('yes');
$parent.columns.push(this.parentElement);
proofOptions.push('no');
(details && (details.proof)) && setVisibleIndex(4, this.parentElement);
keys.push('gcms');
gcmsOptions = [];
$component('global').calculatorOptions.gcmsOptions = gcmsOptions;
Have you ever been refused a Visa to Canada?
$scope.deselectAll = (except) => {
$$scope(this.parentElement).columns.forEach(column => ((column !== except) && ($$scope(column).checked = false)));
};
$parent.columns.push(this.parentElement);
rejectedOptions.push('yes');
$parent.columns.push(this.parentElement);
rejectedOptions.push('no');
(details && (details.rejected === 'yes')) && setVisibleIndex(5, this.parentElement);
Have you ordered your GCMS Note (this is the note issued by IRCC to show the detailed reasons for study visa refusal)?
$scope.deselectAll = (except) => {
$$scope(this.parentElement).columns.forEach(column => ((column !== except) && ($$scope(column).checked = false)));
};
$parent.columns.push(this.parentElement);
gcmsOptions.push('yes');
$parent.columns.push(this.parentElement);
gcmsOptions.push('no');