The Boston Ruby Group and WordCamp Boston

I mentioned a couple months ago that Michael Gyura and I were starting our own consulting business, Poka Yoke Design. We’ve had a good start, and we’ve already launched our first project: the Greenway Health ROI calculator, through our client Hobson & Co.

Our house is still overflowing with half-unpacked boxes. Despite all the craziness of moving (or perhaps because of it…), I was a speaker at WordCamp Boston this past weekend, and also gave a lightning talk at the BostonRB Ruby meetup last week. I wrote all about it on the Poka Yoke Design blog. I’ll be doing my technical posts and work related blogging there from now on, but I’ll always link to new posts from here.

Discontinuing WordPress plugin support

I posted a message in the support forums a couple months ago saying that I was temporarily discontinuing support for my Shashin plugin. I was single-parenting for over a month, and getting ready to move to Japan.

Unfortunately, I now need to say that I’m discontinuing development and support of my plugins for the foreseeable future. I’m living in Japan until the end of the year, working full time, studying Japanese, and enjoying the unique experience of being here with my family.

My work over the last couple years has involved an increasing amount of time with Ruby on Rails, and currently involves little WordPress work. Also, I never developed a business model for my plugins, which means I’ve spent many hundreds of hours over the years developing and supporting them for free. That’s not something I can continue doing.

I’ll keep the current versions available at and they are also available on github, if anyone wants to fork them and continue their development.

The WordPress community has been a fantastic place for me. Because of WordPress I’ve improved my technical skills, made friends, advanced my career, and had the privilege of giving 7 WordCamp presentations over the last few years. So this was not an easy decision. I hope that in the future I’ll have opportunities to contribute to the WordPress community again.

My new job at PromptWorks, and thoughts on developer interviews

I’m excited to officially start my new job at PromptWorks next week. The slogan on their website says it all: “we are craftsmen.” If you’ve seen my Clean Code talk, you know what software craftsmanship means to me. An important aspect of it is to keep improving your skills. I’ve been working at PromptWorks on a contract basis for the past several weeks, and I can tell already that I will learn a lot from my new co-workers. They place a strong emphasis on Agile practices, quality, and working at a sustainable pace. I’ve seen enough so far to know that this isn’t just talk, and that their focus is on building long-term relationships with their clients and their staff. They’re also very involved in the local tech community. Among other things, one of them oversees the philly.rb Ruby meetup group.

They’re also supportive of me working remotely while my family and I are in Japan from July – December this year, which is very generous of them (especially for a new hire).

I interviewed with several different companies recently, and for me, the most dreadful part of interviewing is being asked to do live coding. This is sometimes done in the form of a pop-quiz, where I’m presented with some out of the ordinary coding problem, and I’m expected to write code on a whiteboard, or hack together a quick script to solve it. Other times it’s a surprise mini-project I’m expected to do on the spot. Even though I’ve been coding for close to 20 years, and I’ve had plenty of experience doing quality work faster than expected, I’m terrible at these coding exercises.

The issue for me is that they are nothing like doing real work. The only times in my life I’ve had to think up code on the spot for a surprise problem and write it on a whiteboard is in interviews. And in a real job I don’t think I’ve ever had a project dropped on me out of the blue and been asked to code up a solution in an hour or two, with severe consequences if I make a mistake or try to talk to anyone about it.

My thinking process is largely driven by understanding context (the context of the code, and the context of the business problem), and these coding exercises are usually devoid of context. I’ve also trained myself over the years to not just hack things together. I was told in one interview that, sorry, you won’t have time to write tests. Telling me to take my best practices and throw them out the window in an interview strikes me as completely backwards.

How to best interview programmers is a hotly debated topic. Some very respected people, like Joel Spolsky, swear by the whiteboard-coding approach. Others say you’re doing it wrong:

A candidate would come in, usually all dressed up in their best suit and tie, we’d sit down and have a talk. That talk was essentially like an oral exam in college. I would ask them to code algorithms for all the usual cute little CS problems and I’d get answers with wildly varying qualities. Some were shooting their pre-canned answers at me with unreasonable speed. They were prepared for exactly this kind of interview. Others would break under the “pressure”, barely able to continue the interview…

But how did the candidates we selected measure up? The truth is, we got very mixed results. Many of them were average, very few were excellent, and some were absolutely awful fits for their positions. So at best, the interview had no actual effect on the quality of people we were selecting, and I’m afraid that at worst, we may have skewed the scale in favor of the bad ones…

So what should a developer job interview look like then? Simple: eliminate the exam part of the interview altogether. Instead, ask a few open-ended questions that invite your candidates to elaborate about their programming work.

– What’s the last project you worked on at your former employer?
– Tell me about some of your favorite projects.
– What projects are you working on in your spare time?
– What online hacker communities do you participate in?
– Tell me about some (programming/technical) issues that you feel passionately about.

When I became Director of the web team at the Penn School of Medicine, I led an overhaul of how we conducted our interviews, and we adopted questions similar to these. We focused on behavior-description questions, which are actually much more revealing than you might think, if you haven’t tried them before. We also asked for interviewees to bring in a sample of their code, and we’d have them talk us through it in the interview, and answer any questions we had about it. This was an excellent and reliable way to get an understanding of their experience level and getting past shyness and nervousness. For anyone who’s done half-way decent work, they always become animated when showing off work they’re proud of.

For my interview with PromptWorks, they gave me a small project to do on my own time, to turn in a few days later, which is also a good approach. Apart from that, they also had me do a pair programming exercise, which I was worried about at first, but the focus was on getting an understanding of my thought process and overall problem-solving approach, as opposed to how fast I could tear through it, or trying to hit me with “gotcha” questions.

And they hired me, so I must have gotten something right 😉

WordCamp Lancaster

Giving my talk at WordCamp LancasterGiving my talk at WordCamp Lancaster
Giving my talk at WordCamp Lancaster01-Mar-2014 15:11, HTC EVO, 2.0, 3.63mm, 0.05 sec, ISO 222

I’ve lived in the Philly area more than 10 years, and yesterday was my first time visiting Lancaster, because I finally had a good reason to go! I gave a presentation at WordCamp Lancaster. It was the first WordCamp in Lancaster, and had a single track, with web accessibility as the theme:

The power of the Web is in its universality. Access by everyone regardless of disability is an essential aspect.

— Tim Berners-Lee, W3C Director and inventor of the World Wide Web

There were a bunch of great talks. I especially enjoyed Aaron Jorbin’s and David Kennedy’s:

My talk focused on the language aspects of accessibility, which entailed a discussion of internationalization, localization, and character sets. The title alone was a mouthful: “A11Y? I18N? L10N? UTF8? WTF? Understanding the connections between accessibility, internationalization, localization, and character sets” (slides are below). I managed to make people laugh while discussing character encoding, so I must have done something right.

I also enjoyed having the opportunity to meet and talk with George Stephanis
(@daljo628S), who organized the WordCamp, Scott González (@scott_gonzalez) the jQuery UI project lead, and catch up with Jason Coleman (‏@jason_coleman), Liam Dempsey ‏(@liamdempsey), and Eric (@ericandrewlewis).

WordCamp Lancaster also had one of the nicest designs for a WordCamp t-shirt that I’ve seen.

Here are my slides (if you view them on you can see my notes as well), and hopefully the video will be up on soon.

Get some more coal, it’s time to fire up the old blog engine

I haven’t been blogging for ages – it’s time to fix that. Let’s start with a recap of last night.

The monthly philly.rb meetup at the Comcast Center: how good were the presentations? They were just as good as the view from our room on the 45th floor:

View from the 45th floor of the Comcast Center, where we had the philly.rb monthly meetupView from the 45th floor of the Comcast Center, where we had the philly.rb monthly meetup
View from the 45th floor of the Comcast Center, where we had the philly.rb monthly meetup11-Feb-2014 17:58, HTC EVO, 2.0, 3.63mm, 0.067 sec, ISO 1209

I got a lot out of Nate Olds’ talk, “Refactoring with a View.” A large part of my career has been spent wrestling with big, old, sprawling, messy codebases, so Nate’s real-life walk-through of his strategies for dealing with such challenges was very informative. Check out the February meetup page for more information.

Afterwards, a group of us went to Ladder 15 for beer, where we met up with Maria. She stoically suffered through several minutes of extremely nerdy conversion, before she and I headed to the Boot & Saddle, for a rare evening out without the boys, to see one of Maria’s favorite bands, Cibo Matto. It was a sold out show, and we ended up stuck near the back, but it was still a good time. I tried to take a couple videos, but they didn’t come out. A good introduction to their utterly goofy side is the song Sci Fi Wasabi (I’m Miho Hatori, straight out of purgatory), and their split-screen video for Sugar Water, with one side portraying the visual story in reverse, is quite clever (the ending is in the middle).

I’m presenting at the WordPress ‘Burbs meetup next Monday on Kanban. And on March 1 I’m presenting at WordCamp Lancaster: A11Y? I18N? L10N? UTF8? WTF? Understanding the connections between accessibility, internationalization, localization, and character sets.

Data IO 2013 conference – my notes

These are my notes from today’s Data IO conference

Next Generation Search with Lucene and Solr 4

Speaker’s slides

Lucene 4

  • near real time indexes (used by Twitter for 500 million new tweets/day)
  • can plug in your own scoring model
  • flexible index formats
  • much improved memory use, regexs are faster, etc
  • new autocomplete suggester

Solr (Lucene server – managed by the same team as Lucene)

  • if someone chooses the red shirt, do we have large in stock (pivot faceting – anticipating the next question)
  • improved geo-spatial (all mexican restaurants within 5 blocks, plus function queries to rank them)
  • dstributed/sharded indexing and search
  • solr as nosql data store


  • recommendation engine (LinkedIn uses Lucene for people recommendations). Recommend content to people who exhibit certain behaviors
  • avoid flight delays – one facet – flights out of airports, pivot to destination airports (Ohare to Newark) – origin, destination, carrier, flight, delay times – look at trends over time. Solr has a stats package – you can get averages, max, min, etc
  • for local search, how to show only shops that are open? (Yelp also uses Lucene). 

You added Zookeeper to your stack, now what?

Old way of system management: active and backup servers, frantically switch to backup when active fails

Common challenges with big distributed system

  • Outages
  • Coordination
  • Operational complexity

A common deficiency: sequential consistency (handling everything in the “right” order, when data is coming from multiple places)

  • Zookeeper is a distributed, consistent data store – strictly ordered access
  • Can keep running as long as only a minority of member nodes are lost (usually want to run 3 or 5 nodes)
  • all data stored in memory (50,000 ops/sec)
  • optimized for read performance (not write); also not optimized for giant pieces of data
  • it’s a coordination service
  • A leader node is elected by all the members. Leader manages writes (proposes it to followers, they acknowledge it, then it is assigned and written)
  • nodes can have data, and can have child nodes
  • has “ephemeral nodes” – created when a client connects, destroyed when client disconnects (these do not ever have child nodes)
  • watches: clients can be kept informed about data state changes (just lets you know it has changed, but not what it’s changed to – you need to request it again if you want to know the current value)

Zookeeper open-source equivalent of Chubby

  •  good for discovery services (like DNS)
  • Use cases: Storm and HBase, Redis –
  • Distributed locking

Beware – Zookeeper can be your single point of failure if you don’t have appropriate monitoring and fallbacks in place

Graph Database Use Cases

  • nodes connected by relationships
  • no tables or rows
  • nodes are property containers
  • cypher is neo4j’s query language
  • also used for content management, access control, insurance risk analysis, geo routing, asset management, bioinformatics
  • “what drug will bind to protein X and not interact with drug Y?”
  • performance factors: graph size (doesn’t matter), query degree (this is what matters – how many hops), graph density. RDBMS doesn’t scale well with data size, neo4j does
  • the more connected the data, the better it fits a graph db,
  • NoSQL – 4 categories – key value, column family, document db, graph db
  • popular combo is, e.g. mongo for data, neo4j for searching it (then hydrate the search results from mongo)
  • optimized for graph traversal, not, e.g., aggregate analysis of all the nodes
  • top reasons to use it: problems with RDBMS join performance, evolving data set, domain shape is naturally a graph, open-ended business requirements
  • Gartner’s 5 graphs: interest, intent. mobile, payment


I didn’t take notes during those one (a drop of water from the bottom of my glass got under my Mac trackpad, and my mouse was going crazy for a while)

All the data and still not enough?

  • No matter how much data you have, it’s never enough or never seems like the right type
  • Predictive modeling – will someone default on a loan? Look at data for people who’ve had loans, and who defaulted and didn’t. Use data to make a predictive risk model
  • IID = independent and identically distributed

Example IBM sales force optimization

  • Can we predict where the opportunities are – which companies have growing IT budgets?
  • Couldn’t know what was most important – where were these target companies spending their IT budget (not disclosed)
  • Companies who are spending with us are probably representative of similar sized companies in the same market – use the “nearest neighbor” technique
  • Compared model prediction to expert salesmen’s opinions, except for 15% of them, where the expert’s put the chances at zero. Why the difference? The model mis-identified some of the companies (no good way to cross-reference millions of internal customer records with independent sources)

Siemens – compter aided detection of breast cancer

  • patient IDs ended up predicting odds for cancer. It turns out the ID was a proxy for location (whether they were at a treatment facility or a screening facility)

Display ad auctions – how do we decide who to target?

  • multi-armed bandit – exploration vs exploitation
  • what do we know? urls you’ve visited
  • for something like advertising luxury cars, very few positive examples (people don’t buy them online)
  • There is no correlation between ad clicks and purchases
  • Better to look at – did the person eventually end up at the company’s home page at some point after seeing the ad?
  • target people who the ad can actually influence (i.e. not people who already bought the product, or never will)
  • but there’s no way to get data for that
  • Counterfactuals – you can’t both show and not show someone and ad, and observe subsequent behavior. You have to either show it or not show it
  • Ideally, build a predictive model for those who see the ad, and another model for those who don’t
  • But the industry doesn’t do that – it’s all about conversion rate

Advertising fraud

  • Malware on sites generating http requests
  • Very difficult for ad auctions systems to detect
  • Detect by looking at traffic between sites. Foe example, malware site womenshealthbase generates massive traffic to lots of other sites, not about womens health
  • they make money by visiting a site with a real ad auction system. Then bid prices go up because of your traffic, which drives up ad revenue traffic on womenshealthbase
  • Auction systems now put visitors from these sites in a penalty box, until they start displaying normal behavior again

What’s new with Apache Mahout?

  • Amazon: customers who bought this item also bought this item – best known Mahout example
  • Mahout implemented most of the algorithms in the Netflix recommendation contest
  • In general, finds similarities between different groupings of things (clustering)
  • Key features: classification, clustering, collaborative filtering
  • Automatically tags questions on stack overflow


  • recommend friends, products, etc
  • classify content into groups
  • find similar content
  • find patterns in behavior
  • etc – general solution to machine learning problems

[I’m leaving it most of the details about performance improvements and the roadmap for upcoming refinements – below are other interesting points]

  • Often used with Hadoop, but it’s not necessary. Typically included in Hadoop distributions
  • Streaming K-means – given centroids (points at the center of a cluster) determine which clusters other points belong in
  • References: Mahout in Action (but a bit out of date), Taming Text
  • Topic Modeling He wasn’t sure what the full feature set is – he’s pretty sure it doesn’t generate topic labels for you

Shashin 3.4: responsive design and social sharing

Shashin 3.4 is now available for download at It has great new features for sharing your photos, and for responsive design (so your pictures will look good on any size display). Check out the Shashin examples page to see it in action.

Important upgrade notes:

  • This version of Shashin comes with a customized version of prettyPhoto. On the Shashin settings page, you will want to pick prettyPhoto as your viewer to take full advantage of the new responsive design and social sharing features.
  • If you customized your Shashin stylesheet (shashin.css) in a previous version and placed it in your theme folder, you will need to update it to incorporate the latest changes in the new version.

New features:

  • Sharing: you can now share a link that will take you directly to any Shashin photo on your site, and automatically open it in prettyPhoto. The sharing links appear below the caption in prettyPhoto.
  • Mobile display of slideshows: I’ve customized the version of prettyPhoto that comes with Shashin to improve its display on mobile devices (if you are using Fancybox, I’ve disabled it on mobile displays, as it simply doesn’t work very well on them).
  • Two thumbnail design options to choose from: one is almost exactly the same as the design Shashin has always used – showing the captions underneath the thumbnails and putting a border around each thumbnail. The other design gives the thumbnails rounded corners, a slight box shadow, no borders, and puts the captions in an overlay along the bottom of the thumbnails. Long captions are truncated, to prevent them from covering the entire thumbnail. You can specify which design you want on the Shashin settings page.
  • Responsive design for thumbnail layouts: Shashin will resize and rearrange thumbnails to best match the available space on the page. The final result for a given layout depends on several factors. Let’s say you want to display 3 thumbnails in a single row. If you enter “3” for the columns in your Shashin shortcode, Shashin will try to give you 3 columns. How many you actually get depends on how big the thumbnails are, and how wide the content area is. If the content area isn’t wide enough to accommodate the thumbnails at their full size, Shashin will scale down the thumbnails to about 90% of their actual size to maintain the 3 column layout. After that, it will let the columns start to “wrap,” so the thumbnails don’t shrink too much (that is, the number of columns will go down). If you gradually narrow and then widen your browser window you can see Shashin re-arranging and scaling its thumbnails on the fly.

Implementing responsive design for Shashin was a real challenge. This is because the traditional tools for responsive design – media queries – are not helpful with Shashin. Since Shashin is a WordPress plugin that needs to work in any theme, I couldn’t make any assumptions about the page layout. So basing layout decisions on the display width of the viewing device or the browser window is not helpful. What I need to know is the current width of the HTML element Shashin happens to appear in, which could be anything. So I implemented Shashin’s responsive design with a mix of CSS and jQuery.

Please post any support questions in the support forum for Shashin, not here.

The ElectNext workation in Lake Tahoe

ElectNext team dinner in TahoeElectNext team dinner in Tahoe
ElectNext team dinner in Tahoe13-Sep-2013 11:58, Canon Canon PowerShot ELPH 110 HS, 2.7, 4.3mm, 0.05 sec, ISO 320
The ElectNext team at Maggie's PeakThe ElectNext team at Maggie's Peak
The ElectNext team at Maggie's Peak14-Sep-2013 03:34, Canon Canon PowerShot ELPH 110 HS, 8.0, 4.3mm, 0.006 sec, ISO 200
Granite Lake, along the trail to Maggie's PeakGranite Lake, along the trail to Maggie's Peak
Granite Lake, along the trail to Maggie's Peak14-Sep-2013 02:18, Canon Canon PowerShot ELPH 110 HS, 8.0, 4.3mm, 0.004 sec, ISO 200
View from the top of Maggie's PeakView from the top of Maggie's Peak
View from the top of Maggie's Peak14-Sep-2013 03:15, Canon Canon PowerShot ELPH 110 HS, 8.0, 4.3mm, 0.003 sec, ISO 200

I’ve been with ElectNext for a little over a year, and this past week was only the third time since I started that everyone in the company was in the same place, and the first time that it was for more than a day. There are currently 7 of us, roughly equally divided between New York, Philadelphia, and San Francisco. So a typical workday entails a good amount of time in Google Hangouts, which is a great tool for keeping a distributed time on the same page. But there are a couple things for which there is no substitute for spending time in person: one is building team relationships (here’s a great article on building distributed Agile teams), and the other is brainstorming around challenging problems. As good as Hangout is, and tools like RealtimeBoard, there’s still no substitute for a team putting their heads together in person around a whiteboard or big easel pad.

We rented a 4 bedroom/7 bed house on the north side of Lake Tahoe, right across the street from the lake. This was a workation, which means we put in at least as much work time as usual. But we also enjoyed our evenings and our surroundings. We each had a turn preparing dinner, and sat down most nights around 8:30 to eat, staying at the table until late into the night. And we took the day off on Friday for a hike up to one of Maggie’s Peaks.

Click the album cover below to see more great pictures!

2013 - Lake Tahoe
2013 - Lake TahoeSep 10, 2013Photos: 26

Doug Engelbart passes away

If you use a mouse, hyperlinks, video conferencing, WYSIWYG word processor, multi-window user interface, shared documents, shared database, documents with images & text, keyword search, instant messaging, synchronous collaboration, asynchronous collaboration — thank Doug Engelbart

That quote is from one of Engelbart’s peers. It’s worth taking a few minutes to read the rest of his post, to learn about Doug Engelbart. Personal computing and the internet would not be what they are if it weren’t for his contributions.

About 14 years ago, when Maria and I worked at Stanford, we had dinner with him and his girlfriend, and another couple. He couldn’t have been more pleasant and down to earth. At the time I knew a bit about his history, but not the full extent of his contributions. And I left that dinner still not knowing – he was a modest man. Dave Crocker is someone who worked with him, and he wrote the following last night, after Engelbart’s daughter shared the news of his passing: “Besides the considerable technical contributions of Doug’s project at SRI, theirs was a group that did much to create the open and collaborative tone of the Internet that we’ve come to consider as automatic and natural, but were unusual in those days.”

The San Jose Mercury today re-published a profile of him from 1999:

But the mild-mannered computer scientist who created the computer mouse, windows-style personal computing, hyperlinking–the clickable links used in the World Wide Web–even e-mail and video conferencing, was ridiculed and shunted aside. For much of his career he was treated as a heretic by the industry titans who ultimately made billions off his inventions…

Engelbart is perhaps the most dramatic example of the valley’s habit of forgetting engineers whose brilliance helped build companies–and entire industries. CEOs fail to mention them in corporate press releases; they never become household names. Yet we use their products, or the fruits of their ideas, every day…

“We were doing this for humanity. It would never occur to us to try and cash in on it. That’s still where Doug’s mind is,” explains Rulifson, director of Sun’s Networking and Security Center…

Engelbart’s unwillingness to bend was in evidence when he met Steve Jobs for the first time in the early 1980s. It was 15 years since Engelbart had invented the computer mouse and other critical components for the personal computer, and Jobs was busy integrating them into his Macintosh.

Apple Computer Inc.’s hot-shot founder touted the Macintosh’s capabilities to Engelbart. But instead of applauding Jobs, who was delivering to the masses Engelbart’s new way to work, the father of personal computing was annoyed. In his opinion, Jobs had missed the most important piece of his vision: networking. Engelbart’s 1968 system introduced the idea of networking personal computer workstations so people could solve problems collaboratively. This was the whole point of the revolution.

“I said, ‘It [the Macintosh] is terribly limited. It has no access to anyone else’s documents, to e-mail, to common repositories of information, “‘ recalls Engelbart. “Steve said, ‘All the computing power you need will be on your desk top.”‘

“I told him, ‘But that’s like having an exotic office without a telephone or door.”‘ Jobs ignored Engelbart. And Engelbart was baffled.

We’d been using electronic mail since 1970 [over the government-backed ARPA network, predecessor to the Internet]. But both Apple and Microsoft Corp. ignored the network. You have to ask ‘Why?”‘ He shrugs his shoulders, a practiced gesture after 30 frustrating years…

Here is a set of highlights from his famous 1968 demo of the systems his team developed, showing early versions of computer software and hardware we now consider commonplace. In the 8th video, he shows their online, collaborative document editing system, which looks like an early version of Google Docs. In the 3rd video, he describes the empirical and evolutionary approach they took to their development process. This was another of his ideas that the industry discarded, only to finally re-discover its value, more than 30 years later, as what’s now called Agile development.

Shashin 3.4 Beta: please help test

The beta version of Shashin 3.4 is ready. It has a lot of front-end design changes, which means its needs testing in a variety of browsers. So if you’re comfortable installing WordPress plugins manually, please download the beta version from GitHub and give it a try (important note: rename the folder after you unzip it to “shashin”). It especially needs testing in everyone’s favorite browser, Internet Explorer. Note since this isn’t a normal upgrade through the repository, you will need to deactivate and re-activate Shashin to update its settings.

The biggest new feature is responsive design. This was quite a challenge: since Shashin is a plugin that should work with any theme, the thumbnails it displays need to be responsive to their containing element (the <div> containing a post). This means I can’t just rely on media queries, as they require knowledge of the entire theme layout. So the first thing to note is that if your theme isn’t responsive, Shashin won’t be either. If your theme is responsive, Shashin thumbnails will shrink as the available width decreases. I also tried to find a happy medium for honoring the number of columns you specify for displaying your thumbnails. The rule I’m applying is this: if the thumbnails shrink to less than 80% of their intended size, then the columns will “float”, meaning that the number of columns will go down as the page gets narrower. Also, Shashin detects browser resizing, so you can expand and contract the width of your browser to see how Shashin responds.

Captions now overlay the bottom of the thumbnails, instead of appearing below them. A rule I’ve applied to displaying captions is that they will not appear if they would cover more than 30% of the image.

I’ve improved the browsing experience when you are paging through albums that contain a large number of photos. The “previous” and “next” links will scroll you to the top of the next thumbnail set as you page through them. I’ve added the navigation controls to the bottom as well, which several people have requested.

There are various other updates as well. The complete list is in the Change Log in the readme file.

Please use the comments section on this post for any feedback.

Older Entries »