<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>CodingMonk</title>
        <link>http://www.codingmonk.com/CodingMonk/Default.aspx</link>
        <description />
        <language>en-US</language>
        <copyright>Jim Fisher</copyright>
        <generator>Subtext Version 2.1.2.2</generator>
        <image>
            <title>CodingMonk</title>
            <url>http://www.codingmonk.com/CodingMonk/images/RSS2Image.gif</url>
            <link>http://www.codingmonk.com/CodingMonk/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>iPad App Review: Complete Class Organizer (by Rosario Jameson)</title>
            <category>iPad Apps</category>
            <link>http://www.codingmonk.com/CodingMonk/archive/2011/01/03/ipad-app-review-complete-class-organizer-by-rosario-jameson.aspx</link>
            <description>&lt;p&gt;This past semester, I evaluated several note taking applications for the iPad and have come to the conclusion that the best all-in-one app is "&lt;a href="http://itunes.apple.com/us/app/complete-class-organizer/id379835748"&gt;Complete Class Organizer&lt;/a&gt;" (henceforth to be referred to as "CCO") by &lt;a href="http://www.completeclassorganizer.com"&gt;AnimalBrainz Inc&lt;/a&gt;. For someone like me, who suffers from intolerable deficiencies in their note-taking skills, it's a godsend. I used it for the first time in a class which was almost 100% lecture. It definitely made the difference between an "A" and some other, less "A"-ish grade. I highly recommend that anyone taking classes consider this, primarily because I've seen no other apps that offer as much as this one does. 
&lt;/p&gt;&lt;p&gt;At the same time, CCO has a few places where it comes up short. Understand, I actively use CCO so my identification of these items shouldn't be taken as derogatory feedback but rather as a constructive review. It's my hope that the designers of CCO will address some of these improvements in future releases, making the app fulfill more completely its purpose.  Also, this article isn't meant to be a comparison between competing apps.  It is a review of CCO, but to illustrate the room for improvement I point to another app: &lt;a href="http://itunes.apple.com/us/app/audionote-notepad-voice-recorder/id369820957?mt=8"&gt;AudioNote&lt;/a&gt;.  AudioNote is really good in its own right, but it is a more focused tool and lacks the more holistic approach to classroom organization that CCO has.  
&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The Features: &lt;/strong&gt;
	&lt;/p&gt;&lt;ul style="margin-left: 54pt"&gt;&lt;li&gt;&lt;div&gt;&lt;strong&gt;Organization &lt;/strong&gt;
			&lt;/div&gt;&lt;p&gt;CCO helps you organize your notes by class and by individual note taking sessions within a class. This provides a handy place to register important information about the class itself, such as your instructor's contact information, class location, and online syllabus. Likewise, it helps to keep your notes organized. Nothing is more frustrating than digging through a mound of files trying to locate the notes for a specific lecture and CCO helps to solve this in a natural, intuitive way.
&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;&lt;strong&gt;Audio synchronization with typed notes &lt;/strong&gt;
			&lt;/div&gt;&lt;p&gt;This is, by far, the most impressive and useful feature in CCO. CCO will not only allow you to record the lecture while you are typing, but when reviewing your notes, you can select a word and hit "Play Audio" to begin playing the lecture at exactly the point where you were typing that word. Very nice. Really, I don't know how I ever managed to live through a lecture class without this excellent feature.  For note taking, I use the &lt;a href="http://www.zagg.com/accessories/zaggmate.php"&gt;ZAGGmate&lt;/a&gt; which integrates seamlessly.  In fact, I find CCO and this case/keyboard very complimentary.
&lt;/p&gt;&lt;p&gt;For the typed notes and lecture synchronization aspects of CCO, I see only some small room for improvement, and this is apparent only because I shopped around: AudioNote's version of this highlights the word or graphical stroke you were making as the playback progresses. Without this in CCO, I find that I sometimes get lost and end up clicking on words and restarting playback periodically so that I can reorient myself with the lecture.  It's a small distinction and not something I can really hold against CCO.  It's just a bell or whistle that could make it that much better.
&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;&lt;strong&gt;Drawings &lt;/strong&gt;
			&lt;/div&gt;&lt;p&gt;In addition to typing text, you can also create pages to capture hand-drawn diagrams.  Used with a stylus such as the &lt;a href="http://tenonedesign.com/sketch.php"&gt;Pogo Sketch&lt;/a&gt;, this has a lot of potential which I don't think is fully realized.  In this regard, AudioNote outshines CCO for the simple reason that drawings can be made in line with typed text.  Conversely, CCO launches a special "graphic" note page to capture drawings, which you then close and return to typing, losing a bit of context in the process.  As mentioned above, AudioNote's "highlight during playback" feature will highlight each stroke as it was drawn in relation to the recorded lecture. So CCO's approach to hand-drawn notes is a little weak.  For many classes, like history or political science courses, this is probably not a significant shortcoming, but for mathematics and engineering courses, an integrated graphics option is a must have.  I wouldn't consider using CCO for these sorts of classes until this is addressed.  If I had to rank missing core features that I'd like to see added, this would be my number one, leaving all others far behind.
&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;&lt;strong&gt;Import PDFs and Word .DOC files &lt;/strong&gt;
			&lt;/div&gt;&lt;p&gt;Having the ability to import PDFs is really good for making sure that all your class content is readily available, and the ability to import Word .doc files is even more beneficial.   This is particularly useful for annotating an existing documents by, for example, adding detail to a supplied lecture outline. 
&lt;/p&gt;&lt;p&gt;As I said previously, this review isn't meant to be a comparison between AudioNote and CCO, but since I've spent time holding AudioNote up as a standard in the previous bullets, I feel compelled to state: AudioNote does NOT have anything like this. 
&lt;/p&gt;&lt;p&gt;Even so, there is also room for improvement in CCO: The .doc import feature is a little wonky. It seems to have a problem handling Word's numbered lists in roman numeral format: the roman numerals just aren't imported. Also, indentations of lists disappear when imported as well, which tends to make a mess out of outlines. This was bothersome enough for me that I manually went in and revised a "Master Lecture Outline" Word document, converting roman numerals to standard numbers, then spent time putting all of the indentations back into place after import. Also, the more recent .docx format is not supported. So... again, wonky. 
&lt;/p&gt;&lt;p&gt;The PDF version of the master outline imported fine and looked great, but PDF's are read-only as you might expect. Rumor has it that editing of PDFs might be in the app's future.
&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;&lt;strong&gt;Dropbox support &lt;/strong&gt;
			&lt;/div&gt;&lt;p&gt;As of version 1.5, CCO has Dropbox support. This is a welcome addition to the CCO feature list since reading and writing to Dropbox is a much better mechanism than e-mailing documents to and from your workstation.  It makes loading and sending notes and other documents a lot simpler than the previous means of email. 
&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;&lt;strong&gt;Grade tracking &lt;/strong&gt;
			&lt;/div&gt;&lt;p&gt;There is a well-intentioned screen for keeping track of your grades. It was designed on the back of concepts such as "percentages" and "weightings" which can be, I suppose, a versatile way of modeling scores. While the screen looks promising, I found it almost entirely unusable. In the vast majority, teachers distribute grades using a point scoring system, indicating scores in a "47 out of 50 for assignment X" fashion. I've known very few teachers that provided numbers in the fashion CCO seems to accept. As such, using this screen to keep track of your score requires some up front effort to calculate what the "weight" of an assignment on your overall score (percentage of total class points), then to calculate the percentage of your earned grade. Not impossible, sure, but I expect computers to do dumb stuff like this for me. Also, when entering in a percentage, it is impossible to re-enter a value of 100%. Once changed, input can only be entered as 0 - 99. Finally, I've not found a way to elegantly manage this approach to support "extra credit work" which raises your score but does not adversely impact your grade if not done. So... I think this feature needs work. 
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;A Few Stability Problems: &lt;/strong&gt;
	&lt;/p&gt;&lt;ul style="margin-left: 54pt"&gt;&lt;li&gt;&lt;div&gt;&lt;strong&gt;Failure to launch recording &lt;/strong&gt;
			&lt;/div&gt;&lt;p&gt;There are a few stability issues which I suspect are memory defects in the app itself. Several times, when I press the record button, I'm presented with a message box indicating that I have no more room for recordings, and that I should delete pictures to make space. On review I found that I actually have over 40 GB of space free and the app is just confused. Killing it from memory and restarting always resolves this issue, but losing the first part of several lectures trying to resolve this is quite frustrating. Despite what may seem like criticism, I really like this application and I am rooting for it, so understand that I'm jesting when I say that CCO will sometimes self-correct this condition by blowing up and shutting down on its own. Restarting it makes recordings possible again. 
&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;&lt;strong&gt;Periodic blow ups &lt;/strong&gt;
			&lt;/div&gt;&lt;p&gt;These are real, but thankfully they are sparse. To date, most of my note taking sessions have occurred without incident. I suspect, based on experience, that these blowups are related to memory issues stemming from importing .doc files. It's only guesswork, but the app seems to become unstable after importing these files. A dramatic side effect of this is that the current recording, if actively in progress, is lost when this occurs.  As such, I find that its good practice to stop and restart long recordings, breaking them into pieces.
&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I feel guilty about ranking this app a 3 out of 5 stars (or as CCO would put it, 60% with a 100% weighting).  This is because I really like it and wouldn't dream of taking another lecture class without it. If all of the above details were taken care of, it would be a 5 hands down. It's a testament to how useful I've found it in my day-to-day class work that I still recommend it despite a couple of impactful bugs, but I definitely do and look forward to seeing improvements in the app itself. &lt;/p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk/aggbug/30.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jim Fisher</dc:creator>
            <guid>http://www.codingmonk.com/CodingMonk/archive/2011/01/03/ipad-app-review-complete-class-organizer-by-rosario-jameson.aspx</guid>
            <pubDate>Mon, 03 Jan 2011 23:41:21 GMT</pubDate>
            <wfw:comment>http://www.codingmonk.com/CodingMonk/comments/30.aspx</wfw:comment>
            <comments>http://www.codingmonk.com/CodingMonk/archive/2011/01/03/ipad-app-review-complete-class-organizer-by-rosario-jameson.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://www.codingmonk.com/CodingMonk/comments/commentRss/30.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Postcards from Apple Land: Muscle Memory Trumps Saint Ambrose</title>
            <category>iOS</category>
            <link>http://www.codingmonk.com/CodingMonk/archive/2010/08/04/postcards-from-apple-land-muscle-memory-trumps-saint-ambrose.aspx</link>
            <description>&lt;p&gt;As mentioned &lt;a href="archive/2010/07/16/postcards-from-apple-land-a-venture-into-enemy-territory.aspx"&gt;last article&lt;/a&gt;, I'm currently surveying offerings from the "other side". That is, when I recently awoke to find myself owning (unintentionally and completely by accident) an iPhone, iPad, and Mac, I resigned myself to making the best of it and cracked the boxes open to see what was inside. 
&lt;/p&gt;&lt;p&gt;Yeah. That's how I'm telling the story. 
&lt;/p&gt;&lt;p&gt;The truth is, beneath it all I like new, cool technology. And the iPad is definitely new and cool. So to pacify that inner techie, and to try my hand at iPad development, I bought a Mac, without which there can be no iPad development to speak of. While I bumble my way around this new and somewhat foreign Apple landscape, I'm recording my experiences for the benefit of other Windows developers looking to do the same. 
&lt;/p&gt;&lt;p&gt;&lt;span style="color:black; font-family:Helvetica"&gt;&lt;strong&gt;The Hardware &lt;/strong&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;The act of buying the Mac was painless if not terribly unique. I walked into my local Best Buy store, grabbed the Mac mini box off the shelf (I swear, I have books that are larger) and headed home (stopping briefly at the register to pay). The mini is pretty basic. It comes with no monitor, no keyboard, no mouse. And I was mostly content with this since I have these already. 
&lt;/p&gt;&lt;p&gt;I say "mostly" because there's a part of me that really wanted to go native, to follow the spirit of the famous saying which Wikipedia attributes to &lt;a href="http://en.wikipedia.org/wiki/Saint_Ambrose"&gt;Saint Ambrose&lt;/a&gt;: &lt;span style="color:black; font-family:Helvetica"&gt;&lt;em&gt;when in Apple land, do as the Appleonians do&lt;/em&gt;&lt;/span&gt;. But that part of me, which clung to the ideal of Apple peripherals on Apple devices, was very much at odds with the beautiful, fulfilling, symbiotic relationship I have with my keyboard. 
&lt;/p&gt;&lt;p&gt;Don't look at me like that. Lots of people who type for a living develop a dependency on their keyboards. It is not something to be trifled with. 
&lt;/p&gt;&lt;p&gt;So I was a little concerned, since Apple peripherals are of a different breed than my precious Microsoft natural keyboard and Explorer mouse combo, but as it turns out I needn't have worried. I just plugged the USB cable in alongside my monitor cable and sound input using a generic USB switch and was up and running in seconds. The Mac detected my wireless network too. Nothing sinister surfacing for Windows users so far. 
&lt;/p&gt;&lt;p&gt;&lt;span style="color:black; font-family:Helvetica"&gt;&lt;strong&gt;The Operating System&lt;/strong&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;OSX is fine. Really. It's been a few weeks now and I've grown comfortable with it. I know where things are, it comes with Dock and Spaces, both tools that require installing 3rd party downloads for similar functionality in Windows. And it has all the familiar Unix terminal tools and directory structure, which is familiar to me. But on balance, I have to say that Windows 7 kicks its butt. 
&lt;/p&gt;&lt;p&gt;Now, now. Unball your fists and take your seats Apple fan boys. My blog, my opinions. I just call 'em like I see 'em. 
&lt;/p&gt;&lt;p&gt;To be fair, OSX stomps on XP with regard to aesthetics, and Vista's stability issues make it a non-contender. But next to Windows 7, OSX feels... I dunno, outdated. I'm sure OS11 will fare better against my subjective and admittedly biased comparison, but OSX is still pretty okay. It's nothing to be ashamed of, and at the moment I see no reason to cover it deeper as the specifics aren't relevant to developing for the iPad. 
&lt;/p&gt;&lt;p&gt;Other than you have to have it to do so, of course. 
&lt;/p&gt;&lt;p&gt;&lt;span style="color:black; font-family:Helvetica"&gt;&lt;strong&gt;The Development Environment&lt;/strong&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;Which brings me to XCode. 
&lt;/p&gt;&lt;p&gt;XCode is Apple's standard development environment. If you want to develop for the Mac, the iPhone, or the iPad, you'll want to install it and the appropriate SDKs. They're available from Apple's developer site and they're free. 
&lt;/p&gt;&lt;p&gt;If you're an experienced Visual Studio developer, you're in for an adjustment. I'm not here to slam XCode. After all, I'm all about diversifying skill sets. I've dabbled in Delphi, played with Power Builder, and exercised with Eclipse. I have tinkered around with my share of IDEs on various OSs and I can honestly say that I have never found a serious development environment that made me miss Dev Studio more than Apple's XCode and its partner in crime, Interface Builder. 
&lt;/p&gt;&lt;p&gt;Each session, my blood pressure would begin to rise almost immediately. Within a few minutes I would begin reflecting on how much my Mac mini resembled an oversized hockey puck. Soon I would consider how it might be satisfying to see it serve in that capacity. Invariably I would stomp away in disgust, fuming. "How can anyone make a decent application with such a crummy tool?" 
&lt;/p&gt;&lt;p&gt;Of course, a bizzillion apps in the app store paint a different story. Clearly people can and do write apps, some of them quite good, using XCode. I knew I must be missing something. 
&lt;/p&gt;&lt;p&gt;When I actually stopped to analyze myself I found that the peculiar workings of the IDE, the seemingly unstable interactions between XCode and Interface Builder, and my general unfamiliarity of the environment itself were not solely to blame for my aggravation. I've used some really rough development tools in the past and I've certainly seen worse. But what really bothered me the most, the difference that made writing a simple application unbearable, was typing. Yes, even on my glorious keyboard, typing was a problem. 
&lt;/p&gt;&lt;p&gt;At first I thought it was my keyboard itself and this issue stemmed from the bad mojo begot from connecting a Windows keyboard to a Mac. But no. It turns out that Macs handle a few key navigation strokes differently than nearly every other operating system known to man. Keys like Home, End, Page Up, Page Down, the arrows keys, and the combinations of these with Control and Shift behave differently in ways that seem innocuous but have vile implications to those immersed in the autonomic process of translating thought into keystrokes. 
&lt;/p&gt;&lt;p&gt;&lt;span style="color:black; font-family:Helvetica"&gt;&lt;strong&gt;Remapping Your Keys &lt;/strong&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;Google reveals that a lot of people have this complaint about the Mac and in retrospect I've come to the conclusion that if Saint Ambrose had to contend with muscle memory, the "when in Rome" saying would never have been coined. So making keys work in XCode in a more familiar fashion is my number one recommendation to those developers with a Windows background. It's easy, requires only a couple of minutes, and will have a major impact on your productivity. 
&lt;/p&gt;&lt;p&gt;&lt;img align="left" src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr1.png" alt="" /&gt;&lt;span style="color:black; font-family:Helvetica"&gt;&lt;strong&gt;1. Remapping "Spaces" &lt;/strong&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;"Spaces", Apple's virtual desktop manager, uses the Control + arrow key combinations by default. You can change this from the system preferences. I chose the "&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr2.png" alt="" /&gt; + Arrow Keys" option as shown here. The non-Windows &lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr3.png" alt="" /&gt;symbol signifies the "command" key which, incidentally, is just another name for the Apple key. If you're using an Apple keyboard, it probably looks like this: &lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr4.jpg" alt="" /&gt;. In my case the Windows key, which is positioned in the same place, serves this purpose. 
&lt;/p&gt;&lt;p&gt;This frees us up to define the Control + arrow combinations when we remap XCode. 
&lt;/p&gt;&lt;p&gt;             
 &lt;/p&gt;&lt;p&gt;&lt;em&gt;So, note to the Windows man: for future reference, &lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr5.png" alt="" /&gt;equals &lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr6.png" alt="" /&gt;. &lt;/em&gt;
	&lt;/p&gt;&lt;p&gt;             
 &lt;/p&gt;&lt;p&gt;&lt;img align="left" src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr7.png" alt="" /&gt;&lt;strong&gt;2. Remapping XCode&lt;/strong&gt;
	&lt;/p&gt;&lt;p&gt;For many uses you can remap the keyboard by modifying the DefaultKeyBindings.dict file either directly or indirectly. XCode itself doesn't honor this file, however. Instead XCode has its own key binding mechanism which is quite a bit easier than doing it by hand. You can access this functionality from the main menu by selecting "XCode", then "Preferences". From the preferences dialog, choose the "Key Bindings" icon. The resulting dialog state is shown here. 
&lt;/p&gt;&lt;p&gt;If you want, you can change the default bindings, but I chose to create a new set, a copy of the defaults to work with. Do this by clicking on the "plus" symbol on the bottom, left hand corner of the window, and name it however you see fit. 
&lt;/p&gt;&lt;p&gt;To change a binding, select the appropriate list item by description and double click on the second field, the column entitled "Key", putting the dialog in key capture mode. This mode hosts two more "+" and "-" buttons next to the selected list of key combinations (not shown here). You can either replace an existing combination or hit the "+" button to add a new one. Type the key combination you want to assign. 
&lt;/p&gt;&lt;p&gt;             
 &lt;/p&gt;&lt;p&gt;Below is a list of key bindings which have been most useful to me. You may find others. There are definitely Windows keystrokes that are not covered here, but even these few adjustments will significantly enhance your coding experience. 
&lt;/p&gt;&lt;div style="text-align: center"&gt;&lt;table style="border-collapse:collapse" border="0"&gt;&lt;colgroup&gt;&lt;col style="width:300px" /&gt;&lt;col style="width:102px" /&gt;&lt;col style="width:224px" /&gt;&lt;/colgroup&gt;&lt;tbody valign="top"&gt;&lt;tr style="height: 19px; background: black"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid #404040 1.0pt; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="color:white; font-family:Helvetica; font-size:10pt"&gt;&lt;strong&gt;Command&lt;/strong&gt;&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid #404040 1.0pt; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="color:white; font-family:Helvetica; font-size:10pt"&gt;&lt;strong&gt;Key&lt;/strong&gt;&lt;/span&gt; &lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  solid #404040 1.0pt; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="color:white; font-family:Helvetica; font-size:10pt"&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Move Word Backward&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="bottom" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;^&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr8.png" alt="" /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Control + Left arrow&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Move Word Backward Extending Selection&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;^&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr9.png" alt="" /&gt;&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr10.png" alt="" /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Control + Shift + Left arrow&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Move Word Forward&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;^ &lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr11.png" alt="" /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Control + Right arrow&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Move Word Forward Extending Selection&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;^&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr12.png" alt="" /&gt;&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr13.png" alt="" /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Control + Shift + Right arrow&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Move to Beginning of Document&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;^&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr14.png" alt="" /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Control + Home&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Move to Beginning of Document Extending Selection&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;^&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr15.png" alt="" /&gt;&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr16.png" alt="" /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Control + Shift + Home&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Move to Beginning of Line&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr17.png" alt="" /&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Home&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Move to Beginning of Line Extending Selection&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr18.png" alt="" /&gt;&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr19.png" alt="" /&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Shift + Home&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Move to End of Document&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;^&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr20.png" alt="" /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Control + End&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Move to End of Document Extending Selection&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;^&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr21.png" alt="" /&gt;&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr22.png" alt="" /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Control + Shift + End&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Move to End of Line&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr23.png" alt="" /&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;End&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Move to End of Line Extending Selection&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr24.png" alt="" /&gt;&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr25.png" alt="" /&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Shift + End&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Page Up&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr26.png" alt="" /&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Page Up&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Page Down&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="bottom" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr27.png" alt="" /&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Page Down&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Copy&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;^C&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Control + C&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Cut&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;^X&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Control + X&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Paste&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;^V&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Control + V&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 19px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Undo&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;^Z, &lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr28.png" alt="" /&gt;&lt;img src="http://www.codingmonk.com/CodingMonk2/images/www_codingmonk_com/CodingMonk2/080410_0159_Postcardsfr29.png" alt="" /&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Control + Z or Alt + Backspace&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 17px; background: white"&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  solid #404040 1.0pt; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;Redo&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  none"&gt;&lt;p&gt;&lt;span style="font-size:10pt"&gt;^Y &lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="middle" style="padding-top: 1px; padding-left: 7px; padding-bottom: 1px; padding-right: 7px; border-top:  none; border-left:  none; border-bottom:  solid #404040 1.0pt; border-right:  solid #404040 1.0pt"&gt;&lt;p&gt;&lt;span style="font-family:Verdana; font-size:10pt"&gt;Control + Y&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Next article we'll start digging into the actual development process.&lt;span style="font-family:MS Shell Dlg 2; font-size:8pt"&gt;
		&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk/aggbug/29.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jim Fisher</dc:creator>
            <guid>http://www.codingmonk.com/CodingMonk/archive/2010/08/04/postcards-from-apple-land-muscle-memory-trumps-saint-ambrose.aspx</guid>
            <pubDate>Wed, 04 Aug 2010 06:59:44 GMT</pubDate>
            <wfw:comment>http://www.codingmonk.com/CodingMonk/comments/29.aspx</wfw:comment>
            <comments>http://www.codingmonk.com/CodingMonk/archive/2010/08/04/postcards-from-apple-land-muscle-memory-trumps-saint-ambrose.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://www.codingmonk.com/CodingMonk/comments/commentRss/29.aspx</wfw:commentRss>
        </item>
        <item>
            <title>New Fruit in the 2010 New Lease Resolution</title>
            <link>http://www.codingmonk.com/CodingMonk/archive/2010/07/17/new-fruit-in-the-2010-new-lease-resolution.aspx</link>
            <description>&lt;p&gt;So... 
&lt;/p&gt;&lt;p&gt;What's up? 
&lt;/p&gt;&lt;p&gt;It's, uh, already that time again, isn't it? Another year, another renewed lease for my domains. I'm pleased to say that, true to my &lt;a href="/archive/2009/08/10/site-cleanup-and-new-lease-resolutions.aspx"&gt;2009 new lease resolution&lt;/a&gt;, I was able to successfully produce an unprecedented &lt;a href="/archive/2009/08/14/the-textboxeditmask-behavior.aspx"&gt;two&lt;/a&gt;
		&lt;a href="/archive/2009/08/09/codingmonk-edit-mask-notation.aspx"&gt;posts&lt;/a&gt; in a year! Amazing, right? 
&lt;/p&gt;&lt;p&gt;Ahem. 
&lt;/p&gt;&lt;p&gt;Yes, well. Despite my somewhat limited blogging, things have been reasonably active on the world's technology front. The last twelve months have brought us a new version of Visual Studio, Silverlight, Expression Blend, Subtext, various Android phones, the Nook, and &lt;a href="http://www.apple.com"&gt;that other company&lt;/a&gt; released the iPad among other things. 
&lt;/p&gt;&lt;p&gt;I confess that I've been nursing a bit of envy at that last one with the touch screen interface, so a few months ago I took the plunge and bought some &lt;a href="http://www.apple.com/iphone"&gt;new&lt;/a&gt;
		&lt;a href="http://www.apple.com/ipad"&gt;Apple&lt;/a&gt;
		&lt;a href="http://www.apple.com/macmini"&gt;hardware&lt;/a&gt;. Expect the next year here at the Monk to bring articles describing a how to develop on these devices, especially the iPad, written from a Windows-man's perspective. 
&lt;/p&gt;&lt;p&gt;Hopefully we'll see more than two. &lt;a href="/archive/2010/07/16/postcards-from-apple-land-a-venture-into-enemy-territory.aspx"&gt;This one&lt;/a&gt;, categorized under "iOS" on the Zone menu to the left, should kick us off and explain just what kind of crazy has possessed me. &lt;/p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk/aggbug/28.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jim Fisher</dc:creator>
            <guid>http://www.codingmonk.com/CodingMonk/archive/2010/07/17/new-fruit-in-the-2010-new-lease-resolution.aspx</guid>
            <pubDate>Sun, 18 Jul 2010 04:16:26 GMT</pubDate>
            <comments>http://www.codingmonk.com/CodingMonk/archive/2010/07/17/new-fruit-in-the-2010-new-lease-resolution.aspx#feedback</comments>
            <wfw:commentRss>http://www.codingmonk.com/CodingMonk/comments/commentRss/28.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Postcards from Apple Land: A Venture into Enemy Territory</title>
            <category>iOS</category>
            <link>http://www.codingmonk.com/CodingMonk/archive/2010/07/16/postcards-from-apple-land-a-venture-into-enemy-territory.aspx</link>
            <description>&lt;p&gt;I don't know what's gotten into me. Some creepy form of mid-life crisis I suppose, but yes. I can confirm the rumors are true: 
&lt;/p&gt;&lt;p&gt;I bought a Mac. 
&lt;/p&gt;&lt;p&gt;As I rationalized it to an associate&lt;span style="color:#225522"&gt;, &lt;/span&gt;this doesn't mean for me what it may for others:&lt;span style="color:#225522"&gt;
		&lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="color:#225522"&gt;"When people say they decided to get a Mac, it often means they replaced their PC with a Macintosh.  Fat chance.  I've still got my main workstation (Win7), my test box (Vista), my general purpose server (Win Server 2008), my Tablet PC (Vista), my living room Media Center (Win7), my MAME-based arcade machine in the game room (XP), plus a slew of Windows laptops, net-books, and desktops used by my wife and kids or sitting in the garage waiting for the right project to come along.  &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="color:#225522"&gt;"I haven't exactly thrown Microsoft away and moved over to the dark side." &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="color:black"&gt;Yes, cognitive dissonance and I are good friends. &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="color:black"&gt;So what events led to me committing the eighth deadly sin? &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="color:black"&gt;It was actually a progression. My wife gave me an iPhone for my birthday (much as Eve tempted Adam with an Apple, I believe) and I had the opportunity to experience firsthand the tactile interface and infrastructure Apple has put together for developers to sell their work.  Shortly after, I picked up an iPad. Same touch interface, same application infrastructure, much bigger screen. I just couldn't help myself. &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="color:black"&gt;It took all of a minute for the developer in me to raise his head and begin eyeing it as a fresh, new platform with a prebuilt, thriving distribution network. Development for the iPad seems like something too big not to look into.  And, of course, you can only do that on a Mac (or a Hackintosh, but I looked into that and it seemed less trouble to just buy the Mac mini).  &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="color:black"&gt;So yes, I've an iPhone, an iPad, and a Macintosh. &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="color:black"&gt;And it makes me feel kinda dirty.  &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;strong&gt;You may say I'm a Judas, but I'm not the only one. &lt;/strong&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="color:black"&gt;One thing is certain: I'm not alone. Since the release of the iPhone, internet forums and newsgroups have be inundated by developers asking if there's a way to write apps for these devices from a Windows machine and while I've seen a little headway in this department with so-called "jail broken" devices, and promises of bigger things to come, for now Apple has taken steps to ensure that nearly all iPhone/iPad development is restricted to those machines running OSX. Because of this, I'm confident that right now there are quite a few Windows developers in the same boat I am, looking to find their way around the development offerings of Apple and hoping to realize their iOS solutions. &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="color:black"&gt;In Lennon's words: "&lt;em&gt;Imagine all the people".&lt;/em&gt;
		&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="color:black"&gt;That's what CodingMonk is about, isn't it?  Recording my experiences along the way to help save trouble for others.  So following the convention, I've added a new category to the site: "iOS", since this is Apple's operating system for all of their so-called iTouch devices: "iPod Touch", iPhone, and iPad.  This is the place where I'll record my exploits in iOSdevelopment.&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Disclaimer &lt;/strong&gt;
	&lt;/p&gt;&lt;p&gt;Despite my affinity for Windows, I should confess up front that I haven't started this journey as a complete n00b to non-Microsoft offerings. I spent a decade or so paying hobbyist homage to Linux, so Apple's shift to Posix compliancy with OSX translates into a measure of fluency for me. Augmenting this is the mental osmosis accompanying a few years sharing my study with my wife's "Macintoy". So I'm not really jumping into waters uncharted. As such, when I record my explorations, I might paint the Apple landscape less critically than some fellow Windows fan-boys feel I ought. To those peers of mine, please accept my sincere apologies. That said, I've spent the last couple of decades with a decided aversion to Macs in general and Apple specifically. This too may influence my opinions against the Mac unfairly, so to the Apple aficionados out there, ditto. 
&lt;/p&gt;&lt;p&gt;&lt;a href="archive/2010/08/04/postcards-from-apple-land-muscle-memory-trumps-saint-ambrose.aspx"&gt;Next article&lt;/a&gt;, before I really delve into the act of developing, I'll cover the set up of my shiny new Apple system, how I integrated it into my workspace, and how I configured it to work satisfactorily under the standard of my Windows biased tastes.&lt;/p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk/aggbug/27.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jim Fisher</dc:creator>
            <guid>http://www.codingmonk.com/CodingMonk/archive/2010/07/16/postcards-from-apple-land-a-venture-into-enemy-territory.aspx</guid>
            <pubDate>Sat, 17 Jul 2010 00:50:29 GMT</pubDate>
            <wfw:comment>http://www.codingmonk.com/CodingMonk/comments/27.aspx</wfw:comment>
            <comments>http://www.codingmonk.com/CodingMonk/archive/2010/07/16/postcards-from-apple-land-a-venture-into-enemy-territory.aspx#feedback</comments>
            <wfw:commentRss>http://www.codingmonk.com/CodingMonk/comments/commentRss/27.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Downloads and Watermarks</title>
            <link>http://www.codingmonk.com/CodingMonk/archive/2010/05/02/downloads-and-watermarks.aspx</link>
            <description>&lt;p&gt;I was able to find some time and put a little work into the site this weekend. The end result is a presentation for the site downloads. The downloads folder has been there for a while, slowly collecting files which either accompany postings or I just find useful to put there, but it hasn't had a unified face. &lt;/p&gt;
&lt;p&gt;Well, now it does. You'll find it by following the "Downloads" link in the "action menu" across the top of the page. &lt;/p&gt;
&lt;p&gt;Here you'll find items such as the TextboxEditMask or the sample Java Script Application Code Library (JACL), both of which have been discussed in previous postings. Additionally, you'll find a couple of things that have no accompanying articles, such as the TextboxWatermark behavior, or the DatabaseProxy wrapper which I've been using since .Net 1.0 to streamline my SQL Server access. &lt;/p&gt;
&lt;p&gt;As I write more articles, I'll continue to post any code samples here, but I'll also continue to throw things out there with little or no documentation. Feel free to download and toy around with anything there.&lt;/p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk/aggbug/26.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jim Fisher</dc:creator>
            <guid>http://www.codingmonk.com/CodingMonk/archive/2010/05/02/downloads-and-watermarks.aspx</guid>
            <pubDate>Sun, 02 May 2010 08:02:34 GMT</pubDate>
            <comments>http://www.codingmonk.com/CodingMonk/archive/2010/05/02/downloads-and-watermarks.aspx#feedback</comments>
            <wfw:commentRss>http://www.codingmonk.com/CodingMonk/comments/commentRss/26.aspx</wfw:commentRss>
        </item>
        <item>
            <title>The TextboxEditMask Behavior</title>
            <category>Expression Blend</category>
            <link>http://www.codingmonk.com/CodingMonk/archive/2009/08/14/the-textboxeditmask-behavior.aspx</link>
            <description>&lt;p&gt;Behaviors, which implement a mechanism for wrapping control functionality into reusable blocks, were introduced in Expression Blend 3. They're not a new concept; packaging control event handlers in a separate, reusable class has been possible since .Net was first introduced. What &lt;em&gt;is&lt;/em&gt; new is the seamless integration with a Visual Designer (in this case, Expression Blend). Behaviors enable a truly great design-time experience when applying custom functionality to UI controls. Something that, until now, has required an unwieldy amount of custom code. &lt;/p&gt;
&lt;p&gt;The TextboxEditMask behavior, as you might guess from the name, adds edit mask functionality to a textbox. It comes in both Silverlight and a WPF flavors. You can: &lt;/p&gt;
&lt;ul style="MARGIN-LEFT: 54pt"&gt;
    &lt;li&gt;Download the &lt;a href="http://www.codingmonk.com/downloads/TextBoxEditMask_SourceCode_1.1.zip"&gt;source code&lt;/a&gt; as a Visual Studio 2008 project and compile it yourself, or &lt;/li&gt;
    &lt;li&gt;You can just &lt;a href="http://www.codingmonk.com/downloads/TextBoxEditMask_Binaries_1.1.zip"&gt;Trust the Monk&lt;/a&gt; with the pre-compiled DLLs. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style="FONT-SIZE: 9pt"&gt;&lt;em&gt;    [Note: the above two links reference the 1.1 version of this behavior] &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: #006802"&gt;&lt;strong&gt;Behaviors: the Quick Run Down &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This isn't a tutorial on behaviors, so I won't delve too deeply into the details of their usage, but at the time of this writing they really are a relatively new feature on the Expression Blend landscape, so a quick step through of their use is in order: &lt;/p&gt;
&lt;p&gt;&lt;img alt="" align="left" src="http://codingmonk.com/images/codingmonk_com/081409_0813_TheTextboxE1.png" /&gt;&lt;strong&gt;Step one&lt;/strong&gt;: Reference the DLL. For this article, choose either: &lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;span style="FONT-SIZE: 9pt"&gt;CodingMonk.Wpf.Behaviors.TextboxEditMask.dll &lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span style="FONT-SIZE: 9pt"&gt;CodingMonk.Silverlight.Behaviors.TextboxEditMask.dll &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;depending on your project type. &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;       &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;       &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;       &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;       &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;&lt;strong&gt;Step two&lt;/strong&gt;: Drag the behavior from your "Assets" pane and drop it on to a control (in this case, a &lt;span style="FONT-FAMILY: Courier New"&gt;TextBox&lt;/span&gt; control). This creates an instance of the behavior and applies it to the control. &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;       &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;       &lt;/p&gt;
&lt;p&gt;       &lt;/p&gt;
&lt;p&gt;       &lt;/p&gt;
&lt;p&gt;       &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Finally:&lt;/strong&gt; Select the behavior you've just applied from the "Objects and Timeline" pane:&lt;strong&gt; &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="" align="left" src="http://codingmonk.com/images/codingmonk_com/081409_0813_TheTextboxE2.png" /&gt;  &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;       &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;       &lt;/p&gt;
&lt;p&gt;       &lt;/p&gt;
&lt;p&gt;       &lt;/p&gt;
&lt;p&gt;       &lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: #006802"&gt;&lt;strong&gt;Properties of the TextboxEditMask &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;After selecting an instance of the TextboxEditMask behavior, three custom properties will show in the "Properties" pane: &lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://codingmonk.com/images/codingmonk_com/081409_0813_TheTextboxE3.png" /&gt; &lt;/p&gt;
&lt;p&gt;The first, &lt;strong&gt;EditMask&lt;/strong&gt;, holds the pattern to be enforced. This mask should conform to the &lt;a href="http://www.codingmonk.com/archive/2009/08/09/codingmonk-edit-mask-notation.aspx"&gt;CodingMonk Edit Mask notation (version 1.1&lt;/a&gt;). The notation is relatively easy to learn, especially if you've had experience with more exhaustive notations such as Regular Expressions. &lt;/p&gt;
&lt;p&gt;The second parameter, &lt;strong&gt;MatchCaseToMask&lt;/strong&gt;, is a checkbox. This is off by default, rendering the edit mask case-insensitive. This means when a letter appears in an edit mask, either the upper or lowercase version of that letter is allowed. If the pattern calls for the capitol letter "A", the lowercase "a" would also be accepted and displayed as lowercase. Checking this box causes the text to conform to the case of the pattern. In this example, the lowercase "a" would still be allowed as input, but it would be rendered in uppercase in the textbox. &lt;/p&gt;
&lt;p&gt;The final parameter, &lt;strong&gt;PadEmptyBehavior&lt;/strong&gt;, is a drop down list with the two possible options: &lt;/p&gt;
&lt;ul style="MARGIN-LEFT: 90pt"&gt;
    &lt;li&gt;InferCharacter &lt;/li&gt;
    &lt;li&gt;UseUnderscore &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These effect what is displayed when backspaces and deletes occur. Since edit masks are typically fixed width, the backspace and delete keys have the effect of replacing the next and previous character. InferCharacter, the default, makes a decision based on allowable characters in the pattern. The alternative, UseUnderscore, simply enforces an underscore for character positions not yet filled in. &lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: #006802"&gt;&lt;strong&gt;Coding Considerations &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Although behaviors are currently an Expression Blend feature, TextboxEditMask allows you to set its properties and call methods from within your source code as well. To do this, you must first get a reference to the behavior. A static dictionary is provided at the class level, which allows you to lookup instances of the TextboxEditMask by the control they are applied to. For example: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;    &lt;span style="COLOR: #2b91af"&gt;TextboxEditMask&lt;/span&gt; phonemask = &lt;span style="COLOR: #2b91af"&gt;TextboxEditMask&lt;/span&gt;.Instances[tbPhoneNumber]; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So changing the behavior's properties at runtime is straightforward: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;    phonemask.PadEmptyBehavior = &lt;span style="COLOR: #2b91af"&gt;TextboxEditMask&lt;/span&gt;.&lt;span style="COLOR: #2b91af"&gt;PadEmptyCharacter&lt;/span&gt;.UseUnderscore;&lt;br /&gt;
    phonemask.EditMask="(###)###-####"; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The TextboxEditMask behavior offers an additional helper property, &lt;span style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;MaskCompliantEmptyText&lt;/span&gt;, for your code. This property provides a string of text that effectively represents an empty value which is compliant to the current &lt;span style="FONT-FAMILY: Courier New"&gt;EditMask&lt;/span&gt; property. This is helpful when clearing a field to nothing: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;    tbPhoneNumber.Text=&lt;span style="COLOR: #2b91af"&gt;TextboxEditMask&lt;/span&gt;.Instances[tbPhoneNumber].MaskCompliantEmptyText; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Which, following the previous lines of code, would set the textbox display to: &lt;/p&gt;
&lt;p&gt;    &lt;span style="FONT-FAMILY: Courier New; FONT-SIZE: 10pt"&gt;(___)___-____&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;It's worth pointing out that the edit mask doesn't try to outthink you (the developer), and it doesn't try to undo what you assign in code. So if your edit mask defines a pattern meant for a time in 12 hour format: &lt;/p&gt;
&lt;p&gt;    &lt;span style="FONT-FAMILY: Courier New; FONT-SIZE: 9pt"&gt;[ 01]#[*[ 0]#|1[0-2]]:[0-5]# [AP]M&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;But you pre-populate it with: &lt;/p&gt;
&lt;p&gt;    &lt;span style="FONT-FAMILY: Courier New; FONT-SIZE: 9pt"&gt;malum in se &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Don't be surprised if users find your app unintuitive. &lt;/p&gt;
&lt;p&gt;    &lt;/p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk/aggbug/25.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jim Fisher</dc:creator>
            <guid>http://www.codingmonk.com/CodingMonk/archive/2009/08/14/the-textboxeditmask-behavior.aspx</guid>
            <pubDate>Fri, 14 Aug 2009 08:14:13 GMT</pubDate>
            <comments>http://www.codingmonk.com/CodingMonk/archive/2009/08/14/the-textboxeditmask-behavior.aspx#feedback</comments>
            <slash:comments>18</slash:comments>
            <wfw:commentRss>http://www.codingmonk.com/CodingMonk/comments/commentRss/25.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Site Cleanup and New Lease Resolutions</title>
            <link>http://www.codingmonk.com/CodingMonk/archive/2009/08/10/site-cleanup-and-new-lease-resolutions.aspx</link>
            <description>&lt;p&gt;Every 12 months I'm faced with the task of paying annual fees to renew the lease on my domains. When the time comes, and it always does, I'm accosted with a familiar pang of guilt: How little attention I pay my poor, neglected site. Am I consistent in sharing with the rest of the world the things I can contribute? Do I frequently post the my hard-earned solutions today to help some poor souls faced with the same problems tomorrow? &lt;/p&gt;
&lt;p&gt;A quick review usually dates my last blogs sometime around... last year's domain renewal date. &lt;/p&gt;
&lt;p&gt;For shame! &lt;/p&gt;
&lt;p&gt;I shake my head, disappointed in myself, and reach for my credit card, resolutely declaring that this year will be different! This year, I always say, I will blog prolifically. People will come to my site and find what they need. After reading my blog, they will immediately stand and dance a jig for the obscure, yet pressing answers that they find. This time, I proclaim, my annual renewal fee won't be for naught! &lt;/p&gt;
&lt;p&gt;And this year it's true. I swear it! &lt;/p&gt;
&lt;p&gt;Actually, this New Lease's Resolution couldn't have come at a better time. Only a few short weeks ago Microsoft released a new version of &lt;a href="http://www.microsoft.com/expression/products/Blend_Overview.aspx"&gt;Expression Blend&lt;/a&gt;, a product that I have come to hold in high regard despite my initial distaste and skepticism. Packaged with the new version of Blend is a formalization of a pattern which has been floating around in various forms for several years now. In Blend, the approach is called "Behaviors" and the UI makes using behaviors a blissful experience. Behaviors will definitely be a topic of those promised blogs. &lt;/p&gt;
&lt;p&gt;For now, I've put a little work in on the site. A few additional empty Zones appear to the left, place holders for the content I've just sworn to deliver. If you're familiar with my site, a fan with nothing better to do than avidly follow my two blogs a year (I know you're out there), you might also notice the absence of previously existing zones related to "Interactive Fiction". When the site was in development, these articles were borrowed for the purposes of testing with actual content. If you are looking for these articles, you can still find them at &lt;a href="http://www.OnyxRing.com"&gt;www.OnyxRing.com&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Finally, I've stepped out of my box and updated the site with respect to browser compatibility. It was built originally for IE6, but after a bit of work, it now renders appropriately in newer versions (like IE8) as well as Firefox and Opera. If your browser disagrees, drop me a line and let me know. &lt;/p&gt;
&lt;p&gt;  &lt;/p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk/aggbug/24.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jim Fisher</dc:creator>
            <guid>http://www.codingmonk.com/CodingMonk/archive/2009/08/10/site-cleanup-and-new-lease-resolutions.aspx</guid>
            <pubDate>Mon, 10 Aug 2009 08:22:09 GMT</pubDate>
            <comments>http://www.codingmonk.com/CodingMonk/archive/2009/08/10/site-cleanup-and-new-lease-resolutions.aspx#feedback</comments>
            <wfw:commentRss>http://www.codingmonk.com/CodingMonk/comments/commentRss/24.aspx</wfw:commentRss>
        </item>
        <item>
            <title>CodingMonk Edit Mask Notation (version 1.1)</title>
            <category>General</category>
            <link>http://www.codingmonk.com/CodingMonk/archive/2009/08/09/codingmonk-edit-mask-notation.aspx</link>
            <description>&lt;p&gt;Typing in a text box is the most common means by which programs collect information from a user. Whether collecting a date stamp, a product key, or a phone number, specific pieces of information often have restrictions on their form. &lt;/p&gt;
&lt;p&gt;For example, a person typing in a text box may choose to enter their work phone in a number of different ways: &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;555-1212&lt;br /&gt;
(800)555-1212&lt;br /&gt;
Same as Home&lt;br /&gt;
1-800-555-1212&lt;br /&gt;
800.555.1212 &lt;/p&gt;
&lt;p&gt;Each of these is meaningful to human eyes, but if your system needs to use this information in some way to, for example, sort, search, or power an auto-dialer, a consistent format is needed. &lt;/p&gt;
&lt;p&gt;The most common way of enforcing a format in text is with post-input validation. That is, when the user finishes entering text, the system checks to see if the input conforms to an expected pattern. If it doesn't then the user is notified with a message resembling: &lt;/p&gt;
&lt;p&gt;    "Please use the following format to enter your number: (###) ###-####" &lt;/p&gt;
&lt;p&gt;And this reactive approach works, technically speaking, but at the price of the user experience. &lt;/p&gt;
&lt;p&gt;Edit mask controls allow the system to perform validation proactively, while the user is typing. If a keyed-in character doesn't comply with an expected value (the control's allowable "mask "), then it is ignored. In the previous phone number example, letters would be discarded so input such as "Same as Home" is never a possibility. As an additional advantage, edit mask controls are typically drop-and-go, requiring no additional coding. Instead, the input constraints they perform are defined by a notation. So one control could enforce a phone number pattern, then enforce a product key pattern, then enforce a weather code pattern, all by changing its "edit mask" notation. &lt;/p&gt;
&lt;p&gt;There are a number of edit mask controls out there and all vary in intricacy. Some are quite simplistic in nature, supporting a limited list of pre-defined masks, while other are considerably less basic. On a scale from basic to sophisticated, the notation utilized in Coding Monk edit masks leans more heavily toward the sophistication side of the scale; however, this does not necessarily mean that the notation is more complex out of the gate. Simple needs mean simple notations; as edit mask needs grow in complexity, so do the edit mask patterns. &lt;/p&gt;
&lt;p&gt;This document serves the dual purposes of reference and tutorial, defining the core notation, explaining how to use it, then finally giving examples of common edit mask patterns. &lt;/p&gt;
&lt;div&gt;
&lt;table style="BORDER-COLLAPSE: collapse; BACKGROUND: #bfbfbf" border="0"&gt;
    &lt;colgroup&gt;&lt;col style="WIDTH: 638px" /&gt;&lt;/colgroup&gt;
    &lt;tbody valign="top"&gt;
        &lt;tr style="HEIGHT: 48px"&gt;
            &lt;td style="PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;strong&gt;&lt;em&gt;Note: &lt;/em&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
            &lt;p&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;em&gt;This document is distributed in a variety of media formats. If you are not viewing this online from the CodingMonk site and want to ensure the latest version, it can be found at the following URL:&lt;/em&gt; &lt;/span&gt;&lt;/p&gt;
            &lt;p&gt;&lt;a href="http://codingmonk.com/archive/2009/08/09/codingmonk-edit-mask-notation.aspx"&gt;&lt;span style="COLOR: white; FONT-SIZE: 8pt"&gt;http://codingmonk.com/archive/2009/08/09/codingmonk-edit-mask-notation.aspx&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;     &lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: #1f497d"&gt;&lt;strong&gt;Quick Reference: Reserved Notation Characters &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The following table lists the reserved characters used in Coding Monk's edit mask notation. In later sections, we'll explain in more detail about each of these; however, after the nuances of the notation have been digested, this tables can serve as a place to refresh your memory. Note that any character not listed here is interpreted as a literal. &lt;/p&gt;
&lt;div&gt;
&lt;table style="BORDER-COLLAPSE: collapse" border="0"&gt;
    &lt;colgroup&gt;&lt;col style="WIDTH: 146px" /&gt;&lt;col style="WIDTH: 87px" /&gt;&lt;col style="WIDTH: 405px" /&gt;&lt;/colgroup&gt;
    &lt;tbody valign="top"&gt;
        &lt;tr style="BACKGROUND: black"&gt;
            &lt;td style="BORDER-BOTTOM: black 0.5pt solid; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: black 0.5pt solid; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;&lt;span style="COLOR: white"&gt;Type &lt;/span&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: black 0.5pt solid; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: black 0.5pt solid; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="COLOR: white"&gt;Character(s)&lt;/span&gt;&lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: black 0.5pt solid; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: black 0.5pt solid; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;&lt;span style="COLOR: white"&gt;Description&lt;/span&gt; &lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;&lt;strong&gt;Wildcards&lt;/strong&gt;&lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;#&lt;/span&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;A numeric digit.  &lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;   &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;&amp;lt;&lt;/span&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;Any letter converted to lowercase.&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;   &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;&amp;gt;&lt;/span&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;Any letter converted to uppercase.&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;   &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;&amp;amp;&lt;/span&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;Any letter, regardless of case. &lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;   &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;@&lt;/span&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;Any alphanumeric character&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;   &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;!&lt;/span&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;Any alphanumeric character, converted to lowercase.&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;   &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;^&lt;/span&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;Any alphanumeric character; converted to uppercase.&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: #d9d9d9 0.5pt solid; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;   &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: #d9d9d9 0.5pt solid; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;_ &lt;/span&gt;&lt;/p&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;em&gt;(underscore)&lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: #d9d9d9 0.5pt solid; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;Any character at all.&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;&lt;strong&gt;Groups&lt;/strong&gt;&lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;[&lt;/span&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;Begins a grouping of mask characters.&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;   &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;[*&lt;/span&gt;&lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;Begins a validation expression.&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;   &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;]&lt;/span&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;Closes the grouping or validation expression. &lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: #bfbfbf 0.5pt solid; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;   &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: #bfbfbf 0.5pt solid; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: white; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;- &lt;/span&gt;&lt;/p&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;em&gt;(hyphen)&lt;/em&gt;&lt;/span&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: #bfbfbf 0.5pt solid; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: white; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;Used to define ranges of characters within groupings. &lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: #d9d9d9 0.5pt solid; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;&lt;strong&gt;Validation&lt;/strong&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: #d9d9d9 0.5pt solid; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;*&lt;/span&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: #d9d9d9 0.5pt solid; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;Used alone outside of a group to identify the start of a validation range.&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: #d9d9d9 0.5pt solid; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;&lt;strong&gt;Escape&lt;/strong&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: #d9d9d9 0.5pt solid; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: white; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;\&lt;/span&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: #d9d9d9 0.5pt solid; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: white; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;Used to indicate that the next character should "escape" its reserved status and be interpreted as a literal character.&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
            &lt;td style="BORDER-BOTTOM: black 0.5pt solid; BORDER-LEFT: black 0.5pt solid; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: white; BORDER-TOP: medium none; BORDER-RIGHT: #d9d9d9 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;&lt;strong&gt;Repeat Expression&lt;/strong&gt; &lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: black 0.5pt solid; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: medium none; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p style="TEXT-ALIGN: center"&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;{&lt;/span&gt;&lt;span style="FONT-FAMILY: Book Antiqua; COLOR: gray"&gt;&lt;em&gt;n&lt;/em&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;}&lt;/span&gt;&lt;/p&gt;
            &lt;/td&gt;
            &lt;td style="BORDER-BOTTOM: black 0.5pt solid; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 7px; PADDING-RIGHT: 7px; BACKGROUND: #d9d9d9; BORDER-TOP: medium none; BORDER-RIGHT: black 0.5pt solid; PADDING-TOP: 1px" valign="middle"&gt;
            &lt;p&gt;Where &lt;span style="FONT-FAMILY: Book Antiqua"&gt;&lt;em&gt;n&lt;/em&gt;&lt;/span&gt; is a number, this notation causes the preceding expression to be repeated, appearing a total of &lt;span style="FONT-FAMILY: Book Antiqua"&gt;&lt;em&gt;n&lt;/em&gt;&lt;/span&gt; times&lt;/p&gt;
            &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;     &lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: #1f497d"&gt;&lt;strong&gt;Edit Mask Construction &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Edit mask expressions can be complex if the edit mask requirements are complex. That said, most uses of an edit mask are basic and the more complex masks are few and far between. By the end of this document, you'll have all the tools you need to make sophisticated masks. But first, we'll cover some basic concepts. &lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: #1f497d"&gt;&lt;strong&gt;Literals and Constants &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;As mentioned above, any character that is &lt;em&gt;not&lt;/em&gt; listed in the Reserved Notation Characters table is a &lt;strong&gt;literal&lt;/strong&gt;. This just means that these characters have no special meaning to the edit mask. The letter "A" simply represents the letter "A". A literal character specified by itself, which is to say an "ungrouped" literal, defines the only possible character in a given position. We call this lone-literal a &lt;strong&gt;constant&lt;/strong&gt; since it cannot be changed. &lt;/p&gt;
&lt;p&gt;The following expression demonstrates seven constants. Notice that positioning literals next to each other does not group them. They are still constants, just sequential ones: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;        abcdefg&lt;em&gt; &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;In the above mask notation, the first position allows only the lowercase letter 'a', the second position only the letter 'b', the third 'c', and so on. Since each of the character positions associated with this mask allow but one possible character, they are typically filled in and locked before input begins. The user cannot change these constants. Clearly, this expression serves no purpose but that of example. For true user input, we rely on groups and wildcards. &lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: #1f497d"&gt;&lt;strong&gt;Groups and Ranges &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Groups&lt;/strong&gt; are characters delimited by brackets (&lt;em&gt;[…]&lt;/em&gt;) and are used to define options against which a single character can be matched. To demonstrate, let us modify our previous example by wrapping it in brackets and making it a group: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;        [abcdefg] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Unlike our previous example which defined seven input positions accepting one value each, this example defines a single input position accepting one of seven possible values. That is, this grouping defines a character position into which the user may type one of the letters 'a', 'b', 'c', 'd', 'e', 'f', or 'g'. &lt;/p&gt;
&lt;p&gt;As a convenience, within groups the hyphen (or "dash") also acts as a reserved character used to represent a &lt;strong&gt;range&lt;/strong&gt; of sequential alternatives. Using this technique, our previous example could have been defined as: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;        [a-g] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt; It is also possible to intermingle ranges with other character options within brackets, so that: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;        [xz&lt;strong&gt;&lt;em&gt;a-f&lt;/em&gt;&lt;/strong&gt;j]&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;expands into: &lt;/p&gt;
&lt;p&gt;        &lt;span style="FONT-FAMILY: Courier New"&gt;[xz&lt;strong&gt;&lt;em&gt;abcdef&lt;/em&gt;&lt;/strong&gt;j] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;which defines a single position allowing one of nine different characters. Note that the hyphen's special status as a reserved character is limited to groups. Outside of groupings, the hyphen is considered a constant. &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;em&gt;&lt;strong&gt;Now for a glimpse forward&lt;/strong&gt;: Brackets can also define validations. Brackets with an asterisk as the first character in their contained sequence (&lt;/em&gt;[*…]&lt;em&gt;) are validation patterns. These are wholly different than the groupings described in this section and are mentioned only because they are delimited in a similar way (with brackets). For more on this subject see "&lt;/em&gt;Validation Expressions a.k.a. Regular Expressions"&lt;em&gt; later in this guide. &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: #1f497d"&gt;&lt;strong&gt;Wildcards &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Wildcards are devices used to avoid some of the tedium associated with building common groupings. There are eight special characters that are classified as wildcards. We listed them in the quick reference above, but we'll cover them again here with a little more context: &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;#    -        A numeric digit. This is equivalent to: &lt;span style="FONT-FAMILY: Courier New"&gt;[0123456789]&lt;/span&gt; (or&lt;em&gt; &lt;/em&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;[0-9]&lt;/span&gt;). &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;&amp;lt;    -        Any letter converted to lowercase; similar to &lt;span style="FONT-FAMILY: Courier New"&gt;[a-z]&lt;/span&gt;. &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;&amp;gt;    -        Any letter converted to uppercase, similar to &lt;span style="FONT-FAMILY: Courier New"&gt;[A-Z]&lt;/span&gt;. &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;&amp;amp;    -        Any letter, regardless of case (&lt;span style="FONT-FAMILY: Courier New"&gt;[a-zA-Z]&lt;/span&gt;). &lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;@    -        Any alphanumeric character; manually constructed as: &lt;span style="FONT-FAMILY: Courier New"&gt;[a-zA-Z0-9] &lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;!    -        Any alphanumeric character; converted to lowercase. This is similar to &lt;span style="FONT-FAMILY: Courier New"&gt;[a-z0-9]&lt;/span&gt; except that capitol letters are converted rather than discarded.&lt;em&gt; &lt;/em&gt;&lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;^    -    Any alphanumeric character; converted to uppercase. Similar to &lt;span style="FONT-FAMILY: Courier New"&gt;[A-Z0-9]&lt;/span&gt;except that lowercase letters are converted rather than discarded.&lt;span style="FONT-FAMILY: Courier New"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;_        -    Any character at all. If constructed manually, this would be a very large group indeed.&lt;em&gt; &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Wildcards can stand on their own, looking for all the world like a constant, but actually acting as group in its own right. Wildcards can also be embedded within proper groups, coupled together with literals, ranges, and other wildcards. For example, a four-digit hexadecimal number can be enforced with the following: &lt;/p&gt;
&lt;p&gt;    &lt;span style="FONT-FAMILY: Courier New"&gt;[#A-F][#A-F][#A-F][#A-F] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt; which could be expanded to: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;    [0-9A-F][0-9A-F][0-9A-F][0-9A-F] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: #1f497d"&gt;&lt;strong&gt;Escape &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The backslash (\) is also referred to as the &lt;em&gt;escape&lt;/em&gt; character. It is used to "escape" the special meanings of all reserved characters (including itself). For example, the following expression: &lt;/p&gt;
&lt;p&gt;    &lt;span style="FONT-FAMILY: Courier New"&gt;[abc#] &lt;/span&gt; &lt;span style="FONT-FAMILY: Courier New"&gt;&lt;em&gt; &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;will accept any one of the twelve characters: 'a', 'b', 'c', '0', '1', '2', '3', '4', '5', '6', '7', '8', or '9'. &lt;/p&gt;
&lt;p&gt;A similar expression with a slash "escaping" the wildcard ("\#") changes things: &lt;/p&gt;
&lt;p&gt;    &lt;span style="FONT-FAMILY: Courier New"&gt;[abc\#] &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The above notation signifies one of only four characters: 'a', 'b', 'c', or '#'. &lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: #1f497d"&gt;&lt;strong&gt;Repeat Values &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;When repeating a complex character pattern a few times, or even a simple pattern several times, it is often useful to specify a repeat value. This is accomplished by wrapping a numerical value in braces immediately following the character pattern to be duplicated. By doing so, the previous example of accepting a four-digit hexadecimal number can be reduced to: &lt;/p&gt;
&lt;p&gt;    [&lt;span style="FONT-FAMILY: Courier New"&gt;#A-F]{4}&lt;em&gt; &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;There are very specific rules which govern repeat values. Most of these are intuitive but we state them here in the interest of clarity: &lt;/p&gt;
&lt;ul style="MARGIN-LEFT: 54pt"&gt;
    &lt;li&gt;Repeat values apply to the complete pattern for an input character, which means that they &lt;strong&gt;&lt;em&gt;cannot occur within groupings&lt;/em&gt;&lt;/strong&gt;. Typically, a repeat value is specified immediately following a group. When braces occur within brackets, they are simply interpreted as literals and so will be included in the list of acceptable input. &lt;/li&gt;
    &lt;li&gt;The repeat value &lt;strong&gt;&lt;em&gt;must be numeric&lt;/em&gt;&lt;/strong&gt;. If the value contained within the braces cannot be translated into a number, the braces will again be interpreted as character literals. &lt;/li&gt;
    &lt;li&gt;The repeat value is adjusted to include the token being repeated. That is, the parser decrements the value by one to account for the character position already defined. In the previous example with a repeat value of 4, the parser repeats the grouping three additional times (4 minus 1). This means that &lt;strong&gt;&lt;em&gt;repeat values of one and zero have no effect&lt;/em&gt;&lt;/strong&gt;. Neither suppresses the previous character pattern, and neither repeats that pattern again. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style="COLOR: #1f497d"&gt;&lt;strong&gt;Validation Expressions (a.k.a. Regular Expressions) &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;So far, all of the functionality we've covered falls under the category of "iterative expressions", that is, expressions that test one-character of input at a time. For simple patterns, iterative expressions are all we need concern ourselves with. By the time the user finishes entering values into a social-security expression: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;    ###-##-#### &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;or a phone number pattern: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;    (###) ###-#### &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;we are guaranteed to have data that is formatted as we require it, but for more complex types of data, the iterative expression falls short. Consider the following expression for a 24 hour clock: &lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;    [012]#:[0-5]# &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This example pattern works well for most of the mask, accepting minutes in the range of 00 to 59 and eliminating the possibility of minutes input as 60 or above. The hour portion works reasonably well too. It allows us to enter 00 to 23 while excluding 30 or above. While this is close to what we want, it is not quite right since it also allows hours from 24 to 29 to be input. Alone, both 2 and 9 allowable. It is only when they are used together that one disallows the other. Clearly we need something more than iterative expressions to validate input. &lt;/p&gt;
&lt;p&gt;As it happens, there is another type of notation which lends itself well to this sort of validation: &lt;a href="http://en.wikipedia.org/wiki/Regular_expression"&gt;regular expressions&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;This is not a guide on regular expressions, there are many of those available on the internet. They are pertinent to this document, however, because they can be embedded within edit mask notation to serve as "validation expressions." To do this, we prefix a regular expression with a validation marker ('*') and enclose it in brackets as we would a grouping. The shortcomings of the previous time example can be solved by inserting the appropriate regular expression, enforcing a true 24 hour clock pattern: &lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: gray"&gt;    [&lt;span style="FONT-FAMILY: Courier New"&gt;012]#&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;&lt;span style="COLOR: #1f497d"&gt;&lt;strong&gt;&lt;em&gt;[*[01][0-9]|2[0-3]]&lt;/em&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="COLOR: gray"&gt;:[0-5]#&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;With this revision, when a user attempts to enter an invalid hour such as 29, the edit mask compares the input against the validation expression. Upon failure the caret is moved back so that the user can try again. &lt;/p&gt;
&lt;p&gt;Note that the regular expression tests only the input from the start of the validation bracket to the previous validation marker (or the start of input if one does not exist). To limit the range of characters, you may place a single validation marker (without brackets) at the start of the pattern to input. For example, the following will allow input of two letters followed by a two-digit number between 01 and 16 (e.g.: AK16): &lt;/p&gt;
&lt;p&gt;    &lt;span style="FONT-FAMILY: Courier New"&gt;&lt;span style="COLOR: #a6a6a6"&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span style="COLOR: #1f497d"&gt;&lt;strong&gt;&lt;em&gt;*&lt;/em&gt;&lt;/strong&gt;&lt;/span&gt;&lt;span style="COLOR: gray; TEXT-DECORATION: underline"&gt;[01]#&lt;/span&gt;&lt;em&gt;&lt;span style="COLOR: #1f497d"&gt;&lt;strong&gt;[*0#|1[0-6]]&lt;/strong&gt;&lt;/span&gt; &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The validation expression test only the input since the validation marker (underlined in this example), which excludes the first two letter characters.&lt;span style="COLOR: #1f497d"&gt;&lt;strong&gt; &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="COLOR: #1f497d"&gt;&lt;strong&gt;Sample Useful Expressions &lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The following are a handful of sample patterns. It should be apparent by now that this list is by no mean exhaustive, but these are included here for your convenience: &lt;/p&gt;
&lt;p&gt;     &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;    Phone number: &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;    &lt;span style="FONT-SIZE: 9pt"&gt;(###) ###-####&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;    Social Security:         &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;    &lt;span style="FONT-SIZE: 9pt"&gt;###-##-#### &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;    24 hour clock: &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;    &lt;span style="FONT-SIZE: 9pt"&gt;[ 012]#[*[ 01]#|2[0-3]]:[0-5]# &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;    12 hour clock:          &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;    &lt;span style="FONT-SIZE: 9pt"&gt;[ 01]#[*[ 0]#|1[0-2]]:[0-5]# [AP]M &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;    Date (between 1/1/1900 through 12/31/2199):&lt;span style="FONT-FAMILY: Courier New"&gt; &lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;    &lt;span style="FONT-SIZE: 9pt"&gt;[ 01]#[*[ 0]#|1[0-2]]/*[ 0123]#[*[ 012]#|3[01]]/*[12]#[*19|2[01]]##&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p style="MARGIN-LEFT: 36pt"&gt;&lt;span style="FONT-SIZE: 8pt"&gt;&lt;em&gt;&lt;strong&gt;A note on limitations in validation&lt;/strong&gt;: this pattern enforces the date as much as possible in the current spec. Only values between 1 and 12 are accepted for month and only values between 1 and 31 are accepted for day; however, version 1.1 of the CodingMonk edit mask notation does not support context between separate validation expressions. So rules limiting the number of days to 30 for months 4,6, 9, and 1, as well as 28 or 29 days for month 2 depending on the year are not yet possible. Look to revision 1.2 to support this.&lt;/em&gt;&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;    Percentage: &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;    &lt;span style="FONT-SIZE: 9pt"&gt;###[*100| ##| #]% &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;    Temperature in Celsius or Fahrenheit (between 0.0 and 199.9 degrees): &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;    &lt;span style="FONT-SIZE: 9pt"&gt;[ 01][ #]#[*###| ##| #].# [CF]&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 9pt"&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;    IPv6 address: &lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="FONT-FAMILY: Courier New"&gt;    &lt;span style="FONT-SIZE: 9pt"&gt;[#A-F]{4}:[#A-F]{4}:[#A-F]{4}:[#A-F]{4}:[#A-F]{4}:[#A-F]{4}:[#A-F]{4}:[#A-F]{4}     &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk/aggbug/23.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jim Fisher</dc:creator>
            <guid>http://www.codingmonk.com/CodingMonk/archive/2009/08/09/codingmonk-edit-mask-notation.aspx</guid>
            <pubDate>Sun, 09 Aug 2009 23:15:23 GMT</pubDate>
            <comments>http://www.codingmonk.com/CodingMonk/archive/2009/08/09/codingmonk-edit-mask-notation.aspx#feedback</comments>
            <wfw:commentRss>http://www.codingmonk.com/CodingMonk/comments/commentRss/23.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Subtext &amp; JavaScript</title>
            <link>http://www.codingmonk.com/CodingMonk/archive/2008/08/17/subtext-javascript.aspx</link>
            <description>&lt;p&gt;It's been a few months, but I've finally gotten around to finishing an article promised months ago about &lt;a href="http://www.codingmonk.com/archive/2008/08/17/configuring-subtext-for-blogging-with-word-2007.aspx"&gt;configuring Subtext 1.9.5b to support images when blogging from Word 2007&lt;/a&gt;. As chance would have it, this comes just a week after &lt;a href="http://haacked.com/archive/2008/08/10/subtext-2.0-released.aspx"&gt;Subtext 2.0 is released&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Additionally, I've updated and posted a document written a few years ago but never released offering ways to &lt;a href="http://www.codingmonk.com/archive/2008/08/17/tips-for-building-a-javascript-library.aspx"&gt;organize your JavaScript&lt;/a&gt; library. This article comes along side a new zone to this site: &lt;a href="http://www.codingmonk.com/category/6.aspx"&gt;JavaScript&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk/aggbug/22.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jim Fisher</dc:creator>
            <guid>http://www.codingmonk.com/CodingMonk/archive/2008/08/17/subtext-javascript.aspx</guid>
            <pubDate>Mon, 18 Aug 2008 04:52:34 GMT</pubDate>
            <comments>http://www.codingmonk.com/CodingMonk/archive/2008/08/17/subtext-javascript.aspx#feedback</comments>
            <wfw:commentRss>http://www.codingmonk.com/CodingMonk/comments/commentRss/22.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Tips for Building a JavaScript Library</title>
            <category>JavaScript</category>
            <link>http://www.codingmonk.com/CodingMonk/archive/2008/08/17/tips-for-building-a-javascript-library.aspx</link>
            <description>&lt;p&gt;You're an experienced developer. You learned a long time ago how to make your code generic and factor it for optimum reusability, neatly organizing it into tight, independent packages. Need a multithreaded web scrapper? You have a C# assembly that does that, thank you. Logging to the event viewer from T-SQL? No problem, there's that script you developed a few years ago. Want transformed text embedded in a graphic? Got it covered. The toolkit you've built over the years equips you to easily handle almost any task. 
&lt;/p&gt;&lt;p&gt;Almost. 
&lt;/p&gt;&lt;p&gt;Well… There is that bit of untidiness with your JavaScript. But everyone has that, right? I mean, with the hundreds of snippets smattered across the internet how could anyone keep those straight? Sure, you've made the obligatory attempt. You put the most often used routines into a single common include file. But the file grows with almost every new project, and each project leveraging this file uses only a fraction of its contents. The practice of monolithic includes is… unsatisfying. 
&lt;/p&gt;&lt;p&gt;Fear not. There is a better way. 
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial; font-size:10pt"&gt;&lt;strong&gt;About this Article&lt;/strong&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;This article describes some of the impediments that make fashioning and maintaining a library in JavaScript troublesome and discusses some techniques for surmounting these obstacles. These techniques have been adopted by CodingMonk and are manifest as the JACL (JavaScript Application Code Library) framework. As such, most of the examples are given in that context, yet the techniques described here lend themselves equally well to a personal implementation. 
&lt;/p&gt;&lt;p&gt;The code depicted here has been tested under both the Firefox and Internet Explorer browsers, including Microsoft's implementation of HTAs (HTML applications). I suspect that these techniques could also be ported to additional browsers (e.g. Opera, Safari) with minimal effort. 
&lt;/p&gt;&lt;p&gt;Before going further, I'd like to make it clear that my way is not the only way. There are a number of gifted JavaScript developers around the world and I expect there exist several additional techniques not covered here. Please keep in mind that what works well for me may not fit well in the preferences of another developer. 
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial; font-size:10pt"&gt;&lt;strong&gt;What Makes a Code Library? &lt;/strong&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;A fundamental preconception that people have when they hear the word "library" is that it is a collection of smaller parts. Although I can lump all of my scripts into a single reusable file and call it "Jim's library", that doesn't really hold true to the spirit of the word. Likewise, just as we wouldn't checkout every book from the shelves of a real library when researching English history, we shouldn't have to download the complete code when we're only using one or two of its features. 
&lt;/p&gt;&lt;p&gt;So, &lt;span style="font-family:Arial; font-size:10pt"&gt;&lt;em&gt;our library should be organized into functional modules from which we can pick and choose what we need&lt;/em&gt;&lt;/span&gt;. 
&lt;/p&gt;&lt;p&gt;This deceptively simple diktat is absent from the majority of JavaScript "libraries" available on the internet. Why? Because modules inject unexpected complexity into a library, especially highly functional ones leveraging other modules as dependencies. We'll identify some for these complexities and address them now. When we're finished, we'll have a basis upon which to build a working, expandable framework for our JavaScript library. 
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial; font-size:10pt"&gt;&lt;strong&gt;Modules Including Modules &lt;/strong&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;As a code library matures, it's almost a given that one module will eventually need to include another. In JACL, for example, the Log module is automatically included by the Core module, so logging functionality is always available. Another example: each of JACL's self-updating controls leverages an AJAX implementation housed in the ServerRequest module. 
&lt;/p&gt;&lt;p&gt;So how do we include a JavaScript file from within another JavaScript file? Obviously the most common way to include JavaScript from HTML is with the script tag: 
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;   
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;script src="http://www.codingmonk.com/jacl/jacl.js"&amp;gt;&amp;lt;/script&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;So from within a JavaScript file, one possibility is to leverage &lt;span style="font-family:Courier New"&gt;document.write()&lt;/span&gt; to inject customized script tags whenever a library module needs to meet a dependency. A la: 
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;   
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;document.write( "&amp;lt;script src='http://www.codingmonk.com/jacl/jacl.js'&amp;gt; &amp;lt;/script&amp;gt;");     &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;One complication associated with dynamic inclusion of JavaScript: it is not immediately obvious when the included file has successfully loaded. Despite their similarities, it's easy to forget that the above two lines are not exactly equivalent. To be precise: 
&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;ul&gt;&lt;li&gt;The first, declared within the HTML document, includes the JavaScript file while the page is first loading, but before scripts are run. 
&lt;/li&gt;&lt;li&gt;The second, processed after the page has finished loading and declared scripts are running, identifies subsequent scripts that the browser should load when it gets the opportunity. 
&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;So as rule: JavaScript included from JavaScript is not immediately available, but JavaScript included from a tag in the unmodified HTML document is. 
&lt;/p&gt;&lt;p&gt;To demonstrate, we can do this: 
&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;html&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;script src="http://www.codingmonk.com/jacl/jacl.js"&amp;gt;&amp;lt;/script&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;script language = "JavaScript"&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;jacl.appMain = function(){alert("Something wicked this way comes...");}; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;/script&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;/html&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;But we can't we do this: 
&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;html&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;script language="JavaScript"&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 72pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;document.write( "&amp;lt;script src='http://www.codingmonk.com/jacl/jacl.js'&amp;gt;&amp;lt;/script&amp;gt;"); &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 72pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;jacl.appMain = function(){alert("Something wicked generates an error...");}; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;/script&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;/html&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;Because the second example produces an error message in the spirit of "jacl is undefined". 
&lt;/p&gt;&lt;p&gt;A more sophisticated alternative is to leverage the browser DOM, like so: 
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;   
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;html&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;script language="JavaScript"&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;var o=document.createElement("script"); &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;    o.src="http://www.codingmonk.com/jacl/jacl.js"; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;    o.onreadystatechange = function(){ &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 108pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;if(this.readyState == "loaded"){ &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 144pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;jacl.appMain = function(){alert("Something wicked this way comes...");}; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 108pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;} &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;}; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;document.body.appendChild(o);     &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;/script&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;/html&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;Use of the DOM to dynamically load JavaScript provides a solution to our problem in the form of the &lt;span style="font-family:Courier New"&gt;onreadystatechange&lt;/span&gt; event. This event fires only when the script has loaded completely, at which point we can reference functions and objects provided by the included file with impunity. 
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial; font-size:10pt"&gt;&lt;strong&gt;Initial Module Inclusion &lt;/strong&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;Despite the DOM example in the last section, the practice of including JavaScript from JavaScript gains us nothing when used where traditional HTML script tags are possible. If used appropriately, it enables us to manage our library entries and their dependencies intelligently, but it is still necessary to include the first module by hand. 
&lt;/p&gt;&lt;p&gt;This brings us full-circle to the first code snippet listed in this article: 
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;   
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;script src="http://www.codingmonk.com/jacl/jacl.js"&amp;gt;&amp;lt;/script&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial; font-size:10pt"&gt;As it turns out, there is considerable usefulness in including an initial module as we would include a traditional script file. It provides for us select core routines without having to wait for a load event, including implementation of principals discussed above which load modules programmatically. Additionally, it gives us a place to perform library initialization. This can include, among other things, an application-defined entry point where we can be certain all library modules are loaded and ready. &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial; font-size:10pt"&gt;To demonstrate, below is a working example of an HTML page leveraging JACL's Plot module to draw a sine wave. For those that are curious, it can cut-and-pasted into an html file and viewed it in any browser. &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;   
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;html&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;body&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;script src="http://www.codingmonk.com/jacl/jacl.js"&amp;gt;&amp;lt;/script&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;script language="JavaScript"&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;    jacl.use("jaclPlot"); &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;    jacl.appMain=function(){ &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;        jacl.plot.setOrigin(50,100); &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;        jacl.log.info('Graphing sine wave...'); &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;        for(var t=0;t&amp;lt; 300;t++) &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;            jacl.plot.point(t,Math.sin(t/30)*30); &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;        }; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;/script&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;/body&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;&amp;lt;/html&amp;gt; &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;Notice that our initial inclusion of the now familiar JACL Core module is done explicitly as an HTML tag. This ensures that the library's objects (in this case the &lt;span style="font-family:Courier New"&gt;jacl&lt;/span&gt; object) are present, as are library defined code. In the JACL framework, this includes the &lt;span style="font-family:Courier New"&gt;use&lt;/span&gt; method, which is simply a refined implementation of the DOM principals discussed in the previous section, and the&lt;span style="font-family:Courier New"&gt; appMain&lt;/span&gt; method which is similar in principal to the &lt;span style="font-family:Courier New"&gt;onreadystatechange&lt;/span&gt; event but fires only once when &lt;span style="font-family:Arial; font-size:10pt"&gt;&lt;strong&gt;&lt;em&gt;all&lt;/em&gt;&lt;/strong&gt;&lt;/span&gt; modules have finally been loaded. 
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial; font-size:10pt"&gt;&lt;strong&gt;Avoiding Multiple Inclusions &lt;/strong&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;Another complexity inherent in the practice of &lt;span style="font-family:Arial; font-size:10pt"&gt;&lt;em&gt;modules-including-modules&lt;/em&gt;&lt;/span&gt; occurs when two modules share the same dependency. If not handled, the same module can be included twice. The worst case scenario results in self-referencing recursion and a page that never finishes loading. 
&lt;/p&gt;&lt;p&gt;The simplest solution is to set a flag when a module is included for the first time, doing nothing on subsequent inclusions. By leveraging our object hierarchy, this is almost laughably easy as the individual objects created by a module act as flags simply by virtue of their existence: 
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;   
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;if(jacl.plot==null) { //already created? &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;    jacl.plot=new jacl_plot(); //no? then let's create an instance &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;    // implementation goes here &lt;/span&gt;
	&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;} &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;The only drawback to this is that, while easy, the approach must be enforced across all library modules. A better alternative, one that can be implemented in the library object itself is to track which modules have been already been requested and don't add them via the DOM more than once. 
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial; font-size:10pt"&gt;&lt;strong&gt;Establishing a Library's Location &lt;/strong&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;Astute observers will notice one important nuance in the sine wave example: 
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;   
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;jacl.use("jaclPlot"); &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;The &lt;span style="font-family:Courier New"&gt;use&lt;/span&gt; method does not require a fully qualified file path. At first glance this seems a trivial feature. After all, if we need to specify the URL when we include one module, it is only a small inconvenience to provide the URL with subsequent inclusions. The real problem arises, again, when modules include other modules. In the example where we included modules with the DOM, the path was hard-coded, as in: 
&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;o.src="http://www.codingmonk.com/jacl/jaclPlot.js"; &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;This isn't going to do us any good if we try to access our library locally, or if we move it to a different domain. What we need is for the module to determine the library's location relative to the client. As it turns out, this isn't too difficult. Since we're including an initial core module with a fully qualified filename all we have to do search the document's script objects and parse the path from the correct one: 
&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;var path=""; &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;for(t=0;t&amp;lt;document.scripts.length;t++){ &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;        var val=document.scripts[t].outerHTML.toLowerCase(); &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;        if(val.indexOf("jacl.js")==-1) continue; &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;        var s=val.indexOf("src=\""); &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;        if(s!=-1){ &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;            s+=5; &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;            path=val.substring(s,val.indexOf("jacl",s)); &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;            break; &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;        } &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;    } &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;So the &lt;span style="font-family:Courier New"&gt;use&lt;/span&gt; method knows to expand: 
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;jaclplot &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;into 
&lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;http://www.codingmonk.com/jacl/jaclplot.js&lt;/span&gt;&lt;span style="font-family:Arial; font-size:10pt"&gt;
		&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;by using the resulting path variable. Of course, storing the path as a global variable clutters the namespace. This is just one of several advantages of leveraging an object hierarchy for our JavaScript library… 
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial; font-size:10pt"&gt;&lt;strong&gt;Organizing a Hierarchy &lt;/strong&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;The best, most useful of libraries can suffer and die because it is not kept organized. As libraries grow, they become more difficult to keep arranged. No matter how many modules your library is broken down into, if the net result is just a chaotic bundle of routines, then the library hasn't helped as much as it could. 
&lt;/p&gt;&lt;p&gt;Namespace hierarchies help us to stay organized. More than just factoring code into modules, this technique structures our code in precise and predictable ways. Notice from our examples how every use of the JACL library stems either directly or indirectly from the global &lt;span style="font-family:Courier New"&gt;jacl&lt;/span&gt; object. JACL's implementation of the previous path-finding example populates a member variable rather than a global one: 
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;    jacl.path &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;By doing this, we need not worry ourselves with the possibility of naming collisions, where another module or otherwise appropriated script defines a variable named "path" too. 
&lt;/p&gt;&lt;p&gt;Continuing the review of the fully working sine-wave example given previously, notice that JACL's logging module adds an object which encapsulates various pieces of logging functionality: 
&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p style="text-align: justify; margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;jacl.log.trivial("Here is a message"); &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;Other JACL modules go to greater lengths to categorize their code: 
&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p style="margin-left: 36pt"&gt;&lt;span style="font-family:Courier New; font-size:8pt"&gt;jacl.input.textbox.applyEditMask(tbInput, "###-##-####"); &lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;How diverse you choose to make your hierarchy is, of course, a personal preference. 
&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Arial; font-size:10pt"&gt;&lt;strong&gt;Review a real implementation &lt;/strong&gt;&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;As was pointed out numerous times, the techniques proposed in this article are more than theoretical. For a complete working example, one moderately more fleshed out, I highly recommend taking a look at the most recent implementation of Coding Monk's JACL framework: 
&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p style="text-align: center"&gt;&lt;a href="http://www.codingmonk.com/downloads/jacl.zip"&gt;&lt;span style="font-family:Arial; font-size:10pt"&gt;www.codingmonk.com/downloads/jacl.zip&lt;/span&gt;&lt;/a&gt;&lt;span style="font-family:Arial; font-size:10pt"&gt;
		&lt;/span&gt;
	&lt;/p&gt;&lt;p&gt;   
 &lt;/p&gt;&lt;p&gt;Happy coding! 
&lt;/p&gt;&lt;p&gt;   &lt;/p&gt;&lt;img src="http://www.codingmonk.com/CodingMonk/aggbug/21.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jim Fisher</dc:creator>
            <guid>http://www.codingmonk.com/CodingMonk/archive/2008/08/17/tips-for-building-a-javascript-library.aspx</guid>
            <pubDate>Mon, 18 Aug 2008 03:19:40 GMT</pubDate>
            <comments>http://www.codingmonk.com/CodingMonk/archive/2008/08/17/tips-for-building-a-javascript-library.aspx#feedback</comments>
            <wfw:commentRss>http://www.codingmonk.com/CodingMonk/comments/commentRss/21.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>
