<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Preflight</title>
    <description>The latest articles on DEV Community by Preflight (@preflight).</description>
    <link>https://dev.to/preflight</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4023200%2F8fe1786a-f300-4a4e-a7c1-b84151422136.png</url>
      <title>DEV Community: Preflight</title>
      <link>https://dev.to/preflight</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/preflight"/>
    <language>en</language>
    <item>
      <title>A document QC tool — and how to check it</title>
      <dc:creator>Preflight</dc:creator>
      <pubDate>Mon, 20 Jul 2026 21:40:00 +0000</pubDate>
      <link>https://dev.to/preflight/a-document-qc-tool-and-how-to-check-it-1b1p</link>
      <guid>https://dev.to/preflight/a-document-qc-tool-and-how-to-check-it-1b1p</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A check that cannot be determined from the file says "not evaluable" — never a silent pass.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;A check that cannot be determined from the file says "not evaluable" — never a silent pass. It looks fine right up until it doesn't — in a viewer, on screen, in the happy path — and the failure only shows at the point where it's expensive to fix.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually happens
&lt;/h2&gt;

&lt;p&gt;This is a determinable property of the file: you can check it deterministically, without running the document and without guessing. Preflight does exactly that as part of its correctness-first pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest caveat
&lt;/h2&gt;

&lt;p&gt;not_evaluable is a first-class verdict; it never counts as a pass. That distinction is the whole point of the tool — a check that can't be determined from the file says &lt;strong&gt;not evaluable&lt;/strong&gt;, never a silent pass. A QC tool that passes everything hasn't checked your document; it has flattered it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;Preflight parses the print formats most tools can't open (PDF, AFP/MO:DCA, PCL 5, PostScript, IPDS) and runs deterministic checks like this one — free, in your browser, nothing uploads. → &lt;a href="https://preflightdocs.com" rel="noopener noreferrer"&gt;https://preflightdocs.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>compliance</category>
      <category>printing</category>
    </item>
    <item>
      <title>A recipient who gets nothing: detecting a whole missing mail piece with order-independent set continuity</title>
      <dc:creator>Preflight</dc:creator>
      <pubDate>Thu, 16 Jul 2026 21:22:51 +0000</pubDate>
      <link>https://dev.to/preflight/a-recipient-who-gets-nothing-detecting-a-whole-missing-mail-piece-with-order-independent-set-1deh</link>
      <guid>https://dev.to/preflight/a-recipient-who-gets-nothing-detecting-a-whole-missing-mail-piece-with-order-independent-set-1deh</guid>
      <description>&lt;p&gt;One check I built catches page-level defects inside a mail piece: a statement that should be four pages&lt;br&gt;
and printed three, a duplicated page, a page index out of range. It reads a printed keyline — the little&lt;br&gt;
control line like &lt;code&gt;04 01&lt;/code&gt; meaning "page 1 of a 4-page piece" — groups pages into pieces, and verifies each&lt;br&gt;
piece is whole. Good for the &lt;em&gt;inside&lt;/em&gt; of a piece.&lt;/p&gt;

&lt;p&gt;It is completely blind to a worse defect: &lt;strong&gt;an entire piece that never exists.&lt;/strong&gt; Account 100238 was in the&lt;br&gt;
input file and produced no output — no pages, no keyline, nothing to group. The run looks internally&lt;br&gt;
perfect. Every piece that printed is complete. And one household gets silence where a statement, an EOB, or&lt;br&gt;
a legally-required notice was supposed to be.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why you can't just sort and scan
&lt;/h2&gt;

&lt;p&gt;The obvious approach — collect every piece's serial, sort, walk the list for gaps — breaks on real mail.&lt;br&gt;
Production streams are &lt;strong&gt;presorted&lt;/strong&gt;: reordered into carrier walk sequence for postal discounts. Pieces&lt;br&gt;
arrive deliberately out of order, so "the next serial is smaller than the last" is the normal, correct&lt;br&gt;
state, not an anomaly. Any check that assumes ordering drowns a presorted run in false positives.&lt;/p&gt;

&lt;p&gt;So the check has to be &lt;strong&gt;order-independent&lt;/strong&gt;. Treat the serials as a set and ask set questions: within the&lt;br&gt;
observed range, is every expected serial present exactly once? That reframes the problem away from sequence&lt;br&gt;
and toward continuity of a set — which is what actually matters. Nobody cares what order the pieces printed;&lt;br&gt;
they care that everyone who should have gotten one, did.&lt;/p&gt;

&lt;h2&gt;
  
  
  The findings — and the honest one
&lt;/h2&gt;

&lt;p&gt;From the set of per-piece serials, a few conditions fall out cleanly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;piece missing&lt;/strong&gt; — a serial absent from inside the observed range&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;piece duplicate&lt;/strong&gt; — the same serial on more than one piece&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;out of range&lt;/strong&gt; — a serial outside the declared bounds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;count mismatch&lt;/strong&gt; — a total that doesn't match what was declared&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Per client you choose whether serials must be strictly contiguous or merely unique.&lt;/p&gt;

&lt;p&gt;The subtle one is the boundary. If the very first or very last piece of a run is the missing one, the gap&lt;br&gt;
is invisible — there's nothing beyond it to reveal a hole. You cannot detect a missing edge from the data&lt;br&gt;
alone; you need an &lt;em&gt;external&lt;/em&gt; anchor: a declared expected range or count. So when a run's edge can't be&lt;br&gt;
proven either way, the check doesn't quietly assume it's fine. It emits a coverage disclosure stating&lt;br&gt;
exactly what it could and couldn't guarantee, and points at the declaration that would close the gap. Same&lt;br&gt;
rule as everything else: the limit of what the data can prove is reported, never papered over.&lt;/p&gt;

&lt;p&gt;Full write-up (with how it reuses the same keyline as the page check):&lt;br&gt;
&lt;a href="https://preflightdocs.com/blog/detecting-a-missing-mail-piece?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=piece" rel="noopener noreferrer"&gt;https://preflightdocs.com/blog/detecting-a-missing-mail-piece?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=piece&lt;/a&gt;&lt;br&gt;
The free analyzer: &lt;a href="https://preflightdocs.com/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=piece" rel="noopener noreferrer"&gt;https://preflightdocs.com/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=piece&lt;/a&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>showdev</category>
      <category>printing</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The third verdict: why a document QC tool should be allowed to say "I don't know"</title>
      <dc:creator>Preflight</dc:creator>
      <pubDate>Wed, 15 Jul 2026 14:54:41 +0000</pubDate>
      <link>https://dev.to/preflight/the-third-verdict-why-a-document-qc-tool-should-be-allowed-to-say-i-dont-know-3j6k</link>
      <guid>https://dev.to/preflight/the-third-verdict-why-a-document-qc-tool-should-be-allowed-to-say-i-dont-know-3j6k</guid>
      <description>&lt;p&gt;Most checkers answer one of two ways: pass or fail. I want to make the case that a QC tool with only&lt;br&gt;
two answers is structurally dishonest, because it has to guess whenever it can't actually tell — and a&lt;br&gt;
guess dressed as a green check is the most dangerous thing a validator can emit.&lt;/p&gt;

&lt;p&gt;Here's the failure mode that shaped the engine I work on. Upload a scanned PDF with no text layer to an&lt;br&gt;
accessibility checker. It looks for tagged headings, finds none it can read, and prints &lt;strong&gt;pass&lt;/strong&gt; — not&lt;br&gt;
because the document is accessible, but because there was nothing it could parse, and its vocabulary only&lt;br&gt;
contained "pass" and "fail." Absence of a &lt;em&gt;detected&lt;/em&gt; problem got reported as absence of a problem. Those&lt;br&gt;
are different statements, and the gap between them is where compliance tools quietly lie.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three states, not two
&lt;/h2&gt;

&lt;p&gt;So every check returns one of three things: &lt;strong&gt;pass&lt;/strong&gt;, &lt;strong&gt;fail&lt;/strong&gt;, or &lt;strong&gt;not evaluable&lt;/strong&gt;. The third is a&lt;br&gt;
first-class citizen, not an error path. It means: the tool looked, and it cannot honestly determine the&lt;br&gt;
answer from what it was given. No text layer to assess. No template declared for the thing being checked.&lt;br&gt;
A 2D barcode that would need image decoding that isn't shipped yet. A resource the parser reached but the&lt;br&gt;
module doesn't cover.&lt;/p&gt;

&lt;p&gt;The rule is absolute: &lt;strong&gt;a check that cannot run is never allowed to read as a pass.&lt;/strong&gt; If we can't evaluate&lt;br&gt;
it, we say so, in those words, and we say why.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it's harder than one function
&lt;/h2&gt;

&lt;p&gt;Adding a third return value is easy in isolation. Keeping it honest across an entire pipeline is not,&lt;br&gt;
because "not evaluable" is the state most likely to get flattened at a boundary. A module throws on a&lt;br&gt;
malformed stream; if the surfacing layer coerces that into an empty findings array, the public API&lt;br&gt;
cheerfully reports &lt;em&gt;complete, zero findings&lt;/em&gt; — a false green built from a swallowed exception.&lt;/p&gt;

&lt;p&gt;I have found and fixed that exact class of bug more than once: a not-evaluable or errored signal dropped&lt;br&gt;
at the CLI, the webhook, the scorecard, or the JSON boundary — each one turning "we don't know" back into&lt;br&gt;
"looks fine." The lesson: the verdict has to be &lt;strong&gt;carried, not recomputed&lt;/strong&gt;. Coverage travels alongside&lt;br&gt;
findings all the way out. The CLI renders it and exits non-zero. The webhook marks the result partial.&lt;br&gt;
The in-app view labels how many checks actually ran vs were not evaluable vs errored. The counts have to&lt;br&gt;
add up, or a test fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cost, and why it's worth paying
&lt;/h2&gt;

&lt;p&gt;A tool that says "not evaluable" a lot looks less impressive than one that prints green everywhere. That's&lt;br&gt;
a real cost — it's a worse demo than a wall of check marks. But the user here is someone whose statements,&lt;br&gt;
checks, or EOB mail is already going out the door. For them a false pass isn't a missing feature; it's the&lt;br&gt;
incident. An honest unknown lets them go look. A dishonest pass tells them not to.&lt;/p&gt;

&lt;p&gt;A validator that never fails anything is just a mirror. A validator that never admits it doesn't know is&lt;br&gt;
worse: a mirror that lies about what it reflects.&lt;/p&gt;

&lt;p&gt;I write about this and the rest of the engine here — this piece in full, with the pipeline detail:&lt;br&gt;
&lt;a href="https://preflightdocs.com/blog/the-not-evaluable-verdict?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=noteval" rel="noopener noreferrer"&gt;https://preflightdocs.com/blog/the-not-evaluable-verdict?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=noteval&lt;/a&gt;&lt;br&gt;
And you can watch the third verdict happen on a real file in the free analyzer:&lt;br&gt;
&lt;a href="https://preflightdocs.com/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=noteval" rel="noopener noreferrer"&gt;https://preflightdocs.com/?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=noteval&lt;/a&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webdev</category>
      <category>architecture</category>
      <category>testing</category>
    </item>
    <item>
      <title>Most teams can't open the file that prints their statements — parsing AFP in the browser</title>
      <dc:creator>Preflight</dc:creator>
      <pubDate>Thu, 09 Jul 2026 20:14:48 +0000</pubDate>
      <link>https://dev.to/preflight/most-teams-cant-open-the-file-that-prints-their-statements-parsing-afp-in-the-browser-187k</link>
      <guid>https://dev.to/preflight/most-teams-cant-open-the-file-that-prints-their-statements-parsing-afp-in-the-browser-187k</guid>
      <description>&lt;p&gt;AFP — Advanced Function Presentation — predates the web. It came out of IBM in the 1980s, moves to production printers over IPDS, and still composes a huge share of the world's bank statements, insurance documents, and healthcare EOBs. If you work anywhere near transactional print, AFP files flow through your systems daily.&lt;/p&gt;

&lt;p&gt;And yet: ask a team to answer &lt;strong&gt;"is this AFP batch structurally sane?"&lt;/strong&gt; and watch what happens. The tooling that can even open the format is enterprise software — licensed per seat, installed somewhere specific, owned by another department. The format's documentation (MO:DCA — Mixed Object Document Content Architecture) is public via the AFP Consortium, but public and approachable are different things. Most vendors in this space sell &lt;em&gt;conversion&lt;/em&gt; — AFP in, PDF out. Almost nobody just tells you whether the file is well-formed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The format is friendlier than its reputation
&lt;/h2&gt;

&lt;p&gt;An AFP file is a flat sequence of &lt;strong&gt;structured fields&lt;/strong&gt;. Every field starts with a &lt;code&gt;0x5A&lt;/code&gt; carriage-control byte, then a two-byte big-endian length, a three-byte identifier (SFID), a flag byte, two reserved bytes, and payload. That's the whole framing story. No cross-references to resolve, no compression dictionary to bootstrap — you can walk an AFP file with a while loop.&lt;/p&gt;

&lt;p&gt;Structure comes from &lt;strong&gt;Begin/End pairs&lt;/strong&gt;. &lt;code&gt;BDT…EDT&lt;/code&gt; wraps the document; &lt;code&gt;BPG…EPG&lt;/code&gt; wraps each page; groups, presentation-text objects, and overlays nest inside in last-opened-first-closed order. Names inside the fields are EBCDIC — code page 500, another small museum piece — and resource references (fonts via &lt;code&gt;MCF&lt;/code&gt;, overlays via &lt;code&gt;IPO&lt;/code&gt;, page segments via &lt;code&gt;IPS&lt;/code&gt;) are eight-character EBCDIC names pointing at objects that live &lt;em&gt;outside&lt;/em&gt; the file, in a resource library on the production system.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a structural validator can honestly check
&lt;/h2&gt;

&lt;p&gt;Our free validator does four things, all derivable from the bytes alone:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Framing&lt;/strong&gt; — every field opens with &lt;code&gt;0x5A&lt;/code&gt;, declares an in-bounds length, and the stream ends exactly at a field boundary. Truncation is the classic transfer failure; FTP in ASCII mode has ruined more AFP files than any parser bug.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Begin/End nesting&lt;/strong&gt; — a plain stack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The document envelope&lt;/strong&gt; — exactly one &lt;code&gt;BDT…EDT&lt;/code&gt;, pages nested inside.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inventory&lt;/strong&gt; — every structured field with its name, byte offset, and length, plus the page count and every referenced resource name.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just as important is what it refuses to do. An SFID we don't recognize is reported as &lt;strong&gt;unknown — counted, located, flagged as a warning&lt;/strong&gt; — not guessed at. Whether a referenced font or overlay actually exists in your resource library is not knowable from the file, so we say exactly that instead of implying it was verified. (My rule for the whole product: anything the tool can't actually determine is reported "not evaluable" — never silently passed.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Why client-side was the whole point
&lt;/h2&gt;

&lt;p&gt;AFP files are statements and EOBs — they carry names, addresses, account numbers, health information. The reason "just upload it to a converter site" never became the norm in this industry is that nobody responsible for that data should be uploading it anywhere casually. So the validator runs &lt;strong&gt;entirely in the browser&lt;/strong&gt;: the parser is compiled into the page, the file is read locally, and there is no upload endpoint behind it. Parsing a structured-field stream is cheap — a multi-hundred-page statement run inventories in milliseconds on a laptop — and the file never touches a network.&lt;/p&gt;

&lt;p&gt;Try it (free, no signup, there's a 20-second demo on the page): &lt;a href="https://preflightdocs.com/tools/afp-validator?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=afp" rel="noopener noreferrer"&gt;https://preflightdocs.com/tools/afp-validator?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=afp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The MO:DCA reference is public via the AFP Consortium — if your team fights this format, the structural walk above is entirely buildable from spec, and honestly, more people should.&lt;/p&gt;

</description>
      <category>parsing</category>
      <category>webdev</category>
      <category>printing</category>
      <category>showdev</category>
    </item>
    <item>
      <title>A structurally valid USPS barcode can still encode garbage — validating IMb from the bars</title>
      <dc:creator>Preflight</dc:creator>
      <pubDate>Thu, 09 Jul 2026 20:14:42 +0000</pubDate>
      <link>https://dev.to/preflight/a-structurally-valid-usps-barcode-can-still-encode-garbage-validating-imb-from-the-bars-5dle</link>
      <guid>https://dev.to/preflight/a-structurally-valid-usps-barcode-can-still-encode-garbage-validating-imb-from-the-bars-5dle</guid>
      <description>&lt;p&gt;Every piece of US commercial mail carries an Intelligent Mail barcode — 65 vertical bars, each in&lt;br&gt;
one of four states (full, ascender, descender, tracker). Encoded inside: a barcode ID, service&lt;br&gt;
type, mailer ID, serial number, and the delivery-point routing code. If it's wrong, mail gets&lt;br&gt;
misrouted, automation discounts evaporate, and assessments follow.&lt;/p&gt;

&lt;p&gt;Here's the part that surprised me when I built a validator: &lt;strong&gt;most "IMb checks" only verify that&lt;br&gt;
the bars look like an IMb.&lt;/strong&gt; Sixty-five bars, four valid states each, plausible geometry — pass.&lt;br&gt;
But the encoding pipeline between your data and those bars is long, and a bug anywhere in it&lt;br&gt;
produces a barcode that is structurally perfect and semantically garbage.&lt;/p&gt;

&lt;p&gt;The USPS spec (USPS-B-3200) defines the pipeline roughly like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The tracking + routing fields pack into a single large integer via positional arithmetic
(the routing code contributes up to ~10^11 of the space — this is effectively base conversion
with mixed radixes).&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;11-bit frame check sequence (CRC)&lt;/strong&gt; is computed over that integer's byte representation.&lt;/li&gt;
&lt;li&gt;The integer is converted into ten 3-digit codewords (more base conversion).&lt;/li&gt;
&lt;li&gt;Each codeword maps to a 13-bit &lt;strong&gt;constant-weight character&lt;/strong&gt; — every valid character has
exactly five bits set (weight 5) or two bits set (weight 2, selected by one FCS bit); the
remaining FCS bits flip specific character bits.&lt;/li&gt;
&lt;li&gt;The 130 character bits interleave onto the 65 bars (each bar's ascender/descender halves come
from different characters).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So validation has levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Level 0 — geometry:&lt;/strong&gt; 65 bars, valid states. Catches print defects, nothing else.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level 1 — character validity:&lt;/strong&gt; de-interleave the bars and check that every 13-bit character
is in the constant-weight codebook. Catches some corruption; still passes many encoder bugs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Level 2 — the FCS round-trip:&lt;/strong&gt; reverse the whole pipeline — characters → codewords → the big
integer (undoing the base conversion) — recompute the 11-bit CRC from the recovered payload,
and compare it against the FCS bits actually embedded in the characters. &lt;strong&gt;A mismatch proves
the barcode was produced by a broken encoder&lt;/strong&gt;, even though every bar and every character looks
valid.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Level 2 is the one that catches real production incidents: an off-by-one in codeword packing, a&lt;br&gt;
routing code that got truncated upstream, a library that silently handles 130-bit arithmetic&lt;br&gt;
wrong. All of those produce beautiful, scannable, &lt;em&gt;wrong&lt;/em&gt; barcodes.&lt;/p&gt;

&lt;p&gt;A few implementation notes for anyone building this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need exact big-integer arithmetic (the payload exceeds 64 bits — 10^11 × the tracking
fields). Any float contamination anywhere corrupts the round-trip.&lt;/li&gt;
&lt;li&gt;The reverse base conversion is the fiddly part: the spec is written encode-forward, so the
decode is "run the multiplications backwards as divisions and prove you get clean remainders."&lt;/li&gt;
&lt;li&gt;Test against the spec's published example vectors first, then against barcodes from encoders
you trust, then — the fun part — against deliberately corrupted ones. A validator that never
fails anything is just a mirror. (My rule for the whole product: anything the tool can't
actually determine gets reported "not evaluable" — never silently passed.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I ship this as part of Preflight, a document-QC tool for print/mail — the free analyzer detects&lt;br&gt;
IMbs and validates structure in the browser: &lt;a href="https://preflightdocs.com/tools/imb-barcode-validator?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=imb" rel="noopener noreferrer"&gt;https://preflightdocs.com/tools/imb-barcode-validator?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=imb&lt;/a&gt;&lt;br&gt;
The full FCS round-trip and field decode run in the USPS module. But the algorithm above is all&lt;br&gt;
public spec (USPS-B-3200) — if you maintain mail software, you can build Level 2 yourself, and&lt;br&gt;
you probably should.&lt;/p&gt;

</description>
      <category>barcode</category>
      <category>printing</category>
      <category>algorithms</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
