Note: All websites are in client control and are no longer maintained by me unless stated otherwise.
This personal site is a project implemented as a true continuation of my original SIUE student site. It has gone through a few iterations and came to know its place on
joshuaspann.github.io until I purchased
joshuaspann.com. The 2013-2019 version of the site was made up of pure HTML from scratch, though it did exist in NodeJS (hosted from home) for a few months in 2017.
As of September 2019, the site utilized markdown mixed with HTML, all hosted on GitHub’s Pages. The content is composed in markdown due to markdown being much faster than typing up static html. The content is then managed via a build script file. The script would merge all markdown files with page templates, allowing as little work as possible in creating a static site. The resulting markdown files were composed into static HTML pages and deployed to GitHub where GitHub pages would do the rest of the hosting magic.
I integrated a custom form into the site’s aside. The form utilized PostMail to send an email notification when an individual wanted to register for a newsletter. This is a bit hacky and a bit manual, but is the only option for a statically-hosted site.
The site is an example of how one can create a static website using a CMS workflow similar to Wordpress. It is a hack-together that showcases the best examples of content management as well as administrative skills to have a user-friendly way to hook up a freely hosted website.
You can access the latest version of the site here or you can look at the github page (which is really pointless as it’s managed by Publii): https://github.com/JoshuaSpann/publii-test
A fake charting system implemented in Wordpress, maintained during my time at SIUE. The initial design was to be a system built from scratch or existing FLOSS EMR/EHR systems. Administration desired a Wordpress-based solution because they were sold during a conference talk about using Wordpress for personal hosting. I had to work within constraints but was able to extend Wordpress to meet simulation needs.
The site is integrated with SIUE’s Central Authentication Server, allowing access only with a proper university-issued username and password. Most content is created like a regular Wordpress site though there is a custom navigation element added to each page. The layout poorly attempts to mimic Epic but in a simpler and reduced design. The system was modified to be more easily customized and focuses on all fake patients from a single-page-app perspective.
The goal is to further extend the system so it can be integrated with our LLEAP simulation software. The integration will allow automated changing of patient records during sim. An action in LLEAP will trigger a change in the MAR or the Lab results during sims for a more immersive experience. The system is also planned to allow student practice during lab time, which will routinely empty all submissions within a given period.
A custom Wordpress site hosted on my servers when I provided web hosting through my web-design business, Monada. There was nothing overly spectacular, just a simple Wordpress site that implemented a custom CSS theme. After an extended grace period of late payments the site was shut down.
A customized weebly site that was made under my personal web-design business: Monada Software (formerly Quantum Develop). It was customized on the PHP level to better control functionality of the site and was made to be easily maintained by the client. I established the artistic direction of the initial site in 2017 and helped them easily integrate an existing form (in an iframe) into the website. I also helped with DNS redirection to ensure that the website would transfer from the original GoogleSites page to the Weebly site.
A dynamic website that was primarily for content display. The website was built with responsive design as a core approach from the onset. It was written from the ground up to be more scalable and fit more closely with the MVC (Model View Controller) architectural style. It was the first major PHP-based website that I had developed.
A project created by an instructor from SIUE, FREUD was an engine that was part of an applocation named FIRST. The project was a web-based solution that dealt with quotes and insurance for weather damaging and repairs. I contributed to display logic and improving the UX design. The FREUD/FIRST system was an internal project rather than a public site/system.
One of many senior projects for SIUE. The website acted as a display portal for all of my university work from development projects, artworks, music, and even a personal resume. Home of the Hat has since been reimagined into two separate websites. One is now more of an online resume showcasing professional work, while the other is a project website for graphic design, open source, and other miscellaneous projects.
In late 2018 SIUE had changed the network configuration that ended up scrapping all of the legacy sites on the old server. They established a new setup since then so the original site has been lost.
All of my available software projects can be viewed on GitHub! You can view them on github.com/joshuaspann/
SimMonitor: A Web-Based Patient Monitor
Created to provide a fairly versatile and open-source vital signs monitor that can be used in simulation. It is intended to be customizable, extensible, and cross-platform so it can be utilized in a variety of situations from simulation and training to photography and art.
Due to limitations and costly licenses of simulation vendor software, as well as highly fragmented and platform-locked options, the need arose to have a more flexible solution. The vendor’s vitals monitor application was limited in styling and customization. It also was not flexible enough to allow multiple monitor instances (with different target vitals and monitor layouts) be connected to the same simulator, creating duplicates on every connected monitor instance. Freeware options were limited to a small number of platforms and did not provide the freedom to improve and extend the baseline software to meet specific needs (ie, yet another phone app).
This project attempts to allow customization first, with feature-parity after. Created as a web app, it allows full and easy control over vital signs and layouts, also allowing users to extend it with their own custom assets. The goal is to have it draw and animate vital signs and waveforms in an easy, user-defined way.
To check out the project, visit https://github.com/JoshuaSpann/sim-monitor or you can see it in action here at http://joshuaspann.com/sim-monitor.
LoveSong: A random melody generator inspired by the GodSong utility from TempleOS.
Sometimes a creative person needs a little nudge in the right direction. The goal of the library is to randomly generate music for the user that they can have as a starting point for creating music and melodies.
There is a procedural music generator for TempleOS named
GodSong. The user is met with a dialog that allows them to set options like melody complexity, whether the melody will contain rests, and the octave the melody should be on. The next screen has a timer that increments in hexadecimal format. After a certain number of clicks a monophonic melody is generated.
Inspired by the above functionality,
LoveSong attempts to go a bit further and create savable data. The melodies can be saved in numeric format, based off of the note number in the western chromatic scale, or in alphabetic format, using the note letters instead. The data will also attempt to be exported to MIDI data that can be used in musical application.
Parameters will also be set controlling the key signature, accidentals, and melody length if the user would like to. Options will also allow the melody generation to follow basic rules and principles of music theory. By creating the library in Haxe, it will make it easier to port it to a variety of software applications, though a bit unoptimized.
To see the latest changes and experiments with the project, you can examine the repo at github.com/JoshuaSpann/love-song.
Charte: The Open-Source EMR-Simulator Web App
Because every other charting system didn’t fit my specific needs. Paid ones were locked down, more manual, dated-looking, and offered no freedom or control. Free ones focused on being a comprehensive solution that was too much for basic sim needs. Something simple was needed for simulations; something simple and free that institutions outside of hospitals could afford.
The web app is an attempt to create a basic “flowsheet” view that can be read and temporarily modified from a nurse’s perspective. I decided to make it highly flexible and cross-platform as well as work perfectly fine on its own when there is network downtime. A typo made “charte”, which can mean “Chart Emulator”.
The app is intended to run offline and sync with specified servers when online. It will call multile servers to merge various charting data objects so there can be better allocation and sharing of simulated charting data. This also allows integration with other solutions while still allowing full customization.
It’s meant for learning usage to help follow and apply the workflow behind common digital charting systems, such as EMRs/EHRs.
To see my latest changes and experiments with the project, you can examine my repo at github.com/joshuaspann/charte.
A default HTML date field was added for optimized date selection via the web browser. Once a date was entered or the field’s value changed, the date would be formatted into the requisite format that Qualtrics desires, including the pesky leading 0s. The formatted date would then be pushed to the actual date field, which was hidden until an error occured which would expose all fields. The time of year, Spring Summer or Fall, along with the entered date’s year were also needed. A custom dropdown and a few event listeners allowed me to create a string on the change of the dropdown or the date fields. The listener generated a needed string/text that would be put into the actual hidden Qualtrics field.
JOSH: The Java Object Shell
Inspired in part by the original concepts behind Powershell with a bit of TempleOS for good fun. The shell is an attempt to handle Java objects natively instead of piping text back and forth between apps. The name of
JOSH is purely coencidental; I’m not that egotistical to name it after me. The name came from the initial project goal, having an operating java shell. I wanted the name to be easy to say and catchy like “bash” and thought up “The Java Operating Shell”. I thought of how to compact it down and got “JOSH” as a result.
JOSH is an attempt to make certain features and ideas easier to implement. It focuses on experimenting with new ways to handle data as well as navigation and commands. There is the concept of “nodes”, where numbers represent the counted node in the working directory. You can use nodes in interesting ways, though the shell will default to files or folders with numbers in the name if they exist.
The shell attempts to guess the intentions behind commands to shorten them. You enter a string suffixed with a file delimiter and it attempts to change to the directory. You can also enter a node number to imply the same.
If you start a command with a number, it will attempt to iterate the following command that many times. If the number is followed by numbers, then it is assumed to change to those directories. The commands are intended to work as standalone applications or they can be used as intended as a part of
To see my latest changes and experiments with the project, you can examine my repo at github.com/joshuaspann/josh.
Taskbar: Added Features
Added functionality to the original Taskbar repo. I noticed that it did not have the ability to customize the ‘start menu’ icon outside of two embedded images within the app. I added the ability to allow the user to specify if they desired to use a custom image from their phone. If the setting was checked and a file specified, the taskbar would update with the custom image the user chose via a filepicker.
To see my latest changes and experiments with the project, you can examine my fork at github.com/joshuaspann/taskbar.
cklist: A Minimalist Checklist Manager
A simple command-line checklist application that manages lists through files and folders. It is basically a merged reimplementation of common Unix commands like
rm -rf. The concept came as a way to reduce keystrokes while managing checklists made from files. The project page is at github.com/joshuaspann/cklist
Raspy LCDriver: Controlling a Character LCD from the Pi
An excercise to get familiar with the Raspberry Pi’s GPIO pins on Linux. Inspired by some 8-Bit Guy YouTube videos, I reimplemented David’s solution on a RaspberryPi 3 instead of a Commodore64. It started as an 8-bit counter up to 256 values with just LEDs. I added python code to parse a given character to the character code on the LCD. I did a lot of research and created my own circuit to manage and control a large character LCD. After printing out many characters in a row, some tweaks were made to have the LCD print messages.
I then started creating a shell in Python, which would take in keystrokes and parse commands like bash or any other shell. The difference was to have it save each character and send the LCD code to the screen in real time. It was almost complete but was abandoned with an increased workload and wedding planning. It is currently two separate applications that have yet to interface with one another.
timec: A Simple Time Converter
A command-line calculator that converts given times into different formats. It started to simply convert a mm:ss format to a decimal formatting of mm but grew with more needs. I added the ability to make it convert times from 24-hour to 12-hour formatting.
The need also arose to find the time difference between two times in a mm:ss format, so I added that as well. Out of curiosity, as a benchmark to compare multiple languages, I rewrote it in Haxe then in Python to compare how each platform performed. I also looked at compiling it to C++ via Haxe’s utilities and Cython. Rewriting it helped me to find areas to improve the software and give me ideas of additional functionality.
The project page is at github.com/joshuaspann/timec
Arch-Linux Node: A Persistent Live USB
A series of steps and commands to make a persistent Arch-Linux install on a USB stick. It is bootable, while files can be accessed by all platforms without the need to boot. It boots on most i386 and amd64 processors in both BIOS and UEFI modes. It originally used a UDF-formatted drive but concerns led me to partition the drive to have a shared partition which improved filesystem resiliency for the OS partiton while keeping the open, cross-platform-compatible idea.
The shorthand notes/instructions can be found at github.com/JoshuaSpann/help/blob/master/linux/portable-arch-usb-install.md
Simulation Checklist: A Mobile Management App
A quick project to get familiar with the Flutter framework and Dart language. It was intended to display a list of checklists that could be individually viewed and modified. The changes would not be persistant outside of adding/deleting items. Due to personal time constraints and Flutter feeling like Google’s take on ReactNative, the project has since been abandoned. It is missing the ability to save or modify checklist items, though it is usable.
Daily Droid: A Smartphone Journaling App
A configurable, multi-activity Android applicatioin that acts as a glorified text editor. It was concieved as a response to my dissatisfaction of having to remember everything and handwrite it at the end of each day. I would lose 2-4 hours of sleep writing in my journal. Diction significantly reduced the time, but it was hard to convert to text accurately and took up significantly more space. Not to mention, trying to search an audio file for something was very impractical (especially if you forgot the date). Typing at the end of the day was better, but everything was just bundled into a large amount of time wasted. It was built due to other text editors being slow, rife with ads, or counterintuitive.
It creates text files named by the timestamp created. It uses quick buttons to navigate and add markdown to the text files. If the user specifies so, the app can also auto-log incoming and outgoing calls as markdown. Users can also persistently change colors of the current text file to one of many preset colors for easier organizing and customization.
I was inspired by the default Memo app on Samsung smartphones, but put off that it exported to PDF. I wanted timestamps, markdown, the ability to navigate the document with a few taps. I had to start from scratch, so I wrote my own. It started as a “Text File Writer” that simply allowed a user to save text files via a single activity. It had the ablity to not only create text files, but add time stamps at the tap of a button.
The need for enhanced navigation caused more buttons to be added, allowing navigation between the beginning and end of a file. I made it autosave as long as characters are added, allowing accidental deletions to be undone. The default scroll behavior was not fluid and did not traverse well, so I reconfigured that. I then added the ability to colorized given text files as a way to visually categorize them. I made it capable of automatically log incoming and outgoing calls by inserting timestamps with the basic call information into the text file. I added the ability to manually and hot-refresh the file to ensure that no up-to-date changes were lost in the background. The app also allows users to adjust settings, such as syntax highlighting for markdown support or the ability to control whether calls are auto-logged.
The project page is at github.com/joshuaspann/daily-droid
LLEAP Patient Info Plugin: An Instructor Application Extension
A simple extension to the LLEAP Instructor App (IA) that allowed the viewing of patient info given in scenario files. It obtains the patient data and display it in the IA interface as a window that can be added/modified. Certain tweaks have to be made to the scenario file with UD variables as the Laerdal SDK does not support all patient info like the patient name, birthday, etc. It also was bundled into a self-extracting executable that would extract a copy of all DLL files and the plugin to the proper Laerdal directories. It was additionally improved to load up pages from the SIMS “charting” system in the default web browser.
Dot QR: An Inkscape Plugin
A customization of the base barcode extension in Inkscape. A checkbox for using dots instead of squares was added to the QR Code GUI’s .inx and the rendered QR code would be rendered in a pretty, dotted format too. This reduced manual, time-consuming work to the instant check of a checkbox and click of a button.
You can download a zip file of DotQR here.
Video Text Balancer: A Plugin to Ease Video Editing in Blender
A Blender3D UI customization in Python to help speed up video development. A button was added in the VSE to loop through all selected text objects in the video editor, make them have a minimum specified length, and then space them apart so they do not overlap.
Because a workflow didn’t allow the Opportunity Stage field to be modified via the workflow. An apex trigger was used instead. The trigger ran on the creation of new records only. If there was a certain country code (US or UK) that was chosen for the record, the Opportunity’s Stage would be auto-updated to a custom RMA picklist value. The need was to help expadite the Salesforce proccess of the client and to better match their business process.
A massive scheduled Apex class that automated the RMA process daily. Automated emails would be sent 2 days after the owning Case’s follow-up date and the final email would vary when it was sent. The final email depended on the RMA type being old process or new process. Checks would be run to determine if the emails, phone tasks, and all other tasks were completed before progressing. The first email would be sent, then if it was a phone task would be assigned to a user. If the (standard process) phone task was assigned and then completed, the RMA would be flagged as charged and a final email would be sent. If the final email was sent, then the case would auto close (if old process) or a task would be assigned to close the owning case (if standard process).
The automated apex emails were also linked to the owning Case’s activity history and open activites. This project had a lot of scope creep since its onset, where my company was willing to add changes since the client did not have a standard payment process. It evolved from a simple email and phone?call checker to a data factory that also closed orders and further made the functionality dynamic; requiring multiple records from great grandparent and great great grandchildren objects that were out of the normal Salesforce limits on generational data to object traversal.
A quick pet project to provide basic GET and POST functionality provided via HTTP REST callouts. Custom fields and tables were made to match the structure of a Teamwork Projects organization. API tokens and authentication was dynamically handled and allowed the posting of time entries from Salesforce to Teamwork. The project utilized callout classes and triggers to fire off correctly whenever a time entry was made or updated. The connector also was created as a Salesforce App that ran in the traditional layout as well as Lightning and the Salesforce1 mobile app. This allowed for time entries to be tracked and reported in Salesforce to run a greater variety of reports than Teamwork provided. The goal was to gain more knowledge of both the Teamwork API as well as direct Salesforce integration with other web applications.
This was a form customization that utilized the base project form deeply stripped of its excess functionality. The form was made simple, to load all projects that met a date range, or met a project code, or met a project code within a given date range. The form was the first customization at my company where an updatable BAQ was linked to a form customization and updated via an impl on the adapter business object. The BAQ would then flag certain fields that met the criteria given in the form and update via the BAQ. However, the BAQ ran on a table that did not call the correct methods and had issues inserting more than 50 records to the database. The limitations slowed down the system and a method directive was decided to be the best approach moving forward.
A project where a previous middleware company left broken and unfinished code on a client’s Salesforce organization. The default code was improved upon and I was able to complete it and make it fully functional. The program also had some improvements for displaying error messages and error handling. The code was then modified to work with new use case requirements that required an extension on the existing apex code.
There were 3 major pages involved: credit card selection, credit card entry, and a credit card assignment page. The selection page allowed selection from a listing of valid credit cards assigned to the account. The entry page allowed entry of a credit card or modification of an existing one. The assignment page allowed credit cards to be assigned to accounts.
A simple application that performed financial lookups and reporting on a SQL Server database. The lookups filtered inventory and tracked costs per warehouse as well as per region and overall. The financial report would also perform complex business calculations and then write to Excel. SSRS was not perferred by the project manager, so elevated permissions and outdated techniques were used to dump the data to an Excel file.
A concept application was also made as a backup and would perform the same as a standalone C# app that ran as a cron job. The TSQL would then be set to run on scheduled intervals every few days, but not as a stored procedure. The Excel file would be written but not overwritten once created. New files would be added for each run to provide a better snapshot for the client. Excel templates were also created to meet the client’s needs.
A client requested an extension to the Epicor base Price List Inquiry form. The extension required a custom sheet that allowed quick addition of Quotes or Orders with a miniature form that would load new or existing entry forms. The forms would auto?populate based off of the parameters launched from the other form. I was the first in my organization to implement such functionality. The Quote/Order forms would populate billing and shipping information differently and had to be extended to support the data sent from the PLI form. Quotes required the same bill-to and ship-to address as the customer’s address. Orders would defult to the standard billing/shipping addresses, but would also auto select a proper warehouse to link to the order.
A Scribe platform application that allowed reporting to be done in Scribe on the Scribe organization’s usage history. This called the Scribe API to pull organization usage and details for each child organization. It would also calculate times spent processing records as well as errors encountered. I initially started the project, swapped between development projects, and trained other developers to get them up to speed with the project.
A custom RMA replacement order page was created, almost identically matching the Create Free Part RMA Order Visualforce Page project. This form, however, looked at all products. Another difference was the ability to see all products or only products meeting certain groups or other criteria. The criteria would be the RMA type as well as user?selected radio buttons.
The page would also have the ability to filter products by their associated pricebook entries. All pricebooks were set to a picklist which was then defaulted to the Retail pricebook, or any pricebook with “retail” in its name if there was no lone “Retail” pricebook. The selected pricebook would not only filter the products available, but it would also change the prices accordingly. Only pricebooks from the RMA account’s default pricebook group were shown.
A project breifly picked up by me after another developer could not work on it for a while. I took an existing form customization layout and added in the functionality to allow the entry and modification of defect entries as well as defect details per entry all in the same form customization. The trick was to allow out?of?the?box Epicor functionality but create the same grid display results as a BAQ (Business Activity Query). The issue was working with the Epi Data View and having to code around default issues with utilizing a child data view in a parent.
The child was a UD (User?Defined) extenstion of the parent table. The similarity of Key fields required careful planning and a creative workaround in the code. The child UD data view was integrated instead of a BAQ to allow direct Paste to Excel functionality which was a must for the client.
My first Epicor project. On the Job Entry Form, when the job was flagged as engineered, all 1st level Subassemblies and Raw Materials would be grouped into unbundled parts. The unbundled parts showed up on a custom sheet on a bottom grid. A user could then select multiple Job Assemblies and Materials from the grid and bundle them at once. Bundled parts will be transferred to an upper grid, where advanced calculations are done to determine remaining quantity. Any bundled parts exceeding the required quantity (resulting in negative quantity in bottom row) will flag rows to be marked as red.
The user could update, add, delete parts from a bundle. BPMs fired off to successfully and efficiently manipulate data much faster than an adapter or impl would provide. After bundling parts, the user will move to a 100% custom Bundle Management (Bundle Shipping) form. The custom form would allow bundles to be flagged as completed.
A user can also flag a job as completed by shipping it. Default values are auto assigned for more rapid bundling and shipping. Bundles can be assigned to a load master with an auto?generated bill of lading number if the user decides to do so.
My first Salesforce project, the Free Part RMA (Return Material Authorization) Page utilized the Salesforce MVC pattern using traditional tools. The RMA was a custom object implemented to track returns in Salesforce. The page allowed onlt products flagged as “Free Part Eligible” to be selected from a page block table with a specified quantity and grouped together for an RMA order. The layout used two grids where the products were selected from the bottom table and assigned to the top table. Each row in the page block table had a Select button that pulled the product from the bottom grid to the top grid. Products could be removed from an order (top grid) by clicking a page link while the quantity and RMA reasons could be modified for each individual free part order record.
My first Scribe API project, the subscription checker was built into an already extensive application that covered two versions of an API to integrate with. The checker would sent a web callout to a SQL Server instance that would return queried key values and information like key expiration dates and key hashes. These values would then be evaluated on the Scibe client side and prevent organization access if the subscription key was invalid or expired.
The server-side portion of the Scribe API Subscription Checker used a custom database that was created to work with an old, existing IIS API. The IIS app was updated and the database would hash, salt, and securely store user data as well as subscription keys. It would then return the needed values through SOAP.
A simple presentation in the form of a playable minigame. As I was graduating the School of Business, I needed to give a presentation that sold my skillset. I found a unique way to mix business presentation with computer systems and art in the videogame medium.
The presentation was built with the Blender Game Engine in the Blender 3D software. The player is a rolling ball with a fedora hat (my signature look) that rolls to different parts of a platform. The player can view basic presentation content in any order they desire or they can simply roll around the stage.
You can download a zipfile of my presentation here.
A small extended customization of an existing template database and form structure. The system was architected and built initially to work exactly as the client specified but project management decided that form was perferred over function. As sole developer I had to write complex queries and VBA code to extend the template to meet the use case requirements. Much of the existing template fields were replaced and programmatically populated from the VBA code extensions and Macros.
A script that gives you the value of a traditional 3-band resistor based on the bands’ colors. It was made as I was starting out with electronics to help me quickly get resistor values until I could remember the color values myself. The script ran a command-line app that prompted for specific values: