Showing posts with label web. Show all posts
Showing posts with label web. Show all posts

Thursday, March 31, 2016

Mega.co.nz, web-based file streaming & Copy.com users

The following is an open letter to Mega.co.nz about implementing web-based audio file streaming (and attracting Copy.com users):

March 31, 2016
To the management (and developers) of Mega.co.nz:

In two months, on May 1, 2016 (as you may know), Barracuda Networks will close its (reportedly) "highly rated" Copy.com service.

They are directing "millions of users" to convert to Microsoft's similar service.

Instead, to attract some of those users, it might be in Mega.co.nz's best interest to implement certain Copy.com features. I'm thinking of one in particular:

Copy.com's web-based file manager directly automatically streams audio files (particularly Ogg-Vorbis files: those with extension OGG; and MP3 files).

Thus, whenever users shared (with other people) a web link to a directory tree on Copy.com, then the recipients, simply by navigating there, could stream that audio immediately and directly.

In other words, the recipients of the link could find and stream (in a web browser) any audio file: this without any additional (bothersome or worrisome) steps required; i.e., to:
  1. Download the audio file;
  2. Choose an audio player program; or even
  3. Install a special audio player for Ogg-Vorbis files.
In many cases—for many recipients—these additional steps can be show-stoppers.

This is particularly true in the case of public links.

Many Copy.com users would find this direct-streaming feature highly useful, IMO.

Mega.co.nz could attract more Copy.com users to their service by duplicating this feature.

Does Mega.co.nz plan to add this functionality—of direct-streaming Ogg-Vorbis (extension .ogg) or MP3 files—to their web-based file manager? Would Mega.co.nz's management consider it?

Already, Mega.co.nz's phone apps stream audio. In the web-based file manager, a need for this exists also, for the easiest possible access when sharing web links.

With warm regards,

Copyright (c) 2016 Mark D. Blackwell.

Tuesday, September 23, 2014

Visual project design & reporting & Pivotal Tracker with add-ons

UML

Some business owners wish to see diagrams which can explain the software structure of a project visually. In those cases, UML is a good choice:

  http://en.wikipedia.org/wiki/Unified_Modeling_Language
  http://en.wikipedia.org/wiki/Applications_of_UML

The following (kinds of) UML diagram are useful for that purpose:

  http://en.wikipedia.org/wiki/Activity_diagram
  http://en.wikipedia.org/wiki/Component_diagram
  http://en.wikipedia.org/wiki/Sequence_diagram
  http://en.wikipedia.org/wiki/Use_Case_Diagram

VISUAL PARADIGM

Often, business owners are attracted to the tool, Visual Paradigm. Unfortunately, it is quite expensive.

The tool itself isn't web-based, but the company (free of charge) offers VPository, cloud storage for developers working collaboratively.

IMO, a download for each user is fine in itself if the project data is shared.

Its Professional Edition is the minimum practical level to obtain the features which business owners often are interested in: Requirements Gathering ("uexceler"), Task Management, and Wireframes.

Regarding Visual Paradigm's cost factor, they levy a surcharge to receive bug fixes for their software. (Like all software, I suppose it's buggy.) Therefore, currently the Single Seat License for the Professional Edition is really $838.50 per person (= $699 + $139.50). Floating Licenses—for transient project contributors—are $1,090.00 each (= $908.50 + $181.50. All prices are in US dollars.).

Maybe using Visual Paradigm is really taking things too far.

Basecamp can maintain a project glossary as a versioned, editable file.

For most projects, the database schema diagram can be auto-generated (at least once) and stored in Basecamp.

Perhaps User Stories, and images for each wireframe block, can be tied together in some easy fashion (see "Add-ons adding pictures to User Stories", below).

TOOLS SIMILAR TO VISUAL PARADIGM

I came across this list of tools similar to Visual Paradigm. Of them, the following might be useful:

  http://www.gentleware.com/uml-software-community-edition.html
  http://www.modeliosoft.com/en/products/features.html
  http://www.softwareideas.net/en/features/

PIVOTAL TRACKER

Because Pivotal Tracker is quite successful (or popular), people have contributed quite a large number of add-ons:

Add-ons adding pictures to User Stories:
  http://blog.snapengage.com/2010/03/pivotal-tracker-snapashot-integration/
  https://trackduck.com/en/content/integrations/pivotaltracker/
  https://usersnap.com/pivotaltracker

Add-ons adding User Stories from plain text:
  https://github.com/gabehollombe/Pivotxt
  https://github.com/hashrocket/slurper

Add-ons dumping User Stories:
  https://gist.github.com/glarrain/5861055

Add-ons for bugs:
  http://bugdigger.com/pivotal/
  http://bugherd.com/blog/bugherd-and-pivotal-tracker-best-of-friends/
  http://www.redline.cc/

Add-ons for reporting:
  https://www.dashofagile.com/pivotaltracker
  http://www.easy-insight.com/solutions/PivotalTracker.html
  https://github.com/jimlindstrom/Tracker-Dashboard
  https://www.in-sight.io/
  http://www.just-facts.co/#tabs-services
  http://support.leftronic.com/customer/portal/articles/1120034-create-a-pivotal-tracker-dashboard
  https://www.leftronic.com/services/pivotal-tracker/
  https://www.prodpad.com/2013/05/integrate-with-jira-trello-and-pivotal-tracker/
  http://apps.splunk.com/app/1584/
  http://start-software.com/tracker/modules/tracker-dashboard/
  https://www.tenxer.com/how/
  https://www.tenxer.com/what/
  http://www.timecamp.com/blog/index.php/2012/11/
      log-time-on-a-story-card-in-pivotal-tracker-and-timecamp-integration/


Add-ons for testing:
  http://www.gurock.com/testrail/
  http://www.testlodge.com/

Add-ons liaising other sites with Pivotal Tracker, also with Basecamp:
  http://www.redline.cc/
  http://www.testlodge.com/
  https://trackduck.com/en/content/integrations/basecamp/

Add-ons liaising with Cucumber:
  https://github.com/tpope/pickler

Add-ons liaising with GitHub:
  https://github.com/getvega/Pivothub
  https://github.com/stevenharman/git_tracker
  https://github.com/zauberlabs/gh-pivotal-integration

Add-ons liaising with Redbooth:
  https://help.redbooth.com/hc/en-us/articles/200752732-Pivotal-Tracker-Integration

Add-ons liaising with Redmine:
  https://github.com/capita/redmine_trackmine

Other relevant add-ons:
  http://blog.aha.io/index.php/aha-integrated-with-pivotal-tracker-for-visual-product-roadmaps/
  http://blog.busyflow.com/2012/01/16/the-benefits-of-a-deep-pivotal-tracker-integration/
  https://github.com/bimovidia/planning-poker
  https://github.com/joncooper/lorem-tracker
  https://github.com/nathanmcdaniel/pivotalstuff/tree/master/viewallmywork
  https://chrome.google.com/webstore/detail/
      clone-stories-for-pivotal/mpaldiblbgdmmnolghhbohicignfhimb

  https://chrome.google.com/webstore/detail/
      easy-copy-for-pivotal-tra/mmlaaianjmomeolpmmhdcmjnnmmoalbh

  https://code.google.com/p/mastercontrol/
  http://hojoki.com/
  https://www.honeybadger.io/
  http://sluglug.com/
  https://storymapper.io/

OTHER POSSIBLY INTERESTING PLANNING TOOLS

  http://www.clarizen.com/project-management-solutions/agile-project-management.html
  http://www.clockingit.com/screenshots
  http://www.goplanapp.com/home/features
  http://www.huddle.com/product-overview/
  http://leankit.com/product/
  http://www.mangoapps.com/features
  https://www.planbox.com/tour/
  http://planship.com/
  https://pmrobot.com/features
  http://www.strikebase.com/
  http://www.thymer.com/why/
  https://trello.com/
  https://www.ubirimi.com/
  https://www.ubirimi.com/product/agile
  https://www.ubirimi.com/product/documentador
  https://www.ubirimi.com/product/yongo
  http://www.versionone.com/product/agile-collaboration-tools/
  http://www.versionone.com/product/agile-visualization/
  http://www.webplanner.com/site/index.php
  http://wholemeal.co.nz/projects/fulcrum.html
  http://www.zoho.com/

TRACK DUCK

Track Duck (highly popular) allows people to add comments to any website, after it automatically takes a screen shot.

Track Duck integrates with Pivotal Tracker and Basecamp, etc.

With it, one easily can add (one or multiple) images to Pivotal Tracker User Stories, and also create images for Basecamp. But see other "Add-ons adding pictures to User Stories", above.

Reviews of Track Duck:
  http://techcrunch.com/2014/02/17/
      trackduck-a-tiny-web-site-build-tracking-startup-appears-to-be-on-a-roll/

  http://goaleurope.com/2014/02/04/
      lithuanian-trackduck-launches-new-version-of-its-interactive-website-feedback-tool/


Copyright (c) 2014 Mark D. Blackwell.

Tuesday, June 4, 2013

Blog posts' date position

Just now I was reading a blog to avoid emailing its author with questions they already blogged about. Like others with this purpose, I read it reverse-chronologically (i.e. from the top).

While reading a blog purposefully to learn the current status of a fast-changing software system it seems important to gather a quick sense of time context for each post.

Inevitably I observe myself sliding my browser window downward to the bottom of each post to get a sense of how long prior to the post above it each was released—just in case the time interval is much, much longer than those above.

Then I slide the window back, indeed with resulting uncertainty that I have recovered the proper beginning of the proper post.

Some blogs may never have a delay of more than two weeks between posts.

If I knew this were the case always I wouldn't even look. But since I am not sure, I find myself looking at the dates.

Viewing a blog's archive helps somewhat (and furthermore I can read a whole blog by clicking its posts in an archive list; but this seems less natural).

So the minor suggestion here, for blog formatters' consideration, comprises the usefulness of placing the date of each post immediately below its title.

Copyright (c) 2013 Mark D. Blackwell.

Tuesday, April 30, 2013

Essential jQUERY

Recently, I picked up the bare essentials in jQuery from the book, jQUERY Visual Quickstart Guide by Steven Holzner, Peachpit Press, 2009.

However, a word of warning: the book is somewhat badly edited, and there is no corrected edition (still as of this writing).

From the core jQuery source code, this page also is useful. Here are my brief notes:

JQuery refers to a certain syntax $(thing) for any thing as 'jQuery-wrapping'.

The keyword $ is an alias for jquery. Both are used in the following ways:

  • $(function)  –  Append a function to the list to be run when the document is ready: a shortcut for $(document).ready(function).

  • $(CSS-selector-string)  –  Select some nodes in the document.

  • $(HTML-string)  –  Create HTML for insertion.

  • $(DOM-node)  –  Like saying simply DOM-node, but change the value of this and set context (an attribute used by jQuery). Examples are:
    •   $(document)  –  The document.
    •   $(this)  –  this.

  • $.method  –  (This one has a dot and no parentheses.) Run a utility method.

The jQuery methods selected for explanation in the book are:

  • Methods on jQuery-wrapped collections of HTML elements:
    • addClass,  after,  alt,  animate,  append,  attr,  before,  bind,  clone,  css,  each,  (event binder methods),  fadeIn,  fadeOut,  fadeTo,  height,  hide,  hover,  html,  is,  (jQuery-UI methods),  length,  load,  one,  serializeArray,  show,  size,  slice,  slideDown,  slideToggle,  slideUp,  text,  toggle,  toggleClass,  unbind,  val,  width,  wrap

  • Event binder methods:
    • Keyboard   –   keydown,  keypress,  keyup

    • Mouse   –   mousedown,  mouseenter,  mouseleave,  mousemove,  mouseout,  mouseover,  mouseup

    • The rest   –   beforeunload,  blur,  change,  click,  dblclick,  error,  focus,  load,  resize,  scroll,  select,  submit,  unload

  • jQuery-UI methods:
    • accordian,  datepicker,  dialog,  progressbar,  slider,  tabs

  • Methods on jQuery-wrapped HTML strings:
    • insertAfter,  insertBefore

  • Utility methods:
    • ajax,  browser,  each,  get,  grep,  inArray,  isArray,  isFunction,  makeArray,  map,  post,  support,  trim,  unique

Copyright (c) 2013 Mark D. Blackwell.

Thursday, April 25, 2013

Meetup authentication & email addresses

As part of its OAuth authentication process with other apps, Meetup doesn't provide email addresses of its users. (I refer to this official Meetup forum question, and to this page in the Meetup API docs—search the page for 'email'.)

Twitter doesn't provide email addresses either. However, Meetup seems nicer than Twitter.

People use multiple Twitter accounts (I know some who do). But people don't use multiple Meetup accounts (at least supposedly not).

When registering new users through this difficult class of OAuth authentication providers (those which don't supply an email address) one might ask each new user directly for some email address, or might not. Requesting this is normally recommended.

If an app uses Meetup authentication (and it doesn't request and confirm an email address during user registration), and uses another form of authentication also (even added later) then there's no way to identify the same user, if or when they sign on by a different way.

So Meetup authentication (without email) is only good if the app is forever limited to using Meetup authentication alone. With that permanent limitation, in such an app, nobody (mysteriously) will run into the problem of having more than one account.

Of course, having Meetup as the single method of authentication is useful, reasonably, only to apps which are already limited to Meetup users.

Keeping the UI simple (by not requesting an email address when people register) means the app might never have email addresses. But that might be okay if an app uses Meetup authentication alone, forever.

Then one need not bother people with asking for their email address when they first use an app. The ease of that emotional UX moment when new customers are forming their first impression of an app (and making their initial commitment to it), from the standpoint of building a customer base—depending on the app—could be considered more important than ever knowing their email addresses.

BTW, omniauth-meetup is a good gem for doing Meetup authentication in Rails.

Copyright (c) 2013 Mark D. Blackwell.

Saturday, April 20, 2013

Flat UI and Twitter Bootstrap "Mobile First" for Rails

Designmodo's announcement for their free Flat UI (which uses Sass) mentions plans (in the discussion) to release a pay version containing LESS code. And an issue on their Flat UI gem floats a suggestion of possibly porting it to LESS.

Darthdeus' gem flat-ui-rails contains Flat UI precompiled to CSS with no LESS code.

Whether Flat UI will continue to be maintained and useful for Rails doesn't relate to Darthdeus' trivially easy to maintain gem but therefore instead to Designmodo's free Flat UI product itself. So far, BTW, their Pro version seems to be vaporware.

There is a rumor Twitter Bootstrap version 3 "Mobile first" will have a flatter UI, but that's only temporary (for development purposes) according to this article.

Web searching revealed no sign how Designmodo's Flat UI might be affected by Twitter's new "Mobile first" initiative otherwise.

Copyright (c) 2013 Mark D. Blackwell.

Friday, September 28, 2012

Frontend experience

Recently, I acquired some practical website frontend experience—which took quite a bit of learning!

For an initial demo for a startup, I analyzed, selected and set up all the infrastructure (Rails, Heroku & Amazon). I wrote all the CSS frontend. I also wrote all the working database backend.

See the demo! See how its layout is fluid?

(Click here, if you missed the above links.)

It doesn't have multiple user capability yet; it's just a demo, at this time.

I made this in the pursuit of becoming a does-everything website developer.

Copyright (c) 2012 Mark D. Blackwell.

Monday, September 17, 2012

Website page layouts, proofs of concept

A big part of frontend website development is implementing webpage layouts using CSS stylesheets (of course).

Recently, I've been experiencing a great deal more of business in the area of layouts (specifically for Rails websites) and especially the work of implementing these layouts through developing CSS stylesheets—whether or not this is really programming! (Well, I think it is.)

I find it much less efficient to run the Rails server, and much more efficient to 'web-browse' the local filesystem. The work progresses much more quickly, in other words, when it is isolated from any complicating factors arising from our misunderstanding of the Rails server, jQuery, ERB/HAML, and perhaps even Sass. The weightiest reason for this improvement (by far) is the troubleshooting principle: 'divide and conquer'. Less important is that the filesystem also is relatively quicker.

It is much more doable (dare I say, even feasible) to get isolated layouts working using pure CSS and HTML (while keeping class names simple). And the same is true while paring down a stylesheet to be as simple and clean as possible.

Of course, further simplifying cross-browser development is the use of a CSS-reset stylesheet. Also it is essential, for HTML5's semantic tags: header, footer and nav (etc.), to include a (JavaScript) HTML5 shim (or 'shiv') script. So I include both of these best practices.

I have prepared a repository of my CSS (layout) proofs of concept on GitHub—including nine(!) useful proofs (as of now, September, 2012).

These layout proofs contain stylesheet code the way I write for Rails projects as much as possible (without actually including Rails).

Copyright (c) 2012 Mark D. Blackwell.

Monday, August 27, 2012

Crisp image edges in web browsers, howto

Sometimes, website creation frontend work involves extracting images from pages rendered by browsers. These pages may be wireframes, for instance.

Of course, it is appropriate that web pages (displayed in a browser) contain some blurring for good looks (which becomes plainly visible if blown up to 1600% by Photoshop, etc.)

Of course, it is appropriate also that some images of a wireframe (such as icons) be blurred, because icons are created normally by a dithering process.

Although image blurring (for demonstration purposes) is appropriate and has a good look, such additional blurring is bad when images are extracted for reuse on a webpage, because the blurring will then happen twice (a doubled blurring will result).

To avoid this double-blurred problem, and for pixel art, the following method will set up for you a web browser which does not blur images:
  1. Download and install the latest SeaMonkey web browser:

    http://www.seamonkey-project.org/releases/

  2. For your particular operating system, locate your profile folder by reading:

    http://www.gemal.dk/mozilla/profile.html

  3. Immediately below your profile folder, make sure a folder exists named, 'chrome' (not the Google browser), and that a file exists in the chrome folder called, 'userContent.css' (or create them).

  4. Append to userContent.css the following lines: all are for resampling of images by the desired (in this case) nearest-neighbor method:

    (Note: I leave intact (below) some other browsers' settings for this, just in case you want to add these lines to your particular browser, in whatever way.)
/*
Gecko (Firefox & Seamonkey)
Webkit (Chrome & Safari)
*/
img {
image-rendering: optimizeSpeed;             /* Older Gecko */
image-rendering: optimize-contrast;         /* CSS3 draft proposal */
image-rendering: -webkit-optimize-contrast; /* Webkit */
image-rendering: crisp-edges;               /* CSS3 draft proposal */
image-rendering: -moz-crisp-edges;          /* Gecko */
image-rendering: -o-crisp-edges;            /* Opera */
-ms-interpolation-mode: nearest-neighbor;   /* IE8+ */
}
References:
http://help.dottoro.com/lcuiiosk.php
https://github.com/thoughtbot/bourbon/pull/102
http://productforums.google.com/forum/#!topic/chrome/AIihdmfPNvE
https://bugzilla.mozilla.org/show_bug.cgi/show_bug.cgi?id=41975
https://developer.mozilla.org/en-US/docs/CSS/Image-rendering http://www-archive.mozilla.org/unix/customizing.html#usercss
http://stackoverflow.com/questions/7615009/disable-interpolation-when-scaling-a-canvas
http://nullsleep.tumblr.com/post/16417178705/how-to-disable-image-smoothing-in-modern-web-browsers
http://www.w3.org/TR/2011/WD-css3-images-20110712/#image-rendering

Copyright (c) 2012 Mark D. Blackwell.

Tuesday, July 24, 2012

Getting started with Ajax live updating, howto

Complexity is the enemy of troubleshooting. Remove as many dimensions as possible—it helps in a big way!

To create (with Ajax) your first live-updated web page, this no less applies. (Of course, these kinds of web pages don't require full page refreshes to change their appearance—familiar, right?)

The chosen web stack also makes its own recommendations. For getting Ajax to work, the elements of complexity include:
  • Understanding normally what happens in Ajax on the server and getting that to work, especially in an evolving web stack like Rails. (Googling gives obsolete information.)
  • Learning the details of the recommended language for the browser (naturally it gets compiled into Javascript). This is CoffeeScript for Rails now.
  • Learning the details of the particular Javascript library; Rails now recommends jQuery.
  • Getting from an external server the chosen Javascript library into the browser (which might not be working, giving no sign).
  • Learning in the chosen Javascript library (jQuery, e.g.) how to do Ajax.
  • Learning in (raw) Javascript how to do Ajax in a combination of browsers (using try-and-catch).
  • Learning in (raw) Javascript in a chosen, single browser how to do Ajax (e.g., doing XMLHttpRequest).
  • Learning to troubleshoot Javascript in a browser.
  • Learning the (browser) Document Object Model.
  • Learning Javascript.
For getting first-time Ajax working, all but the last four are unnecessarily complicated dimensions for troubleshooting.

Obviously if Ajax isn't working and nothing's happening, one had better remove all possible dimensions and get one thing working at a time!

So I have written a simple Ajax testbed server for the cloud:
  • It is always running.
  • It is extremely simple.
  • It doesn't have to be installed or configured by you.
  • It responds absolutely identically to:
    • GET and POST requests.
    • Header-specified HTML, JSON, XML and JS requests.
    • URL extension-specified HTML, JSON, XML and JS requests.
  • It simply returns the same JSON no matter what you do.
The testbed is running. Fork it on GitHub! Or tell me how it's not working for you.

Here's some browser client code to match (it runs on Mozilla's browsers):

<!DOCTYPE html>
<html> <head>
<title>bare Ajax</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf8">
<script type="text/javascript">
<!--

//Browser support code:

function getAjaxObject(){
  var result;
  try{ //Gecko: Mozilla, Firefox; Webkit: Chrome, Safari; ?: Opera; (etc.?) browsers:
    result = new XMLHttpRequest();
  } catch (e){ //Internet Explorer browsers:
    try{
      result = new ActiveXObject('Msxml2.XMLHTTP');
    } catch (e) {
      try{
        result = new ActiveXObject('Microsoft.XMLHTTP');
      } catch (e){ //Something went wrong:
        alert('Unable to obtain an Ajax object.');
        return false;
      }
    }
  }
  return result;
}

//Non-browser support code:

function targetId() {
  return 'replaceable';
}

function Target(id) {
  this.id = id;
}

function alterTarget(s) {
  var target = new Target(targetId());
  var elem = document.getElementById(target.id);
  elem.innerHTML = s;
}

function requestAjaxUpdate() {
  var req = getAjaxObject();
  //req.open('GET', 'http://localhost:5000/ajax',false);
  req.open('GET', 'http://ajax-testbed-simple.herokuapp.com/ajax',false); //Synchronous.
  req.send();
  //alert(req.status);
  var myJSON = JSON.parse(req.responseText);
  var s = myJSON.message;
  alert(s);
  alterTarget(s);
}

// When the DOM is fully loaded:
window.document.addEventListener('DOMContentLoaded', function() {
  //alert('window document ready');
}, false);

// When images, etc. are fully loaded:
window.onload = function() {
  //alert('window load');
  requestAjaxUpdate();
};

//-->
</script> </head> <body>

<div id="replaceable"  >replaceable-content</div>

</body> </html>

References:

http://ajaxpatterns.org/XMLHttpRequest_Call
https://developer.mozilla.org/en/AJAX/Getting_Started
https://developer.mozilla.org/en/DOM/
https://developer.mozilla.org/en/DOM/About_the_Document_Object_Model
https://developer.mozilla.org/en/DOM/DOM_event_reference/DOMContentLoaded
https://developer.mozilla.org/en/DOM/XMLHttpRequest
https://developer.mozilla.org/en/DOM/XMLHttpRequest/Using_XMLHttpRequest
https://developer.mozilla.org/en/DOM_Client_Object_Cross-Reference/DOM_Events
https://developer.mozilla.org/en/JavaScript/
https://developer.mozilla.org/en/JavaScript/A_re-introduction_to_JavaScript
https://developer.mozilla.org/en/JavaScript/Guide
https://developer.mozilla.org/en/JavaScript/Reference/
https://developer.mozilla.org/en/JavaScript_technologies_overview
https://developer.mozilla.org/en/Server-Side_Access_Control
http://en.wikipedia.org/wiki/Ajax_(programming)
http://en.wikipedia.org/wiki/JSON
http://en.wikipedia.org/wiki/XMLHttpRequest
http://linuxgazette.net/123/smith.html
http://molily.de/weblog/domcontentloaded
http://stackoverflow.com/questions/1457/modify-address-bar-url-in-ajax-app-to-match-current-state
http://stackoverflow.com/questions/6410951/how-to-simplify-render-to-string-in-rails-3
http://www.hunlock.com/blogs/Mastering_JSON_(_JavaScript_Object_Notation_)
http://www.json.org/js.html
http://www.mousewhisperer.co.uk/ajax_page.html
Ajax Tutorial – tizag.com/
http://www.w3.org/TR/XMLHttpRequest/
http://www.w3schools.com/json/default.asp
http://www.w3schools.com/xml/xml_http.asp
http://www.xml.com/pub/a/2005/02/09/xml-http-request.html

Copyright (c) 2012 Mark D. Blackwell.