Compare commits

...

1 Commits

11 changed files with 68 additions and 8177 deletions

11
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,11 @@
{
"spellright.language": [
"en"
],
"spellright.documentTypes": [
"markdown",
"latex",
"plaintext",
"html"
]
}

View File

@ -1,86 +0,0 @@
$(function () {
$(
"#contactForm input,#contactForm textarea,#contactForm button"
).jqBootstrapValidation({
preventSubmit: true,
submitError: function ($form, event, errors) {
// additional error messages or events
},
submitSuccess: function ($form, event) {
event.preventDefault(); // prevent default submit behaviour
// get values from FORM
var name = $("input#name").val();
var email = $("input#email").val();
var message = $("textarea#message").val();
var firstName = name; // For Success/Failure Message
// Check for white space in name for Success/Fail message
if (firstName.indexOf(" ") >= 0) {
firstName = name.split(" ").slice(0, -1).join(" ");
}
$this = $("#sendMessageButton");
$this.prop("disabled", true); // Disable submit button until AJAX call is complete to prevent duplicate messages
$.ajax({
url: "assets/mail/contact_me.php",
type: "POST",
cache: false,
data: {
name: name,
email: email,
message: message,
},
success: function () {
// Success message
$("#success").html("<div class='alert alert-success'>");
$("#success > .alert-success")
.html(
"<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>&times;"
)
.append("</button>");
$("#success > .alert-success").append(
"<strong>Your message has been sent. </strong>"
);
$("#success > .alert-success").append("</div>");
//clear all fields
$("#contactForm").trigger("reset");
},
error: function () {
// Fail message
$("#success").html("<div class='alert alert-danger'>");
$("#success > .alert-danger")
.html(
"<button type='button' class='close' data-dismiss='alert' aria-hidden='true'>&times;"
)
.append("</button>");
$("#success > .alert-danger").append(
$("<strong>").text(
"Sorry " +
firstName +
", an error occurred! Please try again or mail contact@luke-else.co.uk directly!"
)
);
$("#success > .alert-danger").append("</div>");
//clear all fields
$("#contactForm").trigger("reset");
},
complete: function () {
setTimeout(function () {
$this.prop("disabled", false); // Re-enable submit button when AJAX call is complete
}, 1000);
},
});
},
filter: function () {
return $(this).is(":visible");
},
});
$('a[data-toggle="tab"]').click(function (e) {
e.preventDefault();
$(this).tab("show");
});
});
/*When clicking on Full hide fail/success boxes */
$("#name").focus(function () {
$("#success").html("");
});

View File

@ -1,54 +0,0 @@
<?php
// Check for empty fields
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
require '../phpmailer/Exception.php';
require '../phpmailer/PHPMailer.php';
require '../phpmailer/SMTP.php';
//Instantiation and passing `true` enables exceptions
$mail = new PHPMailer(true);
if ($_POST['name'] != null && $_POST['email'] != null && $_POST['message'] != null) {
try {
//Server settings
$mail->SMTPDebug = SMTP::DEBUG_SERVER; //Enable verbose debug output
$mail->isSMTP(); //Send using SMTP
$mail->Host = 'in-v3.mailjet.com'; //Set the SMTP server to send through
$mail->SMTPAuth = true;
$mail->Username = '';
$mail->Password = '';
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; //Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged
$mail->Port = 587; //TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above
//Recipients
$mail->setFrom('contact@luke-else.co.uk');
$mail->addAddress('contact@luke-else.co.uk'); //Add a recipient
//Content
$mail->isHTML(true); //Set email format to HTML
$mail->Subject = 'Website Contact Form: ' . $_POST['email'];
$mail->Body =
'<br /><b> Name: </b>' . $_POST['name'] .
'<br /> <b>E-Mail: </b>' . $_POST['email'] .
'<br /><br /> <b>Message: </b><br />' . $_POST['message'];
$mail->send();
} catch (Exception $e) {
// error_log($e);
// echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
http_response_code(500);
}
}else{
http_response_code(500);
}
?>

View File

@ -1,912 +0,0 @@
/* jqBootstrapValidation
* A plugin for automating validation on Twitter Bootstrap formatted forms.
*
* v1.3.6
*
* License: MIT <http://opensource.org/licenses/mit-license.php> - see LICENSE file
*
* http://ReactiveRaven.github.com/jqBootstrapValidation/
*/
(function( $ ){
var createdElements = [];
var defaults = {
options: {
prependExistingHelpBlock: false,
sniffHtml: true, // sniff for 'required', 'maxlength', etc
preventSubmit: true, // stop the form submit event from firing if validation fails
submitError: false, // function called if there is an error when trying to submit
submitSuccess: false, // function called just before a successful submit event is sent to the server
semanticallyStrict: false, // set to true to tidy up generated HTML output
autoAdd: {
helpBlocks: true
},
filter: function () {
// return $(this).is(":visible"); // only validate elements you can see
return true; // validate everything
}
},
methods: {
init : function( options ) {
var settings = $.extend(true, {}, defaults);
settings.options = $.extend(true, settings.options, options);
var $siblingElements = this;
var uniqueForms = $.unique(
$siblingElements.map( function () {
return $(this).parents("form")[0];
}).toArray()
);
$(uniqueForms).bind("submit", function (e) {
var $form = $(this);
var warningsFound = 0;
var $inputs = $form.find("input,textarea,select").not("[type=submit],[type=image]").filter(settings.options.filter);
$inputs.trigger("submit.validation").trigger("validationLostFocus.validation");
$inputs.each(function (i, el) {
var $this = $(el),
$controlGroup = $this.parents(".control-group").first();
if (
$controlGroup.hasClass("warning")
) {
$controlGroup.removeClass("warning").addClass("error");
warningsFound++;
}
});
$inputs.trigger("validationLostFocus.validation");
if (warningsFound) {
if (settings.options.preventSubmit) {
e.preventDefault();
}
$form.addClass("error");
if ($.isFunction(settings.options.submitError)) {
settings.options.submitError($form, e, $inputs.jqBootstrapValidation("collectErrors", true));
}
} else {
$form.removeClass("error");
if ($.isFunction(settings.options.submitSuccess)) {
settings.options.submitSuccess($form, e);
}
}
});
return this.each(function(){
// Get references to everything we're interested in
var $this = $(this),
$controlGroup = $this.parents(".control-group").first(),
$helpBlock = $controlGroup.find(".help-block").first(),
$form = $this.parents("form").first(),
validatorNames = [];
// create message container if not exists
if (!$helpBlock.length && settings.options.autoAdd && settings.options.autoAdd.helpBlocks) {
$helpBlock = $('<div class="help-block" />');
$controlGroup.find('.controls').append($helpBlock);
createdElements.push($helpBlock[0]);
}
// =============================================================
// SNIFF HTML FOR VALIDATORS
// =============================================================
// *snort sniff snuffle*
if (settings.options.sniffHtml) {
var message = "";
// ---------------------------------------------------------
// PATTERN
// ---------------------------------------------------------
if ($this.attr("pattern") !== undefined) {
message = "Not in the expected format<!-- data-validation-pattern-message to override -->";
if ($this.data("validationPatternMessage")) {
message = $this.data("validationPatternMessage");
}
$this.data("validationPatternMessage", message);
$this.data("validationPatternRegex", $this.attr("pattern"));
}
// ---------------------------------------------------------
// MAX
// ---------------------------------------------------------
if ($this.attr("max") !== undefined || $this.attr("aria-valuemax") !== undefined) {
var max = ($this.attr("max") !== undefined ? $this.attr("max") : $this.attr("aria-valuemax"));
message = "Too high: Maximum of '" + max + "'<!-- data-validation-max-message to override -->";
if ($this.data("validationMaxMessage")) {
message = $this.data("validationMaxMessage");
}
$this.data("validationMaxMessage", message);
$this.data("validationMaxMax", max);
}
// ---------------------------------------------------------
// MIN
// ---------------------------------------------------------
if ($this.attr("min") !== undefined || $this.attr("aria-valuemin") !== undefined) {
var min = ($this.attr("min") !== undefined ? $this.attr("min") : $this.attr("aria-valuemin"));
message = "Too low: Minimum of '" + min + "'<!-- data-validation-min-message to override -->";
if ($this.data("validationMinMessage")) {
message = $this.data("validationMinMessage");
}
$this.data("validationMinMessage", message);
$this.data("validationMinMin", min);
}
// ---------------------------------------------------------
// MAXLENGTH
// ---------------------------------------------------------
if ($this.attr("maxlength") !== undefined) {
message = "Too long: Maximum of '" + $this.attr("maxlength") + "' characters<!-- data-validation-maxlength-message to override -->";
if ($this.data("validationMaxlengthMessage")) {
message = $this.data("validationMaxlengthMessage");
}
$this.data("validationMaxlengthMessage", message);
$this.data("validationMaxlengthMaxlength", $this.attr("maxlength"));
}
// ---------------------------------------------------------
// MINLENGTH
// ---------------------------------------------------------
if ($this.attr("minlength") !== undefined) {
message = "Too short: Minimum of '" + $this.attr("minlength") + "' characters<!-- data-validation-minlength-message to override -->";
if ($this.data("validationMinlengthMessage")) {
message = $this.data("validationMinlengthMessage");
}
$this.data("validationMinlengthMessage", message);
$this.data("validationMinlengthMinlength", $this.attr("minlength"));
}
// ---------------------------------------------------------
// REQUIRED
// ---------------------------------------------------------
if ($this.attr("required") !== undefined || $this.attr("aria-required") !== undefined) {
message = settings.builtInValidators.required.message;
if ($this.data("validationRequiredMessage")) {
message = $this.data("validationRequiredMessage");
}
$this.data("validationRequiredMessage", message);
}
// ---------------------------------------------------------
// NUMBER
// ---------------------------------------------------------
if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "number") {
message = settings.builtInValidators.number.message;
if ($this.data("validationNumberMessage")) {
message = $this.data("validationNumberMessage");
}
$this.data("validationNumberMessage", message);
}
// ---------------------------------------------------------
// EMAIL
// ---------------------------------------------------------
if ($this.attr("type") !== undefined && $this.attr("type").toLowerCase() === "email") {
message = "Not a valid email address<!-- data-validator-validemail-message to override -->";
if ($this.data("validationValidemailMessage")) {
message = $this.data("validationValidemailMessage");
} else if ($this.data("validationEmailMessage")) {
message = $this.data("validationEmailMessage");
}
$this.data("validationValidemailMessage", message);
}
// ---------------------------------------------------------
// MINCHECKED
// ---------------------------------------------------------
if ($this.attr("minchecked") !== undefined) {
message = "Not enough options checked; Minimum of '" + $this.attr("minchecked") + "' required<!-- data-validation-minchecked-message to override -->";
if ($this.data("validationMincheckedMessage")) {
message = $this.data("validationMincheckedMessage");
}
$this.data("validationMincheckedMessage", message);
$this.data("validationMincheckedMinchecked", $this.attr("minchecked"));
}
// ---------------------------------------------------------
// MAXCHECKED
// ---------------------------------------------------------
if ($this.attr("maxchecked") !== undefined) {
message = "Too many options checked; Maximum of '" + $this.attr("maxchecked") + "' required<!-- data-validation-maxchecked-message to override -->";
if ($this.data("validationMaxcheckedMessage")) {
message = $this.data("validationMaxcheckedMessage");
}
$this.data("validationMaxcheckedMessage", message);
$this.data("validationMaxcheckedMaxchecked", $this.attr("maxchecked"));
}
}
// =============================================================
// COLLECT VALIDATOR NAMES
// =============================================================
// Get named validators
if ($this.data("validation") !== undefined) {
validatorNames = $this.data("validation").split(",");
}
// Get extra ones defined on the element's data attributes
$.each($this.data(), function (i, el) {
var parts = i.replace(/([A-Z])/g, ",$1").split(",");
if (parts[0] === "validation" && parts[1]) {
validatorNames.push(parts[1]);
}
});
// =============================================================
// NORMALISE VALIDATOR NAMES
// =============================================================
var validatorNamesToInspect = validatorNames;
var newValidatorNamesToInspect = [];
do // repeatedly expand 'shortcut' validators into their real validators
{
// Uppercase only the first letter of each name
$.each(validatorNames, function (i, el) {
validatorNames[i] = formatValidatorName(el);
});
// Remove duplicate validator names
validatorNames = $.unique(validatorNames);
// Pull out the new validator names from each shortcut
newValidatorNamesToInspect = [];
$.each(validatorNamesToInspect, function(i, el) {
if ($this.data("validation" + el + "Shortcut") !== undefined) {
// Are these custom validators?
// Pull them out!
$.each($this.data("validation" + el + "Shortcut").split(","), function(i2, el2) {
newValidatorNamesToInspect.push(el2);
});
} else if (settings.builtInValidators[el.toLowerCase()]) {
// Is this a recognised built-in?
// Pull it out!
var validator = settings.builtInValidators[el.toLowerCase()];
if (validator.type.toLowerCase() === "shortcut") {
$.each(validator.shortcut.split(","), function (i, el) {
el = formatValidatorName(el);
newValidatorNamesToInspect.push(el);
validatorNames.push(el);
});
}
}
});
validatorNamesToInspect = newValidatorNamesToInspect;
} while (validatorNamesToInspect.length > 0)
// =============================================================
// SET UP VALIDATOR ARRAYS
// =============================================================
var validators = {};
$.each(validatorNames, function (i, el) {
// Set up the 'override' message
var message = $this.data("validation" + el + "Message");
var hasOverrideMessage = (message !== undefined);
var foundValidator = false;
message =
(
message
? message
: "'" + el + "' validation failed <!-- Add attribute 'data-validation-" + el.toLowerCase() + "-message' to input to change this message -->"
)
;
$.each(
settings.validatorTypes,
function (validatorType, validatorTemplate) {
if (validators[validatorType] === undefined) {
validators[validatorType] = [];
}
if (!foundValidator && $this.data("validation" + el + formatValidatorName(validatorTemplate.name)) !== undefined) {
validators[validatorType].push(
$.extend(
true,
{
name: formatValidatorName(validatorTemplate.name),
message: message
},
validatorTemplate.init($this, el)
)
);
foundValidator = true;
}
}
);
if (!foundValidator && settings.builtInValidators[el.toLowerCase()]) {
var validator = $.extend(true, {}, settings.builtInValidators[el.toLowerCase()]);
if (hasOverrideMessage) {
validator.message = message;
}
var validatorType = validator.type.toLowerCase();
if (validatorType === "shortcut") {
foundValidator = true;
} else {
$.each(
settings.validatorTypes,
function (validatorTemplateType, validatorTemplate) {
if (validators[validatorTemplateType] === undefined) {
validators[validatorTemplateType] = [];
}
if (!foundValidator && validatorType === validatorTemplateType.toLowerCase()) {
$this.data("validation" + el + formatValidatorName(validatorTemplate.name), validator[validatorTemplate.name.toLowerCase()]);
validators[validatorType].push(
$.extend(
validator,
validatorTemplate.init($this, el)
)
);
foundValidator = true;
}
}
);
}
}
if (! foundValidator) {
$.error("Cannot find validation info for '" + el + "'");
}
});
// =============================================================
// STORE FALLBACK VALUES
// =============================================================
$helpBlock.data(
"original-contents",
(
$helpBlock.data("original-contents")
? $helpBlock.data("original-contents")
: $helpBlock.html()
)
);
$helpBlock.data(
"original-role",
(
$helpBlock.data("original-role")
? $helpBlock.data("original-role")
: $helpBlock.attr("role")
)
);
$controlGroup.data(
"original-classes",
(
$controlGroup.data("original-clases")
? $controlGroup.data("original-classes")
: $controlGroup.attr("class")
)
);
$this.data(
"original-aria-invalid",
(
$this.data("original-aria-invalid")
? $this.data("original-aria-invalid")
: $this.attr("aria-invalid")
)
);
// =============================================================
// VALIDATION
// =============================================================
$this.bind(
"validation.validation",
function (event, params) {
var value = getValue($this);
// Get a list of the errors to apply
var errorsFound = [];
$.each(validators, function (validatorType, validatorTypeArray) {
if (value || value.length || (params && params.includeEmpty) || (!!settings.validatorTypes[validatorType].blockSubmit && params && !!params.submitting)) {
$.each(validatorTypeArray, function (i, validator) {
if (settings.validatorTypes[validatorType].validate($this, value, validator)) {
errorsFound.push(validator.message);
}
});
}
});
return errorsFound;
}
);
$this.bind(
"getValidators.validation",
function () {
return validators;
}
);
// =============================================================
// WATCH FOR CHANGES
// =============================================================
$this.bind(
"submit.validation",
function () {
return $this.triggerHandler("change.validation", {submitting: true});
}
);
$this.bind(
[
"keyup",
"focus",
"blur",
"click",
"keydown",
"keypress",
"change"
].join(".validation ") + ".validation",
function (e, params) {
var value = getValue($this);
var errorsFound = [];
$controlGroup.find("input,textarea,select").each(function (i, el) {
var oldCount = errorsFound.length;
$.each($(el).triggerHandler("validation.validation", params), function (j, message) {
errorsFound.push(message);
});
if (errorsFound.length > oldCount) {
$(el).attr("aria-invalid", "true");
} else {
var original = $this.data("original-aria-invalid");
$(el).attr("aria-invalid", (original !== undefined ? original : false));
}
});
$form.find("input,select,textarea").not($this).not("[name=\"" + $this.attr("name") + "\"]").trigger("validationLostFocus.validation");
errorsFound = $.unique(errorsFound.sort());
// Were there any errors?
if (errorsFound.length) {
// Better flag it up as a warning.
$controlGroup.removeClass("success error").addClass("warning");
// How many errors did we find?
if (settings.options.semanticallyStrict && errorsFound.length === 1) {
// Only one? Being strict? Just output it.
$helpBlock.html(errorsFound[0] +
( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" ));
} else {
// Multiple? Being sloppy? Glue them together into an UL.
$helpBlock.html("<ul role=\"alert\"><li>" + errorsFound.join("</li><li>") + "</li></ul>" +
( settings.options.prependExistingHelpBlock ? $helpBlock.data("original-contents") : "" ));
}
} else {
$controlGroup.removeClass("warning error success");
if (value.length > 0) {
$controlGroup.addClass("success");
}
$helpBlock.html($helpBlock.data("original-contents"));
}
if (e.type === "blur") {
$controlGroup.removeClass("success");
}
}
);
$this.bind("validationLostFocus.validation", function () {
$controlGroup.removeClass("success");
});
});
},
destroy : function( ) {
return this.each(
function() {
var
$this = $(this),
$controlGroup = $this.parents(".control-group").first(),
$helpBlock = $controlGroup.find(".help-block").first();
// remove our events
$this.unbind('.validation'); // events are namespaced.
// reset help text
$helpBlock.html($helpBlock.data("original-contents"));
// reset classes
$controlGroup.attr("class", $controlGroup.data("original-classes"));
// reset aria
$this.attr("aria-invalid", $this.data("original-aria-invalid"));
// reset role
$helpBlock.attr("role", $this.data("original-role"));
// remove all elements we created
if (createdElements.indexOf($helpBlock[0]) > -1) {
$helpBlock.remove();
}
}
);
},
collectErrors : function(includeEmpty) {
var errorMessages = {};
this.each(function (i, el) {
var $el = $(el);
var name = $el.attr("name");
var errors = $el.triggerHandler("validation.validation", {includeEmpty: true});
errorMessages[name] = $.extend(true, errors, errorMessages[name]);
});
$.each(errorMessages, function (i, el) {
if (el.length === 0) {
delete errorMessages[i];
}
});
return errorMessages;
},
hasErrors: function() {
var errorMessages = [];
this.each(function (i, el) {
errorMessages = errorMessages.concat(
$(el).triggerHandler("getValidators.validation") ? $(el).triggerHandler("validation.validation", {submitting: true}) : []
);
});
return (errorMessages.length > 0);
},
override : function (newDefaults) {
defaults = $.extend(true, defaults, newDefaults);
}
},
validatorTypes: {
callback: {
name: "callback",
init: function ($this, name) {
return {
validatorName: name,
callback: $this.data("validation" + name + "Callback"),
lastValue: $this.val(),
lastValid: true,
lastFinished: true
};
},
validate: function ($this, value, validator) {
if (validator.lastValue === value && validator.lastFinished) {
return !validator.lastValid;
}
if (validator.lastFinished === true)
{
validator.lastValue = value;
validator.lastValid = true;
validator.lastFinished = false;
var rrjqbvValidator = validator;
var rrjqbvThis = $this;
executeFunctionByName(
validator.callback,
window,
$this,
value,
function (data) {
if (rrjqbvValidator.lastValue === data.value) {
rrjqbvValidator.lastValid = data.valid;
if (data.message) {
rrjqbvValidator.message = data.message;
}
rrjqbvValidator.lastFinished = true;
rrjqbvThis.data("validation" + rrjqbvValidator.validatorName + "Message", rrjqbvValidator.message);
// Timeout is set to avoid problems with the events being considered 'already fired'
setTimeout(function () {
rrjqbvThis.trigger("change.validation");
}, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
}
}
);
}
return false;
}
},
ajax: {
name: "ajax",
init: function ($this, name) {
return {
validatorName: name,
url: $this.data("validation" + name + "Ajax"),
lastValue: $this.val(),
lastValid: true,
lastFinished: true
};
},
validate: function ($this, value, validator) {
if (""+validator.lastValue === ""+value && validator.lastFinished === true) {
return validator.lastValid === false;
}
if (validator.lastFinished === true)
{
validator.lastValue = value;
validator.lastValid = true;
validator.lastFinished = false;
$.ajax({
url: validator.url,
data: "value=" + value + "&field=" + $this.attr("name"),
dataType: "json",
success: function (data) {
if (""+validator.lastValue === ""+data.value) {
validator.lastValid = !!(data.valid);
if (data.message) {
validator.message = data.message;
}
validator.lastFinished = true;
$this.data("validation" + validator.validatorName + "Message", validator.message);
// Timeout is set to avoid problems with the events being considered 'already fired'
setTimeout(function () {
$this.trigger("change.validation");
}, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
}
},
failure: function () {
validator.lastValid = true;
validator.message = "ajax call failed";
validator.lastFinished = true;
$this.data("validation" + validator.validatorName + "Message", validator.message);
// Timeout is set to avoid problems with the events being considered 'already fired'
setTimeout(function () {
$this.trigger("change.validation");
}, 1); // doesn't need a long timeout, just long enough for the event bubble to burst
}
});
}
return false;
}
},
regex: {
name: "regex",
init: function ($this, name) {
return {regex: regexFromString($this.data("validation" + name + "Regex"))};
},
validate: function ($this, value, validator) {
return (!validator.regex.test(value) && ! validator.negative)
|| (validator.regex.test(value) && validator.negative);
}
},
required: {
name: "required",
init: function ($this, name) {
return {};
},
validate: function ($this, value, validator) {
return !!(value.length === 0 && ! validator.negative)
|| !!(value.length > 0 && validator.negative);
},
blockSubmit: true
},
match: {
name: "match",
init: function ($this, name) {
var element = $this.parents("form").first().find("[name=\"" + $this.data("validation" + name + "Match") + "\"]").first();
element.bind("validation.validation", function () {
$this.trigger("change.validation", {submitting: true});
});
return {"element": element};
},
validate: function ($this, value, validator) {
return (value !== validator.element.val() && ! validator.negative)
|| (value === validator.element.val() && validator.negative);
},
blockSubmit: true
},
max: {
name: "max",
init: function ($this, name) {
return {max: $this.data("validation" + name + "Max")};
},
validate: function ($this, value, validator) {
return (parseFloat(value, 10) > parseFloat(validator.max, 10) && ! validator.negative)
|| (parseFloat(value, 10) <= parseFloat(validator.max, 10) && validator.negative);
}
},
min: {
name: "min",
init: function ($this, name) {
return {min: $this.data("validation" + name + "Min")};
},
validate: function ($this, value, validator) {
return (parseFloat(value) < parseFloat(validator.min) && ! validator.negative)
|| (parseFloat(value) >= parseFloat(validator.min) && validator.negative);
}
},
maxlength: {
name: "maxlength",
init: function ($this, name) {
return {maxlength: $this.data("validation" + name + "Maxlength")};
},
validate: function ($this, value, validator) {
return ((value.length > validator.maxlength) && ! validator.negative)
|| ((value.length <= validator.maxlength) && validator.negative);
}
},
minlength: {
name: "minlength",
init: function ($this, name) {
return {minlength: $this.data("validation" + name + "Minlength")};
},
validate: function ($this, value, validator) {
return ((value.length < validator.minlength) && ! validator.negative)
|| ((value.length >= validator.minlength) && validator.negative);
}
},
maxchecked: {
name: "maxchecked",
init: function ($this, name) {
var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]");
elements.bind("click.validation", function () {
$this.trigger("change.validation", {includeEmpty: true});
});
return {maxchecked: $this.data("validation" + name + "Maxchecked"), elements: elements};
},
validate: function ($this, value, validator) {
return (validator.elements.filter(":checked").length > validator.maxchecked && ! validator.negative)
|| (validator.elements.filter(":checked").length <= validator.maxchecked && validator.negative);
},
blockSubmit: true
},
minchecked: {
name: "minchecked",
init: function ($this, name) {
var elements = $this.parents("form").first().find("[name=\"" + $this.attr("name") + "\"]");
elements.bind("click.validation", function () {
$this.trigger("change.validation", {includeEmpty: true});
});
return {minchecked: $this.data("validation" + name + "Minchecked"), elements: elements};
},
validate: function ($this, value, validator) {
return (validator.elements.filter(":checked").length < validator.minchecked && ! validator.negative)
|| (validator.elements.filter(":checked").length >= validator.minchecked && validator.negative);
},
blockSubmit: true
}
},
builtInValidators: {
email: {
name: "Email",
type: "shortcut",
shortcut: "validemail"
},
validemail: {
name: "Validemail",
type: "regex",
regex: "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\\.[A-Za-z]{2,4}",
message: "Not a valid email address<!-- data-validator-validemail-message to override -->"
},
passwordagain: {
name: "Passwordagain",
type: "match",
match: "password",
message: "Does not match the given password<!-- data-validator-paswordagain-message to override -->"
},
positive: {
name: "Positive",
type: "shortcut",
shortcut: "number,positivenumber"
},
negative: {
name: "Negative",
type: "shortcut",
shortcut: "number,negativenumber"
},
number: {
name: "Number",
type: "regex",
regex: "([+-]?\\\d+(\\\.\\\d*)?([eE][+-]?[0-9]+)?)?",
message: "Must be a number<!-- data-validator-number-message to override -->"
},
integer: {
name: "Integer",
type: "regex",
regex: "[+-]?\\\d+",
message: "No decimal places allowed<!-- data-validator-integer-message to override -->"
},
positivenumber: {
name: "Positivenumber",
type: "min",
min: 0,
message: "Must be a positive number<!-- data-validator-positivenumber-message to override -->"
},
negativenumber: {
name: "Negativenumber",
type: "max",
max: 0,
message: "Must be a negative number<!-- data-validator-negativenumber-message to override -->"
},
required: {
name: "Required",
type: "required",
message: "This is required<!-- data-validator-required-message to override -->"
},
checkone: {
name: "Checkone",
type: "minchecked",
minchecked: 1,
message: "Check at least one option<!-- data-validation-checkone-message to override -->"
}
}
};
var formatValidatorName = function (name) {
return name
.toLowerCase()
.replace(
/(^|\s)([a-z])/g ,
function(m,p1,p2) {
return p1+p2.toUpperCase();
}
)
;
};
var getValue = function ($this) {
// Extract the value we're talking about
var value = $this.val();
var type = $this.attr("type");
if (type === "checkbox") {
value = ($this.is(":checked") ? value : "");
}
if (type === "radio") {
value = ($('input[name="' + $this.attr("name") + '"]:checked').length > 0 ? value : "");
}
return value;
};
function regexFromString(inputstring) {
return new RegExp("^" + inputstring + "$");
}
/**
* Thanks to Jason Bunting via StackOverflow.com
*
* http://stackoverflow.com/questions/359788/how-to-execute-a-javascript-function-when-i-have-its-name-as-a-string#answer-359910
* Short link: http://tinyurl.com/executeFunctionByName
**/
function executeFunctionByName(functionName, context /*, args*/) {
var args = Array.prototype.slice.call(arguments).splice(2);
var namespaces = functionName.split(".");
var func = namespaces.pop();
for(var i = 0; i < namespaces.length; i++) {
context = context[namespaces[i]];
}
return context[func].apply(this, args);
}
$.fn.jqBootstrapValidation = function( method ) {
if ( defaults.methods[method] ) {
return defaults.methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
} else if ( typeof method === 'object' || ! method ) {
return defaults.methods.init.apply( this, arguments );
} else {
$.error( 'Method ' + method + ' does not exist on jQuery.jqBootstrapValidation' );
return null;
}
};
$.jqBootstrapValidation = function (options) {
$(":input").not("[type=image],[type=submit]").jqBootstrapValidation.apply(this,arguments);
};
})( jQuery );

View File

@ -1,40 +0,0 @@
<?php
/**
* PHPMailer Exception class.
* PHP Version 5.5.
*
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
namespace PHPMailer\PHPMailer;
/**
* PHPMailer exception handler.
*
* @author Marcus Bointon <phpmailer@synchromedia.co.uk>
*/
class Exception extends \Exception
{
/**
* Prettify error message output.
*
* @return string
*/
public function errorMessage()
{
return '<strong>' . htmlspecialchars($this->getMessage()) . "</strong><br />\n";
}
}

View File

@ -1,139 +0,0 @@
<?php
/**
* PHPMailer - PHP email creation and transport class.
* PHP Version 5.5.
*
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
namespace PHPMailer\PHPMailer;
use League\OAuth2\Client\Grant\RefreshToken;
use League\OAuth2\Client\Provider\AbstractProvider;
use League\OAuth2\Client\Token\AccessToken;
/**
* OAuth - OAuth2 authentication wrapper class.
* Uses the oauth2-client package from the League of Extraordinary Packages.
*
* @see http://oauth2-client.thephpleague.com
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
*/
class OAuth
{
/**
* An instance of the League OAuth Client Provider.
*
* @var AbstractProvider
*/
protected $provider;
/**
* The current OAuth access token.
*
* @var AccessToken
*/
protected $oauthToken;
/**
* The user's email address, usually used as the login ID
* and also the from address when sending email.
*
* @var string
*/
protected $oauthUserEmail = '';
/**
* The client secret, generated in the app definition of the service you're connecting to.
*
* @var string
*/
protected $oauthClientSecret = '';
/**
* The client ID, generated in the app definition of the service you're connecting to.
*
* @var string
*/
protected $oauthClientId = '';
/**
* The refresh token, used to obtain new AccessTokens.
*
* @var string
*/
protected $oauthRefreshToken = '';
/**
* OAuth constructor.
*
* @param array $options Associative array containing
* `provider`, `userName`, `clientSecret`, `clientId` and `refreshToken` elements
*/
public function __construct($options)
{
$this->provider = $options['provider'];
$this->oauthUserEmail = $options['userName'];
$this->oauthClientSecret = $options['clientSecret'];
$this->oauthClientId = $options['clientId'];
$this->oauthRefreshToken = $options['refreshToken'];
}
/**
* Get a new RefreshToken.
*
* @return RefreshToken
*/
protected function getGrant()
{
return new RefreshToken();
}
/**
* Get a new AccessToken.
*
* @return AccessToken
*/
protected function getToken()
{
return $this->provider->getAccessToken(
$this->getGrant(),
['refresh_token' => $this->oauthRefreshToken]
);
}
/**
* Generate a base64-encoded OAuth token.
*
* @return string
*/
public function getOauth64()
{
//Get a new token if it's not available or has expired
if (null === $this->oauthToken || $this->oauthToken->hasExpired()) {
$this->oauthToken = $this->getToken();
}
return base64_encode(
'user=' .
$this->oauthUserEmail .
"\001auth=Bearer " .
$this->oauthToken .
"\001\001"
);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,448 +0,0 @@
<?php
/**
* PHPMailer POP-Before-SMTP Authentication Class.
* PHP Version 5.5.
*
* @see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
*
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
* @author Brent R. Matzelle (original founder)
* @copyright 2012 - 2020 Marcus Bointon
* @copyright 2010 - 2012 Jim Jagielski
* @copyright 2004 - 2009 Andy Prevost
* @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* @note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
namespace PHPMailer\PHPMailer;
/**
* PHPMailer POP-Before-SMTP Authentication Class.
* Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication.
* 1) This class does not support APOP authentication.
* 2) Opening and closing lots of POP3 connections can be quite slow. If you need
* to send a batch of emails then just perform the authentication once at the start,
* and then loop through your mail sending script. Providing this process doesn't
* take longer than the verification period lasts on your POP3 server, you should be fine.
* 3) This is really ancient technology; you should only need to use it to talk to very old systems.
* 4) This POP3 class is deliberately lightweight and incomplete, implementing just
* enough to do authentication.
* If you want a more complete class there are other POP3 classes for PHP available.
*
* @author Richard Davey (original author) <rich@corephp.co.uk>
* @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>
* @author Jim Jagielski (jimjag) <jimjag@gmail.com>
* @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>
*/
class POP3
{
/**
* The POP3 PHPMailer Version number.
*
* @var string
*/
const VERSION = '6.4.1';
/**
* Default POP3 port number.
*
* @var int
*/
const DEFAULT_PORT = 110;
/**
* Default timeout in seconds.
*
* @var int
*/
const DEFAULT_TIMEOUT = 30;
/**
* POP3 class debug output mode.
* Debug output level.
* Options:
* @see POP3::DEBUG_OFF: No output
* @see POP3::DEBUG_SERVER: Server messages, connection/server errors
* @see POP3::DEBUG_CLIENT: Client and Server messages, connection/server errors
*
* @var int
*/
public $do_debug = self::DEBUG_OFF;
/**
* POP3 mail server hostname.
*
* @var string
*/
public $host;
/**
* POP3 port number.
*
* @var int
*/
public $port;
/**
* POP3 Timeout Value in seconds.
*
* @var int
*/
public $tval;
/**
* POP3 username.
*
* @var string
*/
public $username;
/**
* POP3 password.
*
* @var string
*/
public $password;
/**
* Resource handle for the POP3 connection socket.
*
* @var resource
*/
protected $pop_conn;
/**
* Are we connected?
*
* @var bool
*/
protected $connected = false;
/**
* Error container.
*
* @var array
*/
protected $errors = [];
/**
* Line break constant.
*/
const LE = "\r\n";
/**
* Debug level for no output.
*
* @var int
*/
const DEBUG_OFF = 0;
/**
* Debug level to show server -> client messages
* also shows clients connection errors or errors from server
*
* @var int
*/
const DEBUG_SERVER = 1;
/**
* Debug level to show client -> server and server -> client messages.
*
* @var int
*/
const DEBUG_CLIENT = 2;
/**
* Simple static wrapper for all-in-one POP before SMTP.
*
* @param string $host The hostname to connect to
* @param int|bool $port The port number to connect to
* @param int|bool $timeout The timeout value
* @param string $username
* @param string $password
* @param int $debug_level
*
* @return bool
*/
public static function popBeforeSmtp(
$host,
$port = false,
$timeout = false,
$username = '',
$password = '',
$debug_level = 0
) {
$pop = new self();
return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level);
}
/**
* Authenticate with a POP3 server.
* A connect, login, disconnect sequence
* appropriate for POP-before SMTP authorisation.
*
* @param string $host The hostname to connect to
* @param int|bool $port The port number to connect to
* @param int|bool $timeout The timeout value
* @param string $username
* @param string $password
* @param int $debug_level
*
* @return bool
*/
public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0)
{
$this->host = $host;
//If no port value provided, use default
if (false === $port) {
$this->port = static::DEFAULT_PORT;
} else {
$this->port = (int) $port;
}
//If no timeout value provided, use default
if (false === $timeout) {
$this->tval = static::DEFAULT_TIMEOUT;
} else {
$this->tval = (int) $timeout;
}
$this->do_debug = $debug_level;
$this->username = $username;
$this->password = $password;
//Reset the error log
$this->errors = [];
//Connect
$result = $this->connect($this->host, $this->port, $this->tval);
if ($result) {
$login_result = $this->login($this->username, $this->password);
if ($login_result) {
$this->disconnect();
return true;
}
}
//We need to disconnect regardless of whether the login succeeded
$this->disconnect();
return false;
}
/**
* Connect to a POP3 server.
*
* @param string $host
* @param int|bool $port
* @param int $tval
*
* @return bool
*/
public function connect($host, $port = false, $tval = 30)
{
//Are we already connected?
if ($this->connected) {
return true;
}
//On Windows this will raise a PHP Warning error if the hostname doesn't exist.
//Rather than suppress it with @fsockopen, capture it cleanly instead
set_error_handler([$this, 'catchWarning']);
if (false === $port) {
$port = static::DEFAULT_PORT;
}
//Connect to the POP3 server
$errno = 0;
$errstr = '';
$this->pop_conn = fsockopen(
$host, //POP3 Host
$port, //Port #
$errno, //Error Number
$errstr, //Error Message
$tval
); //Timeout (seconds)
//Restore the error handler
restore_error_handler();
//Did we connect?
if (false === $this->pop_conn) {
//It would appear not...
$this->setError(
"Failed to connect to server $host on port $port. errno: $errno; errstr: $errstr"
);
return false;
}
//Increase the stream time-out
stream_set_timeout($this->pop_conn, $tval, 0);
//Get the POP3 server response
$pop3_response = $this->getResponse();
//Check for the +OK
if ($this->checkResponse($pop3_response)) {
//The connection is established and the POP3 server is talking
$this->connected = true;
return true;
}
return false;
}
/**
* Log in to the POP3 server.
* Does not support APOP (RFC 2828, 4949).
*
* @param string $username
* @param string $password
*
* @return bool
*/
public function login($username = '', $password = '')
{
if (!$this->connected) {
$this->setError('Not connected to POP3 server');
}
if (empty($username)) {
$username = $this->username;
}
if (empty($password)) {
$password = $this->password;
}
//Send the Username
$this->sendString("USER $username" . static::LE);
$pop3_response = $this->getResponse();
if ($this->checkResponse($pop3_response)) {
//Send the Password
$this->sendString("PASS $password" . static::LE);
$pop3_response = $this->getResponse();
if ($this->checkResponse($pop3_response)) {
return true;
}
}
return false;
}
/**
* Disconnect from the POP3 server.
*/
public function disconnect()
{
$this->sendString('QUIT');
//The QUIT command may cause the daemon to exit, which will kill our connection
//So ignore errors here
try {
@fclose($this->pop_conn);
} catch (Exception $e) {
//Do nothing
}
}
/**
* Get a response from the POP3 server.
*
* @param int $size The maximum number of bytes to retrieve
*
* @return string
*/
protected function getResponse($size = 128)
{
$response = fgets($this->pop_conn, $size);
if ($this->do_debug >= self::DEBUG_SERVER) {
echo 'Server -> Client: ', $response;
}
return $response;
}
/**
* Send raw data to the POP3 server.
*
* @param string $string
*
* @return int
*/
protected function sendString($string)
{
if ($this->pop_conn) {
if ($this->do_debug >= self::DEBUG_CLIENT) { //Show client messages when debug >= 2
echo 'Client -> Server: ', $string;
}
return fwrite($this->pop_conn, $string, strlen($string));
}
return 0;
}
/**
* Checks the POP3 server response.
* Looks for for +OK or -ERR.
*
* @param string $string
*
* @return bool
*/
protected function checkResponse($string)
{
if (strpos($string, '+OK') !== 0) {
$this->setError("Server reported an error: $string");
return false;
}
return true;
}
/**
* Add an error to the internal error store.
* Also display debug output if it's enabled.
*
* @param string $error
*/
protected function setError($error)
{
$this->errors[] = $error;
if ($this->do_debug >= self::DEBUG_SERVER) {
echo '<pre>';
foreach ($this->errors as $e) {
print_r($e);
}
echo '</pre>';
}
}
/**
* Get an array of error messages, if any.
*
* @return array
*/
public function getErrors()
{
return $this->errors;
}
/**
* POP3 connection error handler.
*
* @param int $errno
* @param string $errstr
* @param string $errfile
* @param int $errline
*/
protected function catchWarning($errno, $errstr, $errfile, $errline)
{
$this->setError(
'Connecting to the POP3 server raised a PHP warning:' .
"errno: $errno errstr: $errstr; errfile: $errfile; errline: $errline"
);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,6 @@
<li class="nav-item"><a class="nav-link js-scroll-trigger" href="#education">Education</a></li> <li class="nav-item"><a class="nav-link js-scroll-trigger" href="#education">Education</a></li>
<li class="nav-item"><a class="nav-link js-scroll-trigger" href="#skills">Skills</a></li> <li class="nav-item"><a class="nav-link js-scroll-trigger" href="#skills">Skills</a></li>
<li class="nav-item"><a class="nav-link js-scroll-trigger" href="#interests">Interests</a></li> <li class="nav-item"><a class="nav-link js-scroll-trigger" href="#interests">Interests</a></li>
<li class="nav-item"><a class="nav-link js-scroll-trigger" href="#contact">Contact</a></li>
</ul> </ul>
</div> </div>
</nav> </nav>
@ -76,12 +75,13 @@
E-Mail: E-Mail:
<a href="mailto:contact@luke-else.co.uk">contact@luke-else.co.uk</a> <a href="mailto:contact@luke-else.co.uk">contact@luke-else.co.uk</a>
</div> </div>
<p class="lead mb-5">I am a Junior but well-practised Software Developer. I have a great passion for learning, especially in topics oriented around Software Development, Networks and Backend Engineering. I am constantly striving to learn more whilst pushing myself to explore new technologies!</p> <p class="lead mb-5">I am a Junior but well-practised Software Engineer currently employed at Thales UK. I have a great passion for learning, especially in topics oriented around Software Development, Networks and Backend Engineering. I am currently in the process of learning <a href="https://www.rust-lang.org">Rust-Lang</a> and hope to use it in my upcoming projects</p>
<div class="social-icons"> <div class="social-icons">
<a target="_blank" class="social-icon" href="https://www.linkedin.com/in/luke-else-a7183a205/"><i class="fab fa-linkedin-in"></i></a> <a target="_blank" class="social-icon" href="https://www.linkedin.com/in/luke-else-a7183a205/"><i class="fab fa-linkedin-in"></i></a>
<a target="_blank" class="social-icon" href="https://git.luke-else.co.uk/luke-else/"><i class="fab fa-git-alt"></i></a>
<a target="_blank" class="social-icon" href="https://github.com/luke-else"><i class="fab fa-github"></i></a> <a target="_blank" class="social-icon" href="https://github.com/luke-else"><i class="fab fa-github"></i></a>
<a target="_blank" class="social-icon" href="https://stackoverflow.com/users/16627564/luke-else"><i class="fab fa-stack-overflow"></i></a>
<a target="_blank" class="social-icon" href="assets/Luke Else - CV.pdf"><i class="fas fa-file-download"></i></a> <a target="_blank" class="social-icon" href="assets/Luke Else - CV.pdf"><i class="fas fa-file-download"></i></a>
<a target="_blank" class="social-icon" href="https://info.luke-else.co.uk"><i class="fa-regular fa-address-card"></i></a>
</div> </div>
</div> </div>
</section> </section>
@ -90,14 +90,34 @@
<section class="resume-section" id="experience"> <section class="resume-section" id="experience">
<div class="resume-section-content"> <div class="resume-section-content">
<h2 class="mb-5">Experience</h2> <h2 class="mb-5">Experience</h2>
<div class="d-flex flex-column flex-md-row justify-content-between mb-5">
<div class="flex-grow-1">
<h3 class="mb-0">Software Engineer</h3>
<div class="subheading mb-3">Thales UK</div>
<p>As a software engineering apprentice at Thales UK, I find myself partaking in agile / scrum development methodologies in a strong team of 6 other engineers. The team iterates on a pre-existing system designed for the MOD, written in C++ using internal frameworks to assist.</p>
</div>
<div class="flex-shrink-0"><span class="text-primary">September 2022 - Current</span></div>
</div>
<div class="d-flex flex-column flex-md-row justify-content-between mb-5">
<div class="flex-grow-1">
<h3 class="mb-0">Trading Assistant</h3>
<div class="subheading mb-3">Sainsbury's</div>
<p>During my 6 months at Sainsbury's, I worked hard to ensure shelves were stocked whilst also assisting with the preparation and execution of promotional strategies through the Spring and Summer seasons.</p>
</div>
<div class="flex-shrink-0"><span class="text-primary">February 2022 - August 2022</span></div>
</div>
<div class="d-flex flex-column flex-md-row justify-content-between mb-5"> <div class="d-flex flex-column flex-md-row justify-content-between mb-5">
<div class="flex-grow-1"> <div class="flex-grow-1">
<h3 class="mb-0">Car Valeter</h3> <h3 class="mb-0">Car Valeter</h3>
<div class="subheading mb-3">CSM Valeting</div> <div class="subheading mb-3">CSM Valeting</div>
<p>This job involved ensuring customer satisfaction was very high! Every car had to be cleaned meticulously to ensure the highest standard was achieved. We often spent a lot of our time in commercial workspace environments and so remaining professional was key to the service we provided. I enjoyed working here a lot because of both the independent and teamworking aspects. On many occasions we would find ourselves working on a car in a group so communication was key to ensure that no part was missed nor any unnecessary work was undertaken!</p> <p>This job involved ensuring customer satisfaction was very high! Every car had to be cleaned meticulously to ensure the highest standard was achieved. We often spent a lot of our time in commercial workspace environments and so remaining professional was key to the service we provided. I enjoyed working here a lot because of both the independent and teamworking aspects. On many occasions we would find ourselves working on a car in a group so communication was key to ensure that no part was missed nor any unnecessary work was undertaken!</p>
</div> </div>
<div class="flex-shrink-0"><span class="text-primary">March 2020 - Present</span></div> <div class="flex-shrink-0"><span class="text-primary">March 2020 - February 2022</span></div>
</div> </div>
<div class="d-flex flex-column flex-md-row justify-content-between mb-5"> <div class="d-flex flex-column flex-md-row justify-content-between mb-5">
<div class="flex-grow-1"> <div class="flex-grow-1">
<h3 class="mb-0">Site Maintenance</h3> <h3 class="mb-0">Site Maintenance</h3>
@ -106,6 +126,7 @@
</div> </div>
<div class="flex-shrink-0"><span class="text-primary">July 2018 - September 2020</span></div> <div class="flex-shrink-0"><span class="text-primary">July 2018 - September 2020</span></div>
</div> </div>
</div> </div>
</section> </section>
<hr class="m-0" /> <hr class="m-0" />
@ -147,13 +168,23 @@
<h2 class="mb-5">Education</h2> <h2 class="mb-5">Education</h2>
<div class="d-flex flex-column flex-md-row justify-content-between mb-5"> <div class="d-flex flex-column flex-md-row justify-content-between mb-5">
<div class="flex-grow-1"> <div class="flex-grow-1">
<h3 class="mb-0">The Norton Knatchbull School</h3> <h3 class="mb-0">University Of Warwick</h3>
<div class="subheading mb-3">A-Levels</div> <div class="subheading mb-3">BSc Digital Solutions Level 6 Integrated Degree</div>
<div>Computer Science, Maths and Physics</div> <div>Provided through Thales UK.</div>
<p>Grades (Predicted): A*, A, A</p> <div>Grade On Track: (<b>1:1</b>)</div>
</div> </div>
<div class="flex-shrink-0"><span class="text-primary">September 2020 - Present</span></div> <div class="flex-shrink-0"><span class="text-primary">September 2022 - current</span></div>
</div>
<div class="d-flex flex-column flex-md-row justify-content-between mb-5">
<div class="flex-grow-1">
<h3 class="mb-0">The Norton Knatchbull School</h3>
<div class="subheading mb-3">A-Levels</div>
<div>Computer Science (<b>A*</b>), Maths (<b>A</b>), Physics (<b>A</b>)</div>
</div>
<div class="flex-shrink-0"><span class="text-primary">September 2020 - July 2022</span></div>
</div> </div>
<div class="d-flex flex-column flex-md-row justify-content-between mb-5"> <div class="d-flex flex-column flex-md-row justify-content-between mb-5">
@ -177,44 +208,37 @@
<h2 class="mb-5">Skills</h2> <h2 class="mb-5">Skills</h2>
<div class="subheading mb-3">Programming Languages & Tools</div> <div class="subheading mb-3">Programming Languages & Tools</div>
<ul class="list-inline dev-icons"> <ul class="list-inline dev-icons">
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="GoLang" class="fab fa-rust"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Bash" class="devicon-c-plain"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Bash" class="devicon-cplusplus-plain"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="C#" class="devicon-csharp-plain"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Linux" class="fab fa-linux"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Git" class="fab fa-git-alt"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Bash" class="devicon-bash-plain"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="docker" class="devicon-docker-plain"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="NGINX" class="devicon-nginx-plain"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="GoLang" class="fab fa-golang"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="HTML 5" class="fab fa-html5"></i></li> <li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="HTML 5" class="fab fa-html5"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="CSS 3" class="fab fa-css3-alt"></i></li> <li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="CSS 3" class="fab fa-css3-alt"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Java Script" class="fab fa-js-square"></i></li> <li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Java Script" class="fab fa-js-square"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="GoLang" class="fab fa-golang"></i></li>
<!-- <li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Golang" class="fab fa-golang"></i></li> -->
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="C#" class="devicon-csharp-plain"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title=".Net" class="devicon-dotnetcore-plain"></i></li>
<!--
<li class="list-inline-item"><i class="fab fa-python"></i></li>
<li class="list-inline-item"><i class="fab fa-php"></i></li>
-->
<!-- <li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Network Infrastructure" class="fas fa-network-wired"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Server Infrastructure" class="fas fa-server"></i></li> -->
<!--<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Amazon Web Services" class="fab fa-aws"></i></li> -->
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="NGINX" class="devicon-nginx-plain"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="docker" class="devicon-docker-plain"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Linux" class="fab fa-linux"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Bash" class="devicon-bash-plain"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Git" class="fab fa-git-alt"></i></li>
<li class="list-inline-item"><i data-toggle="tooltip" data-placement="bottom" title="Stack Overflow" class="fab fa-stack-overflow"></i></li>
</ul> </ul>
<div class="subheading mb-3">Workflow</div> <div class="subheading mb-3">Workflow</div>
<ul class="fa-ul mb-0"> <ul class="fa-ul mb-0">
<li> <li>
<span class="fa-li"><i class="fas fa-check"></i></span> <span class="fa-li"><i class="fas fa-check"></i></span>
Basic Website front-end and UI Development Competent in Agile / Scrum Methodologies and workflows
</li> </li>
<li> <li>
<span class="fa-li"><i class="fas fa-check"></i></span> <span class="fa-li"><i class="fas fa-check"></i></span>
Website Client Side and Server Side Development Confident using Version Control tools such as Git and Subversion.
</li> </li>
<li> <li>
<span class="fa-li"><i class="fas fa-check"></i></span> <span class="fa-li"><i class="fas fa-check"></i></span>
Basic Networking and Server Infrastructure In depth knowledge of programming and computer system theory
</li> </li>
<li> <li>
<span class="fa-li"><i class="fas fa-check"></i></span> <span class="fa-li"><i class="fas fa-check"></i></span>
Software Development Well practiced in Software Development and Engineering
</li> </li>
</ul> </ul>
</div> </div>
@ -224,72 +248,12 @@
<section class="resume-section" id="interests"> <section class="resume-section" id="interests">
<div class="resume-section-content"> <div class="resume-section-content">
<h2 class="mb-5">Interests</h2> <h2 class="mb-5">Interests</h2>
<p>In my spare time, I will often find myself working on some of my smaller projects such as websites for my friends which I host on my own rented cloud servers. As well as this, I am quite interested in reading about system exploits as it is something that I can apply to my own work in order to keep it safe and secure.</p> <p>In my spare time, I will often find myself working on some of my smaller projects, writing small scalable apps in Rust. Check out my <a href="https://git.luke-else.co.uk/luke-else/">remote git server</a> to see what I am working on now.</p>
<p>I am also an avid member of the VATSIM flight simulation community and spend my evenings interacting with the many members that it holds. I operate as a virtual air traffic controller and will also find myself flying on the network in some of the many events they host each week.</p> <p>I am also an avid member of the VATSIM flight simulation community and spend my evenings interacting with the many members that it holds. I operate as a virtual air traffic controller and will also find myself flying on the network in some of the many events they host each week.</p>
<p class="mb-0">From 2015 to 2020 I was also in the 'Royal Air Force Air Cadets' which taught me a lot of leadership, communication and problem solving skills. Whilst there, I partook in the Bronze Duke Of Edinburgh award and joined the squadron band, both of which were tough but rewarding experiences. Throughout the year we would attend many parades for which our drill and discipline standard had to be impeccable.</p> <p class="mb-0">From 2015 to 2020 I was in the 'Royal Air Force Air Cadets' which taught me a lot of leadership, communication and problem solving skills. Whilst there, I partook in the Bronze Duke Of Edinburgh award and joined the squadron band, both of which were tough but rewarding experiences. Throughout the year we would attend many parades for which our drill and discipline standard had to be impeccable.</p>
</div> </div>
</section> </section>
<hr class="m-0" /> <hr class="m-0" />
<!-- Interests-->
<section class="resume-section" id="contact">
<div class="resume-section-content">
<h2 class="mb-5">Contact</h2>
<form id="contactForm" name="sentMessage" novalidate="novalidate">
<div class="row">
<div class="control-group col-sm-6">
<div class="form-group floating-label-form-group controls mb-0 pb-2">
<label>Name</label>
<input class="form-control" id="name" type="text" placeholder="Name" required="required" data-validation-required-message="Please enter your name." />
<p class="help-block text-danger"></p>
</div>
</div>
<div class="control-group col-sm-6">
<div class="form-group floating-label-form-group controls mb-0 pb-2">
<label>E-Mail</label>
<input class="form-control" id="email" type="email" placeholder="E-Mail Address" required="required" data-validation-required-message="Please enter your email address." />
<p class="help-block text-danger"></p>
</div>
</div>
</div>
<div class="control-group">
<div class="form-group floating-label-form-group controls mb-0 pb-2">
<label>Message</label>
<textarea class="form-control" id="message" rows="5" placeholder="Message" required="required" data-validation-required-message="Please enter a message."></textarea>
<p class="help-block text-danger"></p>
</div>
</div>
<br />
<div id="success"></div>
<div class="form-group">
<button class="btn btn-success btn-xl" id="sendMessageButton" type="submit">
<i class="fa fa-paper-plane " aria-hidden="true"></i> Send →
</button>
</div>
</form>
</div>
</section>
<hr class="m-0" />
<!-- Code
<section class="d-flex flex-wrap justify-content-center" id="code">
<div class="resume-section-content">
<img src="/assets/img/code.png" width="100%" height="auto"/>
</div>
</section>
<hr class="m-0" />
-->
</div> </div>
<!-- Bootstrap core JS--> <!-- Bootstrap core JS-->
@ -300,8 +264,6 @@
<!-- Core theme JS--> <!-- Core theme JS-->
<script src="js/scripts.js"></script> <script src="js/scripts.js"></script>
<script src="js/type.js"></script> <script src="js/type.js"></script>
<script src="assets/mail/contact_me.js"></script>
<script src="assets/mail/jqBootstrapValidation.js"></script>
</body> </body>
</html> </html>

View File

@ -45,7 +45,7 @@ class typer{
} }
} }
var pagetyper = new typer(["//Junior Software Developer", "//Aspiring Backend Engineer"], true); var pagetyper = new typer(["//Apprentice C++ Software Engineer", "//Aspring Rust Dev"], true);
setTimeout(() =>{ setTimeout(() =>{
pagetyper.type(); pagetyper.type();