<?xml version="1.0"?>
<News hasArchived="true" page="7845" pageCount="10794" pageSize="10" timestamp="Mon, 07 Sep 2026 12:03:51 -0400" url="https://my3.my.umbc.edu/posts.xml?mode=activity&amp;page=7845&amp;range=2">
<NewsItem contentIssues="true" id="41268" important="false" status="posted" url="https://my3.my.umbc.edu/posts/41268">
<Title>How To Build A CLI Tool With Node.js And PhantomJS</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <table width="650">
    <tbody>
    <tr>
    <td>
    <div>
    <img src="http://statisches.auslieferung.commindo-media-ressourcen.de/advertisement.gif" alt="" style="max-width: 100%; height: auto;"><br><a href="http://auslieferung.commindo-media-ressourcen.de/random.php?mode=target&amp;collection=smashing-rss&amp;position=1" rel="nofollow external" class="bo"><img src="http://auslieferung.commindo-media-ressourcen.de/random.php?mode=image&amp;collection=smashing-rss&amp;position=1" alt="" style="max-width: 100%; height: auto;"></a> <a href="http://auslieferung.commindo-media-ressourcen.de/random.php?mode=target&amp;collection=smashing-rss&amp;position=2" rel="nofollow external" class="bo"><img src="http://auslieferung.commindo-media-ressourcen.de/random.php?mode=image&amp;collection=smashing-rss&amp;position=2" alt="" style="max-width: 100%; height: auto;"></a> <a href="http://auslieferung.commindo-media-ressourcen.de/random.php?mode=target&amp;collection=smashing-rss&amp;position=3" rel="nofollow external" class="bo"><img src="http://auslieferung.commindo-media-ressourcen.de/random.php?mode=image&amp;collection=smashing-rss&amp;position=3" alt="" style="max-width: 100%; height: auto;"></a>
    </div>
    </td>
    </tr>
    </tbody>
    </table>
    <p>In this article, we’ll go over the concepts and techniques required to build a command line tool using <a href="http://nodejs.org/" rel="nofollow external" class="bo">Node.js</a> and <a href="http://phantomjs.org/" rel="nofollow external" class="bo">PhantomJS</a>. Building a command line tool enables you to automate a process that would otherwise take a lot longer.</p>
    <p>Command line tools are built in a myriad of languages, but the one we’ll focus on is Node.js.</p>
    <h4>What We’ll Cover</h4>
    <ul>
    <li>Secret sauce</li>
    <li>Installing Node.js and npm</li>
    <li>Process</li>
    <li>Automation</li>
    <li>PhantomJS</li>
    <li>Squirrel</li>
    <li>How it works</li>
    <li>The code</li>
    <li>Packaging</li>
    <li>Publishing</li>
    <li>Conclusion</li>
    </ul>
    <h3>Secret Sauce</h3>
    <p>For those short on time, I’ve condensed the core process into three steps. This is the secret sauce to convert your Node.js script into a fully functioning command line tool. But do stick around to see what else I have to show you.</p>
    <ol>
    <li>In your <code>package.json</code> file, include the following settings:</li>
    </ol>
    <ul>
    <li><code>"preferGlobal": "true"</code></li>
    <li><code>"bin": { "name-of-command": "path-to-script.js" }</code></li>
    </ul>
    <li>Add <code>#!/usr/bin/env node</code> to <code>path-to-script.js</code>.</li>
    <li>To test your new command (<code>name-of-command</code>), use <code>npm link</code>.</li>
    
    <p>The rest of the process is just deciding what functionality to implement.</p>
    <h3>Installing Node.js And npm</h3>
    <p>To install Node.js, you have a few options:</p>
    <ul>
    <li>
    <a href="http://nodejs.org/download/" rel="nofollow external" class="bo">OS-specific installer</a> for Windows, Mac or binary;</li>
    <li>
    <a href="http://brew.sh/" rel="nofollow external" class="bo">Homebrew</a>: <code>brew install node</code>;</li>
    <li>
    <a href="https://github.com/isaacs/nave#nave" rel="nofollow external" class="bo">Nave</a>;</li>
    <li>
    <a href="https://github.com/creationix/nvm#node-version-manager" rel="nofollow external" class="bo">NVM</a>.</li>
    </ul>
    <p>Note that npm is installed as part of Node.js; there is no separate installation.</p>
    <p>To test that Node.js and npm are installed correctly, run the following commands in your terminal:</p>
    <ul>
    <li><code>node --version</code></li>
    <li><code>npm --version</code></li>
    </ul>
    <h3>Process</h3>
    <p>Let’s consider a sample process: generating an <a href="http://www.html5rocks.com/en/tutorials/appcache/beginner/" rel="nofollow external" class="bo">Application Cache</a> manifest file.</p>
    <p>In case you are unfamiliar with AppCache, it <strong>enables you to take your application offline</strong> by specifying pages and resources to cache in the event that the user loses their Internet connection or tries to access your application later offline.</p>
    <p>Typically, you would create an <a href="http://appcachefacts.info/" rel="nofollow external" class="bo">appcache.manifest</a> file, where you would configure the offline settings.</p>
    <p>We won’t go into much detail about AppCache itself because that would distract us from the purpose of this article. Nevertheless, below are the lines for a sample file:</p>
    <pre><code>&#x000A;    CACHE MANIFEST&#x000A;    &#x000A;    CACHE:&#x000A;    foo.jpg&#x000A;    index.html&#x000A;    offline.html&#x000A;    styles.css&#x000A;    behaviours.js&#x000A;    &#x000A;    NETWORK:&#x000A;    *&#x000A;    &#x000A;    FALLBACK:&#x000A;    / /offline.html&#x000A;    </code></pre>
    <p>As you can see, we’ve specified the following:</p>
    <ul>
    <li>a JPG image,</li>
    <li>two HTML files,</li>
    <li>a CSS file,</li>
    <li>a JavaScript file.</li>
    </ul>
    <p>These are the resources that we want to cache in case the user goes offline.</p>
    <p>We’ve also specified that all other items requested by the user should require a network to be accessed.</p>
    <p>Finally, we’ve stated that any file that should be cached but isn’t yet should redirect the user to a file named <code>offline.html</code>.</p>
    <h3>Automation</h3>
    <p>Having to manually look up all of the images, style sheets, scripts and other pages linked from a Web page would be tedious. Thus, we’re trying to automate the process of generating an AppCache manifest file.</p>
    <p>We could do this by writing some Node.js code along with some additional tools, but that wouldn’t be very easy (even for the person writing the script), because we would need to open the code and tell it which Web page to interrogate.</p>
    <p>We also want other people to have the benefit of this tool, without their needing to download a folder full of code, change certain lines of code and run commands to run the scripts.</p>
    <p>This is why a command line tool would help.</p>
    <h3>PhantomJS</h3>
    <p>First, we want to figure out how to solve this problem.</p>
    <p>We’ll use a tool named <a href="http://phantomjs.org/" rel="nofollow external" class="bo">PhantomJS</a>, which is a headless (i.e. chromeless) browser.</p>
    <p>Specifically, it’s a headless <a href="http://www.webkit.org/" rel="nofollow external" class="bo">WebKit</a> browser, which provides a JavaScript API that we can tap into and that lets us do things such as open Web pages and analyze their network requests. (It does many other things, but those are the two fundamental aspects we’re interested in.)</p>
    <p>We can use a Node.js module to load PhantomJS and interact with its API. We can then convert our code into a command line tool with relative ease using Node.js’s package manager, <a href="https://npmjs.org/" rel="nofollow external" class="bo">npm</a>, and a <code>package.json</code> file.</p>
    <h3>Squirrel</h3>
    <p>Luckily, I’ve already done the work for you. It’s an open-source project named <a href="https://github.com/Integralist/Squirrel#squirrel" rel="nofollow external" class="bo">Squirrel</a>.</p>
    <p>To install it, run the command <code>npm install -g squirrel-js</code>.</p>
    <p>Once it’s installed, you can use it by running the command <code>squirrel [url]</code>. For example, <code>squirrel bbc.co.uk/news</code>.</p>
    <p>This would generate (in the current directory) an <code>appcache.manifest</code> file populated with all relevant page resources.</p>
    <h3>How It Works</h3>
    <p>I started Squirrel by first writing the relevant Node.js and PhantomJS code to incorporate the functionality I was after.</p>
    <p>Then, I added a script that bootstraps that code and allows me to take arguments that configure how the code runs.</p>
    <p>I ended up with two scripts:</p>
    <ul>
    <li><a href="https://github.com/Integralist/Squirrel/blob/master/lib/squirrel.js" rel="nofollow external" class="bo">squirrel.js</a></li>
    <li><a href="https://github.com/Integralist/Squirrel/blob/master/lib/appcache.js" rel="nofollow external" class="bo">appcache.js</a></li>
    </ul>
    <p>The first script sets up the work:</p>
    <ul>
    <li>We specify the environment in which we want the script to execute (in this case, Node.js).</li>
    <li>Parse the arguments passed by the user.</li>
    <li>Read an internal (i.e. dummy) <code>appcache.manifest</code> file.</li>
    <li>Open a shell child process, call PhantomJS and pass it the script that we want it to execute (in this case, <code>appcache.js</code>) and the dummy manifest file.</li>
    <li>When the second script finishes its work (collating the Web page data), return to this first script and display some statistical information to the user and generate the manifest file.</li>
    </ul>
    <p>The second script processes the Web page that the user has requested:</p>
    <ul>
    <li>We take in the dummy manifest file.</li>
    <li>Create listeners for the page resources that are requested.</li>
    <li>Set the viewport size.</li>
    <li>Open the Web page and store the resources.</li>
    <li>Get all links from the page (by executing JavaScript code directly in the Web page).</li>
    <li>Convert the contents of the manifest file and inject the resources found, and then return that as a JSON file.</li>
    </ul>
    <h3>The Code</h3>
    <p>Now that you understand what the code does, let’s review it. I’ll show the code in its entirely, and then we’ll go through it piecemeal.</p>
    <h4>squirrel.js</h4>
    <pre><code>&#x000A;    #!/usr/bin/env node&#x000A;    &#x000A;    var userArguments = process.argv.slice(2); // Copies arguments list but removes first two options (script exec type &amp; exec location)&#x000A;    &#x000A;    if (userArguments.length &gt; 1) {&#x000A;        throw new Error('Only one argument may be specified (the URL for which you want to generate the AppCache.)');&#x000A;    }&#x000A;    &#x000A;    var fs               = require('fs');&#x000A;    var shell            = require('child_process').execFile;&#x000A;    var phantomjs        = require('phantomjs').path;&#x000A;    var scriptToExecute  = __dirname + '/appcache.js';&#x000A;    var manifest         = __dirname + '/../appcache.manifest';&#x000A;    var url              = userArguments[0];&#x000A;    var manifestContent;&#x000A;    var data;&#x000A;    &#x000A;    fs.readFile(manifest, bootstrap);&#x000A;    &#x000A;    function bootstrap(err, contentAsBuffer) {&#x000A;        if (err) throw err;&#x000A;    &#x000A;        manifestContent = contentAsBuffer.toString('utf8');&#x000A;    &#x000A;        shell(phantomjs, [scriptToExecute, url, manifestContent], function(err, stdout, stderr) {&#x000A;            if (err) throw err;&#x000A;    &#x000A;            // Sometimes an error in the loaded page's JavaScript doesn't get picked up or thrown,&#x000A;            // but the error comes in via stdout and causes JSON parsing to break&#x000A;            try {&#x000A;                data = JSON.parse(stdout);&#x000A;            } catch(err) {&#x000A;                log('Whoops! It seems there was an error? You\'ll find the stack trace below.');&#x000A;                error(err);&#x000A;            }&#x000A;    &#x000A;            displayStatistics();&#x000A;            createManifestFile();&#x000A;        });&#x000A;    }&#x000A;    &#x000A;    function displayStatistics() {&#x000A;        log(''); // Adds extra line of spacing when displaying the results&#x000A;        log('Links: '      + data.links);&#x000A;        log('Images: '     + data.images);&#x000A;        log('CSS: '        + data.css);&#x000A;        log('JavaScript: ' + data.javascript);&#x000A;    }&#x000A;    &#x000A;    function createManifestFile() {&#x000A;        fs.writeFile(process.cwd() + '/appcache.manifest', data.manifestContent, function(err) {&#x000A;            if (err) throw err;&#x000A;    &#x000A;            log('\nManifest file created');&#x000A;        });&#x000A;    }&#x000A;    &#x000A;    function log(message) {&#x000A;        process.stdout.write(message + '\n');&#x000A;    }&#x000A;    &#x000A;    function error(err) {&#x000A;        process.stderr.write(err);&#x000A;    }&#x000A;    </code></pre>
    <p>The first line, <code>#!/usr/bin/env node</code>, is critical to the script being used in the shell. We have to tell the shell what process should handle the script.</p>
    <p>Next, we have to retrieve the arguments passed to the command. If we run <code>squirrel bbc.co.uk/news</code>, then <code>process.argv</code> would be an array containing the following:</p>
    <ul>
    <li>the script execution type (<code>node</code>);</li>
    <li>the script being executed (<code>squirrel.js</code>);</li>
    <li>any other arguments (in this instance, only one, <code>bbc.co.uk/news</code>).</li>
    </ul>
    <p>Ignore the first two arguments, and store the user-specific arguments so that we can reference them later:</p>
    <pre><code>&#x000A;    var userArguments = process.argv.slice(2);&#x000A;    </code></pre>
    <p>Our script only knows how to handle a single argument (which is the page URL to load). The following line isn’t really needed because we’ll ignore any more than one argument, but it’s useful for the code to have clear intent, so we’ll throw an error if more than one argument is passed.</p>
    <pre><code>&#x000A;    if (userArguments.length &gt; 1) {&#x000A;        throw new Error('Only one argument may be specified (the URL for which you want to generate the AppCache.)');&#x000A;    }&#x000A;    </code></pre>
    <p>Because we’re using PhantomJS, we’ll need to open up a shell and call the <code>phantomjs</code> command:</p>
    <pre><code>&#x000A;    var shell = require('child_process').execFile;&#x000A;    </code></pre>
    <p>We’ll also need to reference the <code>bin</code> directory, where the PhantomJS executable is stored:</p>
    <pre><code>&#x000A;    var phantomjs = require('phantomjs').path;&#x000A;    </code></pre>
    <p>Next, store a reference to the script that we want PhantomJS to execute, as well as the dummy manifest file.</p>
    <pre><code>&#x000A;    var scriptToExecute = __dirname + '/appcache.js';&#x000A;    var manifest        = __dirname + '/../appcache.manifest';&#x000A;    var url             = userArguments[0];&#x000A;    </code></pre>
    <p>Because the PhantomJS script that we’ll be executing needs a reference to the dummy manifest file, we’ll asynchronously read the contents of the file and then pass it on to a <code>bootstrap</code> function:</p>
    <pre><code>&#x000A;    fs.readFile(manifest, bootstrap);&#x000A;    </code></pre>
    <p>Our <code>bootstrap</code> function does exactly what you would expect: start our application (in this case, by opening the shell and calling PhantomJS). You’ll also notice that Node.js passes the contents of the manifest as a buffer, which we need to convert back into a string:</p>
    <pre><code>&#x000A;    function bootstrap(err, contentAsBuffer) {&#x000A;        if (err) throw err;&#x000A;    &#x000A;        manifestContent = contentAsBuffer.toString('utf8');&#x000A;    &#x000A;        shell(phantomjs, [scriptToExecute, url, manifestContent], function(err, stdout, stderr) {&#x000A;            // code...&#x000A;        });&#x000A;    }&#x000A;    </code></pre>
    <p>At this point in the execution of the code, we are in the <code>appcache.js</code> file. Let’s move over there now.</p>
    <h4>appcache.js</h4>
    <p>The purpose of <code>appcache.js</code> is to get information from the user-requested page and pass it back to <code>squirrel.js</code> for processing.</p>
    <p>Again, I’ll show the script in its entirety, and then we’ll break it down. (Don’t worry, we won’t go over each line — only the important parts.)</p>
    <pre><code>&#x000A;    var unique     = require('lodash.uniq');&#x000A;    var system     = require('system');&#x000A;    var fs         = require('fs');&#x000A;    var page       = require('webpage').create();&#x000A;    var args       = system.args;&#x000A;    var manifest   = args[2];&#x000A;    var css        = [];&#x000A;    var images     = [];&#x000A;    var javascript = [];&#x000A;    var links;&#x000A;    var url;&#x000A;    var path;&#x000A;    &#x000A;    bootstrap();&#x000A;    pageSetUp();&#x000A;    openPage();&#x000A;    &#x000A;    function bootstrap() {&#x000A;        if (urlProvided()) {&#x000A;            url = cleanUrl(args[1]);&#x000A;        } else {&#x000A;            var error = new Error('Sorry, a valid URL could not be recognized');&#x000A;                error.additional = 'Valid URL example: bbc.co.uk/news';&#x000A;    &#x000A;            throw error;&#x000A;    &#x000A;            phantom.exit();&#x000A;        }&#x000A;    &#x000A;        if (bbcNews()) {&#x000A;            // We want to serve the responsive code base.&#x000A;            phantom.addCookie({&#x000A;                'name'  : 'ckps_d',&#x000A;                'value' : 'm',&#x000A;                'domain': '.bbc.co.uk'&#x000A;            });&#x000A;        }&#x000A;    }&#x000A;    &#x000A;    function pageSetUp() {&#x000A;        page.onResourceRequested = function(request) {&#x000A;            if (/\.(?:png|jpeg|jpg|gif)$/i.test(request.url)) {&#x000A;                images.push(request.url);&#x000A;            }&#x000A;    &#x000A;            if (/\.(?:js)$/i.test(request.url)) {&#x000A;                javascript.push(request.url);&#x000A;            }&#x000A;    &#x000A;            if (/\.(?:css)$/i.test(request.url)) {&#x000A;                css.push(request.url);&#x000A;            }&#x000A;        };&#x000A;    &#x000A;        page.onError = function(msg, trace) {&#x000A;            console.log('Error :', msg);&#x000A;    &#x000A;            trace.forEach(function(item) {&#x000A;                console.log('Trace:  ', item.file, ':', item.line);&#x000A;            });&#x000A;        }&#x000A;    &#x000A;        page.viewportSize = { width: 1920, height: 800 };&#x000A;    }&#x000A;    &#x000A;    function openPage() {&#x000A;        page.open(url, function(status) {&#x000A;            links      = unique(getLinks());&#x000A;            images     = unique(images);&#x000A;            css        = unique(css);&#x000A;            javascript = unique(javascript);&#x000A;    &#x000A;            populateManifest();&#x000A;    &#x000A;            // Anything written to stdout is actually passed back to our Node script callback&#x000A;            console.log(JSON.stringify({&#x000A;                links           : links.length,&#x000A;                images          : images.length,&#x000A;                css             : css.length,&#x000A;                javascript      : javascript.length,&#x000A;                manifestContent : manifest&#x000A;            }));&#x000A;    &#x000A;            phantom.exit();&#x000A;        });&#x000A;    }&#x000A;    &#x000A;    function urlProvided() {&#x000A;        return args.length &gt; 1 &amp;&amp; /(?:www\.)?[a-z-z1-9]+\./i.test(args[1]);&#x000A;    }&#x000A;    &#x000A;    function cleanUrl(providedUrl) {&#x000A;        // If no http or https found at the start of the URL...&#x000A;        if (/^(?!https?:\/\/)[\w\d]/i.test(providedUrl)) {&#x000A;            return '<a href="http://">http://</a>' + providedUrl + '/';&#x000A;        }&#x000A;    }&#x000A;    &#x000A;    function bbcNews(){&#x000A;        if (/bbc.co.uk\/news/i.test(url)) {&#x000A;            return true;&#x000A;        }&#x000A;    }&#x000A;    &#x000A;    function getLinks() {&#x000A;        var results = page.evaluate(function() {&#x000A;            return Array.prototype.slice.call(document.getElementsByTagName('a')).map(function(item) {&#x000A;                return item.href;&#x000A;            });&#x000A;        });&#x000A;    &#x000A;        return results;&#x000A;    }&#x000A;    &#x000A;    function writeVersion() {&#x000A;        manifest = manifest.replace(/# Timestamp: \d+/i, '# Timestamp: ' + (new Date()).getTime());&#x000A;    }&#x000A;    &#x000A;    function writeListContentFor(str, type) {&#x000A;        manifest = manifest.replace(new RegExp('(# ' + str + ')\\n[\\s\\S]+?\\n\\n', 'igm'), function(match, cg) {&#x000A;            return cg + '\n' + type.join('\n') + '\n\n';&#x000A;        });&#x000A;    }&#x000A;    &#x000A;    function populateManifest() {&#x000A;        writeVersion();&#x000A;    &#x000A;        writeListContentFor('Images', images);&#x000A;        writeListContentFor('Internal HTML documents', links);&#x000A;        writeListContentFor('Style Sheets', css);&#x000A;        writeListContentFor('JavaScript', javascript);&#x000A;    }&#x000A;    </code></pre>
    <p>We begin by using PhantomJS’ API to create a new Web page:</p>
    <pre><code>&#x000A;    var page = require('webpage').create();&#x000A;    </code></pre>
    <p>Next, we’ll check that a URL was provided and, if so, clean it into the format required (for example, by giving it an <code>http</code> protocol). Otherwise, we’ll throw an error and stop PhantomJS:</p>
    <pre><code>&#x000A;    if (urlProvided()) {&#x000A;        url = cleanUrl(args[1]);&#x000A;    } else {&#x000A;        var error = new Error('Sorry, a valid URL could not be recognized');&#x000A;        error.additional = 'Valid URL example: bbc.co.uk/news';&#x000A;    &#x000A;        throw error;&#x000A;        phantom.exit();&#x000A;    }&#x000A;    </code></pre>
    <p>We also put in a check to see whether the URL passed was for <code>bbc.co.uk/news</code> and, if so, use PhantomJS to set a cookie that enables the responsive version of the website to load (the purpose being merely to demonstrate some of PhantomJS’ useful APIs, such as <code>addCookie</code>):</p>
    <pre><code>&#x000A;    if (bbcNews()) {&#x000A;        phantom.addCookie({&#x000A;            'name'  : 'ckps_d',&#x000A;            'value' : 'm',&#x000A;            'domain': '.bbc.co.uk'&#x000A;        });&#x000A;    }&#x000A;    </code></pre>
    <p>For PhantomJS to be able to analyze the network data (so that we can track the style sheets, JavaScript and images being requested by the page), we need to use special PhantomJS handlers to interpret the requests:</p>
    <pre><code>&#x000A;    page.onResourceRequested = function(request) {&#x000A;        if (/\.(?:png|jpeg|jpg|gif)$/i.test(request.url)) {&#x000A;            images.push(request.url);&#x000A;        }&#x000A;    &#x000A;        if (/\.(?:js)$/i.test(request.url)) {&#x000A;            javascript.push(request.url);&#x000A;        }&#x000A;    &#x000A;        if (/\.(?:css)$/i.test(request.url)) {&#x000A;            css.push(request.url);&#x000A;        }&#x000A;    };&#x000A;    </code></pre>
    <p>We’ll also use another PhantomJS API feature that enables us to determine the size of the browser window:</p>
    <pre><code>&#x000A;    page.viewportSize = { width: 1920, height: 800 };&#x000A;    </code></pre>
    <p>We then tell PhantomJS to open the specified Web page. Once the page is open (i.e. the <code>load</code> event has fired), a callback is executed:</p>
    <pre><code>&#x000A;    page.open(url, function(status) {&#x000A;        // code...&#x000A;    });&#x000A;    </code></pre>
    <p>In the callback, we store the resources that were found, and we call a function that replaces the contents of our string (the dummy manifest) with a list of each set of resources:</p>
    <pre><code>&#x000A;    page.open(url, function(status) {&#x000A;        links      = unique(getLinks());&#x000A;        images     = unique(images);&#x000A;        css        = unique(css);&#x000A;        javascript = unique(javascript);&#x000A;    &#x000A;        populateManifest();&#x000A;    &#x000A;        // Remaining code...&#x000A;    });&#x000A;    </code></pre>
    <p>Finally, we create a data object to hold statistics about the resources being requested, convert it to a JSON string, and log it using the <code>console</code> API.</p>
    <p>Once this is done, we tell PhantomJS to <code>exit</code> (otherwise the process would stall):</p>
    <pre><code>&#x000A;    page.open(url, function(status) {&#x000A;        // Previous code...&#x000A;    &#x000A;        console.log(JSON.stringify({&#x000A;            links           : links.length,&#x000A;            images          : images.length,&#x000A;            css             : css.length,&#x000A;            javascript      : javascript.length,&#x000A;            manifestContent : manifest&#x000A;        }));&#x000A;    &#x000A;        phantom.exit();&#x000A;    });&#x000A;    </code></pre>
    <p>Reviewing the code above, you might wonder how we get the data back to our <code>squirrel.js</code> script? Take another look at the <code>console.log</code>. The code has an odd side effect, which is that any code logged by PhantomJS is passed back to our shell callback (originally executed in <code>squirrel.js</code>).</p>
    <p>Let’s revisit our <code>squirrel.js</code> script now.</p>
    <h4>Back to squirrel.js</h4>
    <pre><code>&#x000A;    shell(phantomjs, [scriptToExecute, url, manifestContent], function(err, stdout, stderr) {&#x000A;        if (err) throw err;&#x000A;    &#x000A;        try {&#x000A;            data = JSON.parse(stdout);&#x000A;        } catch(err) {&#x000A;            log('Whoops! It seems there was an error? You\'ll find the stack trace below.');&#x000A;            error(err);&#x000A;        }&#x000A;    &#x000A;        displayStatistics();&#x000A;        createManifestFile();&#x000A;    });&#x000A;    </code></pre>
    <p>The callback function is run when the PhantomJS script finishes executing. It is passed any errors that may have occurred and, if there are, then we throw the error:</p>
    <p><code>if (err) throw err;</code></p>
    <p>The other arguments are the standard output and error arguments provided by the shell. In this case, the standard output would be our JSON string, which we <code>console.log</code>’ed from <code>appcache.js</code>. We parse the JSON string and convert it back into an object so that we can present the data to the user who has run the <code>squirrel</code> command.</p>
    <p>As a side note, we wrap this conversion in a <code>try/catch</code> clause to protect against Web pages that cause a JavaScript error to occur (the error is picked up by <code>stdout</code>, not <code>stderr</code>, thus causing the JSON parsing to break):</p>
    <pre><code>&#x000A;    try {&#x000A;        data = JSON.parse(stdout);&#x000A;    } catch(err) {&#x000A;        error(err);&#x000A;    }&#x000A;    </code></pre>
    <p>Once we have our data, we call <code>displayStatistics</code>, which uses <code>stdout</code> to write a message to the user’s terminal.</p>
    <p>Lastly, we call <code>createManifestFile</code>, which creates an <code>appcache.manifest</code> file in the user’s current directory:</p>
    <pre><code>&#x000A;    fs.writeFile(process.cwd() + '/appcache.manifest', data.manifestContent, function(err) {&#x000A;        if (err) throw err;&#x000A;    &#x000A;        log('\nManifest file created');&#x000A;    });&#x000A;    </code></pre>
    <p>Now that we understand how the script works in its entirety, let’s look at how to allow others to download and install our work.</p>
    <h3>Packaging</h3>
    <p>For other users to be able to install our module, we’ll need to publish it to a public repository. The place to do this is the <a href="https://npmjs.org/" rel="nofollow external" class="bo">npm</a> registry.</p>
    <p>To publish to npm, you’ll need a <code>package.json</code> file.</p>
    <p>The purpose of <code>package.json</code> is to specify the dependencies of the project you’re working on. In this instance, it specifies the dependencies required by Squirrel to do its job.</p>
    <p>Below is Squirrel’s <code>package.json</code> file:</p>
    <pre><code>&#x000A;    {&#x000A;      "name": "squirrel-js",&#x000A;      "version": "0.1.3",&#x000A;      "description": "Node.js-based CLI tool, using PhantomJS to automatically generate an Application Cache manifest file for a specified URL",&#x000A;      "main": "lib/squirrel",&#x000A;      "scripts": {&#x000A;        "test": "echo "Error: no test specified" &amp;&amp; exit 1"&#x000A;      },&#x000A;      "engines": {&#x000A;        "node": "&gt;=0.10"&#x000A;      },&#x000A;      "repository": {&#x000A;        "type": "git",&#x000A;        "url": "<a href="git://github.com/Integralist/Squirrel.git">git://github.com/Integralist/Squirrel.git</a>"&#x000A;      },&#x000A;      "preferGlobal": "true",&#x000A;      "bin": {&#x000A;        "squirrel": "lib/squirrel.js"&#x000A;      },&#x000A;      "dependencies": {&#x000A;        "phantomjs": "~1.9.2-6",&#x000A;        "lodash.uniq": "~2.4.1"&#x000A;      },&#x000A;      "keywords": [&#x000A;        "appcache",&#x000A;        "phantomjs",&#x000A;        "cli"&#x000A;      ],&#x000A;      "author": "Mark McDonnell  (<a href="http://www.integralist.co.uk/">http://www.integralist.co.uk/</a>)",&#x000A;      "license": "MIT",&#x000A;      "bugs": {&#x000A;        "url": "<a href="https://github.com/Integralist/Squirrel/issues">https://github.com/Integralist/Squirrel/issues</a>"&#x000A;      },&#x000A;      "homepage": "<a href="https://github.com/Integralist/Squirrel">https://github.com/Integralist/Squirrel</a>"&#x000A;    }&#x000A;    </code></pre>
    <p>You can read up on all of the properties of <code>package.json</code> in the <a href="https://npmjs.org/doc/json.html" rel="nofollow external" class="bo">npm registry</a>.</p>
    <p>The properties to note are these:</p>
    <ul>
    <li><code>"preferGlobal": "true"</code></li>
    <li><code>"bin": { "squirrel": "lib/squirrel.js" }</code></li>
    </ul>
    <p>The first property indicates when a user has installed a module that you would prefer to be installed globally. In this case, we want it to be installed globally because then the user will be able to run the command anywhere in their system.</p>
    <p>The second property indicates where the command will find the code required to execute the command.</p>
    <p>To test that your command works, you’ll need to run the <code>npm link</code> command, which in this case creates a symlink from the <code>squirrel</code> command to the <code>squirrel.js</code> file.</p>
    <h3>Publishing</h3>
    <p>To publish your code, first <a href="https://npmjs.org/signup" rel="nofollow external" class="bo">register</a> for an npm account.</p>
    <p>You’ll need to verify the account via the command line. To do this, run <code>npm adduser</code>, which will ask you to specify a user name and password.</p>
    <p>Once you’ve verified the account, you can publish your module to the npm registry using <code>npm publish</code>.</p>
    <p>It could take a few minutes for the module to become publicly accessible.</p>
    <p>Be aware that if you update the code and try to run <code>npm publish</code> without updating the <code>package.json</code> file’s <code>version</code> property, then npm will return an error asking you to update the version number.</p>
    <h3>Conclusion</h3>
    <p>This is just one example of the sort of command line tools you can develop with Node.js’ many features.</p>
    <p>The next time you find yourself performing a repetitive task, consider automating the process with a CLI tool.</p>
    <p><em>(al)</em></p>
    <hr>
    <p><small>© Mark McDonnell for <a href="http://www.smashingmagazine.com" rel="nofollow external" class="bo">Smashing Magazine</a>, 2014.</small></p>
    </div>
]]>
</Body>
<Summary>        In this article, we’ll go over the concepts and techniques required to build a command line tool using Node.js and PhantomJS. Building a command line tool enables you to automate a process...</Summary>
<Website>http://www.smashingmagazine.com/2014/02/12/how-to-build-a-cli-tool-with-node-js-and-phantomjs/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/41268/guest@my.umbc.edu/3dd955463cdd7b249cc9f04822b204ad/api/pixel</TrackingUrl>
<Tag>coding</Tag>
<Tag>css</Tag>
<Tag>design</Tag>
<Tag>development</Tag>
<Tag>html</Tag>
<Tag>javascript</Tag>
<Tag>mysql</Tag>
<Tag>php</Tag>
<Tag>sql</Tag>
<Tag>web</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Wed, 12 Feb 2014 05:24:23 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="false" id="122837" important="false" status="posted" url="https://my3.my.umbc.edu/posts/122837">
<Title>UMBC: Making a Mark</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <h2>Making a Mark</h2>
    <h3>A UMBC mathematician finds the right equation for biologists</h3>
    <p><strong>Kathleen Hoffman</strong>, a professor of mathematics and statistics at UMBC, works in math biology, but she often felt that her biology colleagues didn�t really understand what she was doing.</p>
    <p>�The work I did was very foundational in mathematics and it didn�t really help them design an experiment or impact their way of thinking,� Hoffman says. So after she got tenure, Hoffman did something most mathematicians wouldn�t think of doing: she took a sabbatical, got funding from the National Science Foundation and joined a biology lab.</p>
    <p>�I called it an immersion program,� says Hoffman, �because what I wanted to do was like learning a new language, where you just go to the country and live there, and that�s what I did.�</p>
    <p>Hoffman had done her homework. She knew she wanted to work with Avis Cohen, a professor of biology at the University of Maryland, College Park who researches lampreys � a kind of a jawless fish that sucks the blood out of other fish � and how they swim. Scientists study lamprey locomotion because these fish possess neurons similar to those that power human locomotion, but thousands and thousands of orders of magnitude fewer in number � and thus much easier to study.</p>
    <p>Joining Cohen�s lab brought about a fundamental change in Hoffman�s research, introducing her to an interdisciplinary group of mathematicians, biologists, and engineers all working on lampreys.  �We had the best meetings,� says Hoffman, �because we were such an interdisciplinary group and it was predominantly women, which is very unusual in mathematics.�</p>
    <p>Hoffman�s task was to mathematically model neurons. �The model pushes you in the right direction experimentally,� she explains. In developing the equations for the model, however, Hoffman had to grapple with lamprey biology.</p>
    <p>�You don�t know what you�re trying to model if you don�t understand the biology,� she says.  �But I wouldn�t say I sit down and understand the biology and then start writing math. It�s a process. I understand a little bit of the biology, and then I do a little bit of the math, and then I go back.�</p>
    <p>One colleague says that Hoffman�s work modeling work is critical for the biologists and other researchers on the team to understand locomotion and design their experiments. �The problem of locomotion is difficult to understand without mathematics,� says Tim Kiemel, a research assistant professor in the department kinesiology at the University of Maryland, College Park.</p>
    <p>Hoffman eventually needs the power of computing to actually �do� the modeling. But before she dives into programming, she starts out using a pencil and paper to define the problem and pose the right questions.</p>
    <p>�Sometimes you just have to sit there and stare at it,� Hoffman says. �Sometimes you have to do a lot of calculation, or sometimes you just have to let it stew.�</p>
    <p>(02/07/14)</p>
    </div>
]]>
</Body>
<Summary>Making a Mark   A UMBC mathematician finds the right equation for biologists   Kathleen Hoffman, a professor of mathematics and statistics at UMBC, works in math biology, but she often felt that...</Summary>
<Website>https://umbc.edu/stories/umbc-making-a-mark/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/122837/guest@my.umbc.edu/0f08a68085cc6b94f532eacd78632c5f/api/pixel</TrackingUrl>
<Tag>window-stories</Tag>
<Group token="umbc-news-magazine">UMBC News &amp;amp; Magazine</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/umbc-news-magazine</GroupUrl>
<AvatarUrl>https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xsmall.png?1748556657</AvatarUrl>
<AvatarUrl size="original">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/original.png?1748556657</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xxlarge.png?1748556657</AvatarUrl>
<AvatarUrl size="xlarge">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xlarge.png?1748556657</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/large.png?1748556657</AvatarUrl>
<AvatarUrl size="medium">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/medium.png?1748556657</AvatarUrl>
<AvatarUrl size="small">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/small.png?1748556657</AvatarUrl>
<AvatarUrl size="xsmall">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xsmall.png?1748556657</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xxsmall.png?1748556657</AvatarUrl>
<Sponsor>UMBC News &amp; Magazine</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>false</CommentsAllowed>
<PostedAt>Wed, 12 Feb 2014 05:00:00 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="122836" important="false" status="posted" url="https://my3.my.umbc.edu/posts/122836">
<Title>UMBC: Planting A Seed</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <img width="150" height="150" src="https://umbc.edu/wp-content/uploads/2022/02/planting-seed1-150x150.jpg" alt="" style="max-width: 100%; height: auto;"><h2>Planting a Seed</h2>
    <h3>New grants grow UMBC�s research partnership with UMB </h3>
    <p>Faculty members at Maryland universities conduct important research that may provide relief for spinal cord injury victims, or develop new targeted methods to deliver drugs through nanotechnology.</p>
    <p>More and more of that vital work is being conducted in collaborations between faculty at UMBC and the University of Maryland, Baltimore (UMB). </p>
    <p>The latest venture to expand the research partnership between the two neighboring universities (separated by less than seven miles) is a joint UMBC-UMB Research and Innovation Partnership Seed Grant Program that pairs primary investigators from each university to conduct research as a team. Successful partners are offered research funding of up to $75,000 over twelve months to pursue their collaboration. </p>
    <p>The program�s first grant recipients were announced at a ceremony and poster session held at UMBC�s Albin O. Kuhn Library on February 11, 2014. Those selected for the awards included faculty in UMBC�s College of Natural and Mathematical Science and College of Engineering and Information Technology, as well as researchers in the University of Maryland School of Medicine and University of Maryland School of Pharmacy. </p>
    <p>At the announcement ceremony, UMB Chief Academic and Research Officer and Senior Vice President Bruce Jarrell observed that the Seed Grant Program represents the deepening of a relationship that already includes cooperation on a joint graduate school and the Institute of Marine Environmental Technology (IMET) as well as a panoply of curricular efforts in areas such as the life sciences, gerontology, health informatics and social work.</p>
    <p>�These collaborations already exist,� Jarrell observed. �And we�re proud to have UMBC as a partner.�</p>
    <p>UMBC <strong>President Freeman A. Hrabowski, III</strong>, is enthusiastic about the projects selected for the initial round, which include investigations that may influence the course of research into cancer, strokes and muscle degeneration.</p>
    <p>�The Seed Grant Program is a means by which both universities can better discover each other�s strengths and needs to see how we can better collaborate,� says Hrabowski.</p>
    <p>Jay Perman, President of the University of Maryland, Baltimore, says increased partnership between the two universities is a key element of his vision. �I cannot stress enough the importance we place on our collaborative relationship with our colleagues at UMBC. The partnerships that UMBC and UMB have enjoyed for years are real, longstanding collaborations, and have been extremely successful, if not widely known.�</p>
    <p>At the state level, the research partnerships fostered by the Seed Grant Program will further extend Maryland�s research profile and aid in securing vital funding from federal agencies, private foundations and other funding sources.</p>
    <p><strong>William E. Kirwan</strong>, Chancellor of the University System of Maryland (USM), praises the new program for its �focus on cutting-edge science and health concerns� and its emphasis on interdisciplinary teamwork.</p>
    <p>�It is this type of structured collaboration.� Kirwan says, �that will enable both UMBC and UMB�as well as the USM�to reach their full potential, and to take full advantage of the opportunities before us.�</p>
    <p>The first five teams to receive UMBC-UMB Research and Innovation Partnership Seed Grants are:</p>
    <p>* <strong>Kathleen Hoffman</strong>, professor of mathematics (UMBC) and <strong>Asaf Keller</strong>, professor of anatomy and neurobiology (UMB), are exploring the chronic pain of patients with spinal cord injury and how computational modeling may help analyze the neurobiological changes in the central nervous system after such injuries.</p>
    <p>* <strong>Martin Schneider</strong>, professor of biochemistry and molecular biology (UMB) and <strong>Bradford E. Peercy</strong>, assistant professor of mathematics (UMBC) are combining forces to analyze a transcription factor (Foxo1) in skeletal muscle that activates genes in a pathway that leads to the breakdown of muscle protein. They hope to develop protocols and models that will provide new approaches to controlling this factor. </p>
    <p>* <strong>Charles Bieberich</strong>, professor of biological sciences (UMBC) and <strong>Paul Shapiro</strong>, associate professor of pharmaceutical sciences (UMB) are working on a more targeted use of a promising cancer treatment called �kinase inhibition.� Currently kinase inhibition creates resistance over time, so Bieberich and Shapiro are looking for more selective paths to inhibit portions of an enzyme that allows cancer cells to multiply without shutting down other functions in the process.</p>
    <p>* <strong>Marie-Christine Daniel</strong>, associate professor of chemistry and biochemistry (UMBC) and <strong>Peter Swaan</strong>, professor of pharmaceutical sciences (UMB) are exploring how nanotechnology might improve the delivery of drugs (increased dosage, or better targeting) by examining a class of molecules known as �dendrons.�  </p>
    <p>* <strong>Tulay Adali</strong>, professor of computer science and electrical engineering (UMBC) and <strong>Kelly Westlake</strong>, assistant professor of physical therapy and rehabilitation science (UMB) are exploring how using a powerful computational tool (independent vector analysis) can aid in navigating  variability in cognitive neural function and better help the recovery of stroke victims. </p>
    <p><em> A call for proposals for the next round of the UMBC-UMB Research and Innovation Partnership Seed Grant Program will be issued on April 15, 2014. </em></p>
    <p>(02/12/14)</p>
    </div>
]]>
</Body>
<Summary>Planting a Seed   New grants grow UMBC�s research partnership with UMB    Faculty members at Maryland universities conduct important research that may provide relief for spinal cord injury...</Summary>
<Website>https://umbc.edu/stories/umbc-planting-a-seed/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/122836/guest@my.umbc.edu/acd7986c854a993f0f250f9658f26994/api/pixel</TrackingUrl>
<Tag>window-stories</Tag>
<Group token="umbc-news-magazine">UMBC News &amp;amp; Magazine</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/umbc-news-magazine</GroupUrl>
<AvatarUrl>https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xsmall.png?1748556657</AvatarUrl>
<AvatarUrl size="original">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/original.png?1748556657</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xxlarge.png?1748556657</AvatarUrl>
<AvatarUrl size="xlarge">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xlarge.png?1748556657</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/large.png?1748556657</AvatarUrl>
<AvatarUrl size="medium">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/medium.png?1748556657</AvatarUrl>
<AvatarUrl size="small">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/small.png?1748556657</AvatarUrl>
<AvatarUrl size="xsmall">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xsmall.png?1748556657</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xxsmall.png?1748556657</AvatarUrl>
<Sponsor>UMBC News &amp; Magazine</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>false</CommentsAllowed>
<PostedAt>Wed, 12 Feb 2014 05:00:00 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="41267" important="false" status="posted" url="https://my3.my.umbc.edu/posts/41267">
<Title>How to supercharge your site&#8217;s speed with AJAX and jQuery</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <p><img alt="thumbnail" src="http://netdna.webdesignerdepot.com/uploads/2014/02/thumbnail15.jpg" width="200" height="160" style="max-width: 100%; height: auto;">In this tutorial we’re going to look at how to speed up the user experience on small static sites using a few different methods. (A static site is one which doesn’t have any renewing content, so no blog posts or photo streams etc.)</p> <p>The way we’re going to be doing this is by taking out page reloads. So simply put, when the user uses some navigation links, only the main content of the page changes and it doesn’t make the browser reload the page.</p> <p>We will be achieving this effect in two different ways, the first only uses jQuery, and the other uses AJAX and some PHP. They both have their pros and cons, which we’ll look at as well. Take a look at <a href="http://netdna.webdesignerdepot.com/uploads7/how-to-supercharge-your-sites-speed-with-ajax-and-jquery/demo1/" rel="nofollow external" class="bo">the demo</a> to see what we’re trying to achieve and let’s start with the first (and simpler) jQuery method.</p> <h1>Achieving the effect with jQuery</h1> <p>First we will look at the setup for the page. The HTML is very simple but has a few important parts, “the essentials” as it were. We need some navigation links which have a specific hash href (which we’ll explain in a minute) and a specified content area which you would already have on any other site anyway. So let’s first see what is in our index.html file:</p> <pre>&lt;body&gt;<br>&lt;header&gt;<br> &lt;h1&gt;Speed Up Static Sites with jQuery&lt;/h1&gt;<br> &lt;nav&gt;<br> &lt;ul&gt;<br> &lt;li&gt;&lt;a href="#page1" class="active" id="page1-link"&gt;Page 1&lt;/a&gt;&lt;/li&gt;<br> &lt;li&gt;&lt;a href="#page2" id="page2-link"&gt;Page 2&lt;/a&gt;&lt;/li&gt;<br> &lt;li&gt;&lt;a href="#page3" id="page3-link"&gt;Page 3&lt;/a&gt;&lt;/li&gt;<br> &lt;li&gt;&lt;a href="#page4" id="page4-link"&gt;Page 4&lt;/a&gt;&lt;/li&gt;<br> &lt;/ul&gt;<br> &lt;/nav&gt;<br>&lt;/header&gt;<br>&lt;div id="main-content"&gt;<br> &lt;section id="page1"&gt;<br> &lt;h2&gt;First Page Title&lt;/h2&gt;<br> &lt;p&gt;First page content.&lt;/p&gt;<br> &lt;/section&gt;<br> &lt;section id="page2"&gt;<br> &lt;h2&gt;Look, no page load!&lt;/h2&gt;<br> &lt;p&gt;Second page content.&lt;/p&gt;<br> &lt;/section&gt;<br> &lt;section id="page3"&gt;<br> &lt;h2&gt;Ooh fade!&lt;/h2&gt;<br> &lt;p&gt;Third page content.&lt;/p&gt;<br> &lt;/section&gt;<br> &lt;section id="page4"&gt;<br> &lt;h2&gt;Fourth Page Title&lt;/h2&gt;<br> &lt;p&gt;Fourth page content.&lt;/p&gt;<br> &lt;/section&gt;<br>&lt;/div&gt; &lt;!-- end #main-content --&gt;<br>&lt;script type="text/javascript" src="<a href="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js%22&gt;&lt;/script&amp;gt">http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"&gt;&lt;/script&amp;gt</a>;<br>&lt;script type="text/javascript" src="custom.js"&gt;&lt;/script&gt;<br>&lt;/body&gt;</pre> <p>So to recap the important parts of what needs to go into the markup: we have our navigation in which each link has an href of the corresponding DIV. So the link to “Page 2″ has a href=”#page2″ (which is the id of the &lt;section&gt; element further down). So with this first method as you can see we have a div of #main-content surrounding our sections, and then each page content one after the other in their own separate ‘section’ element. We also call jQuery and our own custom.js javascript file in which the actual functionality of the site will be made.</p> <p>But before we get to that we need to add one line to our CSS, there’s no need to go over the whole CSS file for this example as it’s all only for looks, which will change with whatever project you’re working on. However, with this first method there’s one line that’s essential and that’s:</p> <pre>#page2, #page3, #page4 {<br>display: none;<br>}</pre> <p>This hides all the ‘pages’ except the first one. So the page appears normally on first load.</p> <h2>The JavaScript</h2> <p>So now to explain what we need to achieve via jQuery. In our custom.js file, we need to target when the user clicks on a navigation link. Retrieve its href link and find the ‘section’ with that same ID, then hide everything in the #main-content div and fade in the new section. This is what it looks like:</p> <pre>$(function() {<br>    $('header nav a').click(function() {<br>        var $linkClicked = $(this).attr('href');<br>        document.location.hash = $linkClicked;<br>        if (!$(this).hasClass("active")) {<br>            $("header nav a").removeClass("active");<br>            $(this).addClass("active");<br>            $('#main-content section').hide();<br>            $($linkClicked).fadeIn();<br>            return false;<br>        }<br>        else {<br>            return false;<br>        }<br>    });<br>    var hash = window.location.hash;<br>    hash = hash.replace(/^#/, '');<br>    switch (hash) {<br>        case 'page2' :<br>            $("#" + hash + "-link").trigger("click");<br>            break;<br>        case 'page3' :<br>            $("#" + hash + "-link").trigger("click");<br>            break;<br>        case 'page4' :<br>            $("#" + hash + "-link").trigger("click");<br>            break;<br>    }<br>});</pre> <p>This code is split into two sections, the first achieves what we just talked about. It has a click function on the header nav links. It then puts the ‘#page1, #page2′ etc into a variable named $linkClicked. We then update the browser’s URL to have that same hash name. Then we have an if statement making sure the link we’re clicking is not the current tab, if it is then do nothing, but if not hide all current content and unhide the div with an ID of $linkClicked. Simple as that!</p> <p>The second section checks if the url has a hash link on the end of it, if it does, it finds a corresponding link on the page with the same value (that’s why the links have specific IDs in the markup) and then it triggers that link (it clicks on it). What this does, is means the user can reload a page after having navigated to a ‘page’ and the refresh will send the user back there instead of just back to the first page, which can often be a problem with this sort of system.</p> <p>So that’s the end of the first method, this results in a working static site that has instantaneous content swapping, and no page reloads. The only drawback to this method is the fact that all the content is called on the initial load, as it’s all there in the index file. This can start to be a problem with photos and extra content making the first site visit load a bit longer. So let’s look at another way to do this same effect which can eliminate that problem.</p> <p> </p> <h1>Using AJAX and PHP</h1> <p>To achieve this same effect but in a slightly different way, so that the initial load isn’t going to load all of our content and thus slow it down (defeating the point if the site has a lot of content) we will use a little PHP and AJAX. This means that the file structure for our project will change and look like this:</p> <p><a href="http://netdna.webdesignerdepot.com/uploads/2014/02/structure.jpg" rel="nofollow external" class="bo"><img src="http://netdna.webdesignerdepot.com/uploads/2014/02/structure.jpg" width="650" alt="How to supercharge your sites speed with AJAX and jQuery" style="max-width: 100%; height: auto;"></a></p> <p>So if you look, the index file is now a .php and not a .html. We also have an extra file named ‘load.php’ as well as a new folder/directory called pages in which there are four HTML pages. Now this means that if you’re working locally you need to set up a local development environment using something like <a href="http://mamp.info" rel="nofollow external" class="bo">MAMP</a> (for Mac) or <a href="http://www.wampserver.com/en/" rel="nofollow external" class="bo">WAMP Server</a> (for Windows). Or you can upload the whole folder onto a web server if you have access and edit on there, basically you’ll need an environment where the PHP will work.</p> <p>The index.php has only changed one thing, but it’s important, we will now not load all the content in there, and simply call the initial content in with a PHP include. It now will look something like this:</p> <pre>&lt;body&gt;<br>&lt;header&gt;<br> &lt;h1&gt;AJAX a Static Site&lt;/h1&gt;<br> &lt;nav&gt;<br> &lt;ul&gt;<br> &lt;li&gt;&lt;a href="#page1" class="active" id="page1-link"&gt;Page 1&lt;/a&gt;&lt;/li&gt;<br> &lt;li&gt;&lt;a href="#page2" id="page2-link"&gt;Page 2&lt;/a&gt;&lt;/li&gt;<br> &lt;li&gt;&lt;a href="#page3" id="page3-link"&gt;Page 3&lt;/a&gt;&lt;/li&gt;<br> &lt;li&gt;&lt;a href="#page4" id="page4-link"&gt;Page 4&lt;/a&gt;&lt;/li&gt;<br> &lt;/ul&gt;<br> &lt;/nav&gt;<br>&lt;/header&gt;<br>&lt;div id="main-content"&gt;<br>&lt;?php include('pages/page1.html'); ?&gt;<br>&lt;/div&gt; &lt;!-- end #main-content --&gt;<br>&lt;script type="text/javascript" src="<a href="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js%22&gt;&lt;/script&amp;gt">http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"&gt;&lt;/script&amp;gt</a>;<br>&lt;script type="text/javascript" src="custom.js"&gt;&lt;/script&gt;<br>&lt;/body&gt;</pre> <p>So the line beginning <em>&lt;?php</em> is calling in the first HTML file from our folder of pages and inserting in entirely into our #main-content DIV. The file called can contain whatever content you want to appear on the page.</p> <h2>Using $.ajax in the JavaScript</h2> <p>Let’s move onto the new JavaScript, it now looks slightly different, mainly we’re now using AJAX to fetch the new content from each HTML file when the user clicks on some corresponding navigation. Here’s the first function in the code (the second stays the same as before):</p> <pre>$(function() {<br>    $('header nav a').click(function() {<br>        var $linkClicked = $(this).attr('href');<br>        document.location.hash = $linkClicked;<br>        var $pageRoot = $linkClicked.replace('#page', '');<br>        if (!$(this).hasClass("active")) {<br>            $("header nav a").removeClass("active");<br>            $(this).addClass("active");<br>            $.ajax({<br>                type: "POST",<br>                url: "load.php",<br>                data: 'page='+$pageRoot,<br>                dataType: "html",<br>                success: function(msg){<br>                if(parseInt(msg)!=0)<br>                {<br>                    $('#main-content').html(msg);<br>                    $('#main-content section').hide().fadeIn();<br>                }<br>            }<br>        });<br>    }<br>    else {<br>        event.preventDefault();<br>    }<br>});</pre> <p>So let’s explain what’s going on. We’re adding one more variable, that’s $pageRoot. This is basically the actual number clicked (taking way the ‘#page’ part of the hash link and leaving the individual number). Then inside the same “if” statement as before we call ajax and use the other PHP file we mentioned earlier to parse the information given (which link has been clicked) and find the corresponding page. Then if it comes back with no error, we insert the new HTML from the file received into our #main-content DIV. Then just to stop it changing suddenly, we hide everything and then fade it in.</p> <h2>load.php</h2> <p>The contents of the new PHP file is short and sweet, it takes the page number that jQuery has sent it and looks to see if the corresponding HTML file exists. If it does it gets all the content and returns it to the AJAX function (which we showed a moment ago that we insert that content into the main DIV).</p> <pre>&lt;?php<br>if(!$_POST['page']) die("0");<br>$page = (int)$_POST['page'];<br>if(file_exists('pages/page'.$page.'.html'))<br>echo file_get_contents('pages/page'.$page.'.html');<br>else echo 'There is no such page!';<br>?&gt;</pre> <p>Following that the site should look however you want it to, but mostly work properly.</p> <p>That’s it! The site now calls in the right corresponding HTML file each time the user clicks on a navigation link. It swaps out the content without making the page reload. And this way it still doesn’t have to call all the content on the initial page load! I hope you’ve managed to learn some useful method from this tutorial and that you can use it to improve some project in some way.</p> <p>You can view the <a href="http://netdna.webdesignerdepot.com/uploads7/how-to-supercharge-your-sites-speed-with-ajax-and-jquery/demo1/" rel="nofollow external" class="bo">jQuery demo here,</a> the <a href="http://netdna.webdesignerdepot.com/uploads7/how-to-supercharge-your-sites-speed-with-ajax-and-jquery/demo2/" rel="nofollow external" class="bo">PHP demo here,</a> or <a href="http://netdna.webdesignerdepot.com/uploads7/how-to-supercharge-your-sites-speed-with-ajax-and-jquery/download.zip" rel="nofollow external" class="bo">download the source</a> and take a closer look.</p> <p> </p> <p><em><strong>Have you used AJAX for loading content? Have you used a similar technique to speed up your site? Let us know your thoughts in the comments below.</strong></em></p> <p><em>Featured image/thumbnail, <a href="http://www.shutterstock.com/pic-130275437/stock-photo-bakersfield-ca-mar-a-bright-orange-ford-pickup-hot-rod-is-displayed-for-the-cruisin-for-a.html" rel="nofollow external" class="bo">supercharged image</a> via Shutterstock.</em></p> <p><br><br> </p>
    <table width="100%"> <tbody>
    <tr> <td> <a href="http://www.mightydeals.com/deal/beautune.html?ref=inwidget" rel="nofollow external" class="bo"><strong>Create Picture-Perfect Portraits With Beautune – only $14!</strong></a> </td> <td> <a href="http://www.mightydeals.com/?ref=inwidget" rel="nofollow external" class="bo"><br> <img src="http://mightydeals.com/web/images/widget-logo.png" height="40" width="90" alt="How to supercharge your sites speed with AJAX and jQuery" style="max-width: 100%; height: auto;"><br> </a> </td> </tr> </tbody>
    </table> <p><br> </p> <a href="http://www.webdesignerdepot.com/2014/02/how-to-supercharge-your-sites-speed-with-ajax-and-jquery/" rel="nofollow external" class="bo">Source</a> <br><div><table border="0"><tbody><tr><td>
    <a href="http://share.feedsportal.com/share/twitter/?u=http%3A%2F%2Fwww.webdesignerdepot.com%2F2014%2F02%2Fhow-to-supercharge-your-sites-speed-with-ajax-and-jquery%2F&amp;t=How+to+supercharge+your+site%E2%80%99s+speed+with+AJAX+and+jQuery" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/twitter.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/facebook/?u=http%3A%2F%2Fwww.webdesignerdepot.com%2F2014%2F02%2Fhow-to-supercharge-your-sites-speed-with-ajax-and-jquery%2F&amp;t=How+to+supercharge+your+site%E2%80%99s+speed+with+AJAX+and+jQuery" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/facebook.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/linkedin/?u=http%3A%2F%2Fwww.webdesignerdepot.com%2F2014%2F02%2Fhow-to-supercharge-your-sites-speed-with-ajax-and-jquery%2F&amp;t=How+to+supercharge+your+site%E2%80%99s+speed+with+AJAX+and+jQuery" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/linkedin.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/gplus/?u=http%3A%2F%2Fwww.webdesignerdepot.com%2F2014%2F02%2Fhow-to-supercharge-your-sites-speed-with-ajax-and-jquery%2F&amp;t=How+to+supercharge+your+site%E2%80%99s+speed+with+AJAX+and+jQuery" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/googleplus.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/email/?u=http%3A%2F%2Fwww.webdesignerdepot.com%2F2014%2F02%2Fhow-to-supercharge-your-sites-speed-with-ajax-and-jquery%2F&amp;t=How+to+supercharge+your+site%E2%80%99s+speed+with+AJAX+and+jQuery" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/email.png" style="max-width: 100%; height: auto;"></a>
    </td></tr></tbody></table></div>
    <br><br><a href="http://da.feedsportal.com/r/187557692925/u/49/f/661066/c/35285/s/37001dc7/sc/4/rc/1/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187557692925/u/49/f/661066/c/35285/s/37001dc7/sc/4/rc/1/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/187557692925/u/49/f/661066/c/35285/s/37001dc7/sc/4/rc/2/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187557692925/u/49/f/661066/c/35285/s/37001dc7/sc/4/rc/2/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/187557692925/u/49/f/661066/c/35285/s/37001dc7/sc/4/rc/3/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187557692925/u/49/f/661066/c/35285/s/37001dc7/sc/4/rc/3/rc.img" style="max-width: 100%; height: auto;"></a><br><br><a href="http://da.feedsportal.com/r/187557692925/u/49/f/661066/c/35285/s/37001dc7/a2.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/187557692925/u/49/f/661066/c/35285/s/37001dc7/a2.img" style="max-width: 100%; height: auto;"></a>
    </div>
]]>
</Body>
<Summary>In this tutorial we’re going to look at how to speed up the user experience on small static sites using a few different methods. (A static site is one which doesn’t have any renewing content, so...</Summary>
<Website>http://rss.feedsportal.com/c/35285/f/661066/s/37001dc7/sc/4/l/0L0Swebdesignerdepot0N0C20A140C0A20Chow0Eto0Esupercharge0Eyour0Esites0Espeed0Ewith0Eajax0Eand0Ejquery0C/story01.htm</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/41267/guest@my.umbc.edu/4cd6635dcb648c3464a68c85e0ef173d/api/pixel</TrackingUrl>
<Tag>ajax</Tag>
<Tag>art</Tag>
<Tag>css</Tag>
<Tag>design</Tag>
<Tag>development</Tag>
<Tag>how-to</Tag>
<Tag>html</Tag>
<Tag>html5</Tag>
<Tag>illustrator</Tag>
<Tag>javascript</Tag>
<Tag>jquery</Tag>
<Tag>loading-techniques</Tag>
<Tag>mysql</Tag>
<Tag>oracle</Tag>
<Tag>photoshop</Tag>
<Tag>php</Tag>
<Tag>site-speed</Tag>
<Tag>speed-up-your-site</Tag>
<Tag>sql</Tag>
<Tag>website-speed</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Wed, 12 Feb 2014 03:15:04 -0500</PostedAt>
<EditAt>Wed, 12 Feb 2014 03:15:04 -0500</EditAt>
</NewsItem>

<NewsItem contentIssues="false" id="41266" important="false" status="posted" url="https://my3.my.umbc.edu/posts/41266">
<Title>Sell Your Personal Data for $8 a Month</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <p>Would you let a startup track your social media accounts and credit-card transactions in exchange for cash?</p>
    <p>A startup called <a href="https://datacoup.com/" rel="nofollow external" class="bo">Datacoup</a> is far from the only tech company hoping to get rich by selling insights mined from your personal data. But it may be the only one offering to give you money for that information.</p>
    </div>
]]>
</Body>
<Summary>Would you let a startup track your social media accounts and credit-card transactions in exchange for cash?  A startup called Datacoup is far from the only tech company hoping to get rich by...</Summary>
<Website>http://www.technologyreview.com/news/524621/sell-your-personal-data-for-8-a-month/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/41266/guest@my.umbc.edu/d5fd7fe67c5e483099beb8f91160e10f/api/pixel</TrackingUrl>
<Tag>development</Tag>
<Tag>internet</Tag>
<Tag>mit</Tag>
<Tag>technology</Tag>
<Tag>web</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Wed, 12 Feb 2014 00:00:00 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="false" id="54202" important="false" status="posted" url="https://my3.my.umbc.edu/posts/54202">
<Title>User-Experience Driven Mobile Health Applications and Services</Title>
<Body>
<![CDATA[
    <div class="html-content">
      <p><img src="https://drkoru.us/./_static/assets/images/News/katarzyna.jpg" alt="katarzyna.jpg" style="max-width: 100%; height: auto;">
      </p>
      <span>Figure 32:</span> Dr. Wac speaking on Mobile Health Apps and Services
      
    
      <p>
      By <strong>Ms. Katarzyna Wac</strong>
      </p>
    
      <p>
      <strong>Abstract</strong> Increasingly, we use mobile applications and services in our
      daily life activities, to support our needs for information,
      communication, leisure, or even health and care needs. However, user
      acceptance of a mobile application depends on at least two conditions:
      the application's perceived experience, and the appropriateness of the
      application to the user's context and needs. However, we have a weak
      understanding of a mobile user's quality of experience (QoE) and the
      factors influencing it. In my talk i discuss a 4-week-long
      29-Android-phone-user study, where we collected both QoE and the
      underlying network's quality of service measurements through a
      combination of user, application, and network data on the user's phones.
      We aimed to derive and improve the understanding of users' QoE for a set
      of widely used mobile applications in users' natural environments and
      different daily contexts. I present data acquired in the study and
      discuss implications for mobile applications design, especially those in
      mobile health domain. I propose a framework for assuring the user's
      experience for these applications.
      </p>
    
      <p>
      Bio: Ms. Katarzyna Wac is a senior scientist (fr. "MER") at the
      Institute of Services Science (ISS) of University of Geneva (UniGE) and
      leader of the Quality of Life (QoL) research area since 2010. She holds
      a BSc and MSc degree in Computer Science from Wroclaw University of
      Technology (WUT, Poland), an MSc in Telematics from University of Twente
      (UT, the Netherlands), as well as a PhD in Information Systems from
      University of Geneva (Switzerland). In 2003-2004, Ms. Wac was a research
      staff member at University of Twente. In 2005 she joined University of
      Geneva as a research and teaching assistant, while keeping her
      affiliation with the University of Twente. In 2007-2010, Ms. Wac was
      also affiliated with the MobiHealth BV start-up company. In 2009-2010,
      Ms. Wac was on leave for a one-year Swiss NSF Fellowship at Carnegie
      Mellon University (CMU, USA), Human-Computer Interaction Institute
      (HCII). Along the summer 2013, Ms. Wac was supported by Swiss NSF
      International Visits program to research at Stanford University
      (Stanford, USA), and particularly at the Stanford Human-Sciences and
      Technologies Advanced Research Institute (H-STAR). Ms. Wac's research
      interests include Quality of Service-aware mobile systems and services
      with special emphasis on support of adaptive multimedia protocols and
      Quality of Service mechanisms, especially in the mobile healthcare
      (i.e., mHealth) domain. Ms. Wac strives towards effective and efficient
      pervasive mobile computing and communication - meeting the end-user
      Quality of Service requirements and Quality of Experience expectations.
      Ms. Wac is since 2012 an Associate Expert of the International
      Telecommunication Union (ITU) European Regional Initiative for mHealth.
      </p>
    </div>
]]>
</Body>
<Summary>Figure 32: Dr. Wac speaking on Mobile Health Apps and Services           By Ms. Katarzyna Wac            Abstract Increasingly, we use mobile applications and services in our   daily life...</Summary>
<Website>https://drkoru.us/posts.html#user-experience-driven-mobile-health-applications-and-services</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/54202/guest@my.umbc.edu/73b526792105e2fb92ac5f066545c425/api/pixel</TrackingUrl>
<Group token="hit">Health IT Community @ UMBC</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/hit</GroupUrl>
<AvatarUrl>https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/362/b95466b8b139e9e1fa1400d527798b7c/xsmall.png?1419188005</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/362/b95466b8b139e9e1fa1400d527798b7c/original.jpg?1419188005</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/362/b95466b8b139e9e1fa1400d527798b7c/xxlarge.png?1419188005</AvatarUrl>
<AvatarUrl size="xlarge">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/362/b95466b8b139e9e1fa1400d527798b7c/xlarge.png?1419188005</AvatarUrl>
<AvatarUrl size="large">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/362/b95466b8b139e9e1fa1400d527798b7c/large.png?1419188005</AvatarUrl>
<AvatarUrl size="medium">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/362/b95466b8b139e9e1fa1400d527798b7c/medium.png?1419188005</AvatarUrl>
<AvatarUrl size="small">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/362/b95466b8b139e9e1fa1400d527798b7c/small.png?1419188005</AvatarUrl>
<AvatarUrl size="xsmall">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/362/b95466b8b139e9e1fa1400d527798b7c/xsmall.png?1419188005</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/362/b95466b8b139e9e1fa1400d527798b7c/xxsmall.png?1419188005</AvatarUrl>
<Sponsor>Health IT Community @ UMBC</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>false</CommentsAllowed>
<PostedAt>Wed, 12 Feb 2014 00:00:00 -0500</PostedAt>
<EditAt>Wed, 12 Feb 2014 00:00:00 -0500</EditAt>
</NewsItem>

<NewsItem contentIssues="true" id="41265" important="false" status="posted" url="https://my3.my.umbc.edu/posts/41265">
<Title>Sass Mixins, JavaScript Coding, Git Tips | The Treehouse Show Episode 77</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <p>It’s Tuesday which means that the Treehouse Show is back! In episode 77 of The Treehouse Show, Nick and Jason (<a href="http://twitter.com/jseifer" rel="nofollow external" class="bo">@jseifer</a>) talk about Sass mixins, JavaScript coding, git tips, and much more.</p>
    <p></p>
    <div class="embed-container"><iframe src="//www.youtube.com/embed/FGx80JSmLBc" frameborder="0" webkitallowfullscreen="webkitAllowFullScreen" mozallowfullscreen="mozallowfullscreen" allowfullscreen="allowFullScreen">[Video]</iframe></div>
    <h3>This Week’s Links</h3>
    <ul>
    <li>
    <p><a href="http://zerosixthree.se/8-sass-mixins-you-must-have-in-your-toolbox/" rel="nofollow external" class="bo">Z63 | 8 Sass mixins you must have in your toolbox</a></p>
    </li>
    <li>
    <p><a href="http://www.mozilla.org/en-US/firefox/27.0/releasenotes/" rel="nofollow external" class="bo">Firefox Notes – Desktop</a></p>
    </li>
    <li>
    <p><a href="http://www.sitepoint.com/sass-mixin-placeholder/" rel="nofollow external" class="bo">Sass: Mixin or Placeholder?</a></p>
    </li>
    <li>
    <p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/A_re-introduction_to_JavaScript" rel="nofollow external" class="bo">A re-introduction to JavaScript (JS Tutorial) – JavaScript | MDN</a></p>
    </li>
    <li>
    <p><a href="https://github.com/carrot/share-button" rel="nofollow external" class="bo">carrot/share-button</a></p>
    </li>
    <li>
    <p><a href="https://ochronus.com/git-tips-from-the-trenches/" rel="nofollow external" class="bo">Git tips from the trenches</a></p>
    </li>
    <li>
    <p><a href="http://patterns.alistapart.com/" rel="nofollow external" class="bo">A List Apart Pattern Library</a></p>
    </li>
    <p>The post <a href="http://blog.teamtreehouse.com/sass-mixins-javascript-coding-git-tips-treehouse-show-episode-77" rel="nofollow external" class="bo">Sass Mixins, JavaScript Coding, Git Tips | The Treehouse Show Episode 77</a> appeared first on <a href="http://blog.teamtreehouse.com" rel="nofollow external" class="bo">Treehouse Blog</a>.</p>
    </ul>
    </div>
]]>
</Body>
<Summary>It’s Tuesday which means that the Treehouse Show is back! In episode 77 of The Treehouse Show, Nick and Jason (@jseifer) talk about Sass mixins, JavaScript coding, git tips, and much more....</Summary>
<Website>http://feedproxy.google.com/~r/teamtreehouse/~3/vWGcl49o-Fc/sass-mixins-javascript-coding-git-tips-treehouse-show-episode-77</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/41265/guest@my.umbc.edu/8a598ae762fb131753e811e84d7465e6/api/pixel</TrackingUrl>
<Tag>android</Tag>
<Tag>css</Tag>
<Tag>design</Tag>
<Tag>development</Tag>
<Tag>html</Tag>
<Tag>ios</Tag>
<Tag>javascript</Tag>
<Tag>responsive</Tag>
<Tag>treehouse-show</Tag>
<Tag>web</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Tue, 11 Feb 2014 23:59:01 -0500</PostedAt>
<EditAt>Tue, 11 Feb 2014 23:59:01 -0500</EditAt>
</NewsItem>

<NewsItem contentIssues="true" id="41264" important="false" status="posted" url="https://my3.my.umbc.edu/posts/41264">
<Title>When Gender Identity leads to Bathroom Equality</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <p><a href="http://usdemocrazy.net/wp-content/uploads/2014/02/Democrazy12-630x6301.jpg" rel="nofollow external" class="bo"><img alt="" src="http://usdemocrazy.net/wp-content/uploads/2014/02/Democrazy12-630x6301.jpg" width="504" height="504" style="max-width: 100%; height: auto;"></a></p>
    <p>Here’s a tricky one for you…can genetic guys use girls’ bathrooms?</p>
    <p>This very question was recently contested in the courts of Maine, where the highest court ruled that a biological male, who has identified as a female for most of her life,<a href="http://news.yahoo.com/maine-court-rules-favor-transgender-pupil-165405315.html" rel="nofollow external" class="bo"> may use the women’s restroom instead of the men’s. </a></p>
    <p>The court further held that preventing her from using the women’s bathroom was discrimination, and a violation of her rights.</p>
    <p> Critics have complained that this move is impossible to enforce. Can a guy suddenly decide to “identify” as a girl just to get into the girls’ restroom?</p>
    <p>Where do schools draw the line between who is, and who is not, allowed in a restroom? While the court stressed that males should not be “casually” granted access to women’s facilities, the question of who can use the women’s bathroom is still very unclear.</p>
    <p>Maybe your thoughts on this are clearer… What do you think about this new commotion in the commodes?</p>
    </div>
]]>
</Body>
<Summary>Here’s a tricky one for you…can genetic guys use girls’ bathrooms?   This very question was recently contested in the courts of Maine, where the highest court ruled that a biological male, who has...</Summary>
<Website>http://usdemocrazy.net/when-gender-identity-leads-to-bathroom-equality/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/41264/guest@my.umbc.edu/a09dd8bca111ca0a9d2d9052d03d9ef6/api/pixel</TrackingUrl>
<Tag>bathrooms</Tag>
<Tag>current</Tag>
<Tag>democracy</Tag>
<Tag>equality</Tag>
<Tag>gay</Tag>
<Tag>lgbt</Tag>
<Tag>lgbtq</Tag>
<Tag>marriage</Tag>
<Tag>marriage-equality</Tag>
<Tag>morality</Tag>
<Tag>news</Tag>
<Tag>politics</Tag>
<Tag>rights</Tag>
<Tag>school</Tag>
<Tag>transgender</Tag>
<Tag>us</Tag>
<Tag>usdemocrazy</Tag>
<Group token="retired-12">USDemocrazy</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-12</GroupUrl>
<AvatarUrl>https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/012/f0935e4cd5920aa6c7c996a5ee53a70f/xsmall.png?1279120129</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/012/f0935e4cd5920aa6c7c996a5ee53a70f/original.jpg?1279120129</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/012/f0935e4cd5920aa6c7c996a5ee53a70f/xxlarge.png?1279120129</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/012/f0935e4cd5920aa6c7c996a5ee53a70f/xlarge.png?1279120129</AvatarUrl>
<AvatarUrl size="large">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/012/f0935e4cd5920aa6c7c996a5ee53a70f/large.png?1279120129</AvatarUrl>
<AvatarUrl size="medium">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/012/f0935e4cd5920aa6c7c996a5ee53a70f/medium.png?1279120129</AvatarUrl>
<AvatarUrl size="small">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/012/f0935e4cd5920aa6c7c996a5ee53a70f/small.png?1279120129</AvatarUrl>
<AvatarUrl size="xsmall">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/012/f0935e4cd5920aa6c7c996a5ee53a70f/xsmall.png?1279120129</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/012/f0935e4cd5920aa6c7c996a5ee53a70f/xxsmall.png?1279120129</AvatarUrl>
<Sponsor>USDemocrazy</Sponsor>
<PawCount>14</PawCount>
<CommentCount>41</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Tue, 11 Feb 2014 23:47:28 -0500</PostedAt>
<EditAt>Tue, 11 Feb 2014 23:48:28 -0500</EditAt>
</NewsItem>

<NewsItem contentIssues="true" id="41282" important="false" status="posted" url="https://my3.my.umbc.edu/posts/41282">
<Title>Liquid-Cooled Supercomputers, to Trim the Power Bill</Title>
<Body>
<![CDATA[
    <div class="html-content">Looking to reduce energy bills and environmental strains, operators of supercomputers are immersing them in cooling liquids.<br><div><table border="0"><tbody><tr><td>
    <a href="http://share.feedsportal.com/share/twitter/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F02%2F12%2Fbusiness%2Finternational%2Fimproving-energy-efficiency-in-supercomputers.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Liquid-Cooled+Supercomputers%2C+to+Trim+the+Power+Bill" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/twitter.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/facebook/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F02%2F12%2Fbusiness%2Finternational%2Fimproving-energy-efficiency-in-supercomputers.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Liquid-Cooled+Supercomputers%2C+to+Trim+the+Power+Bill" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/facebook.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/linkedin/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F02%2F12%2Fbusiness%2Finternational%2Fimproving-energy-efficiency-in-supercomputers.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Liquid-Cooled+Supercomputers%2C+to+Trim+the+Power+Bill" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/linkedin.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/gplus/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F02%2F12%2Fbusiness%2Finternational%2Fimproving-energy-efficiency-in-supercomputers.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Liquid-Cooled+Supercomputers%2C+to+Trim+the+Power+Bill" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/googleplus.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/email/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F02%2F12%2Fbusiness%2Finternational%2Fimproving-energy-efficiency-in-supercomputers.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Liquid-Cooled+Supercomputers%2C+to+Trim+the+Power+Bill" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/email.png" style="max-width: 100%; height: auto;"></a>
    </td></tr></tbody></table></div>
    </div>
]]>
</Body>
<Summary>Looking to reduce energy bills and environmental strains, operators of supercomputers are immersing them in cooling liquids.      </Summary>
<Website>http://www.nytimes.com/2014/02/12/business/international/improving-energy-efficiency-in-supercomputers.html?partner=rss&amp;emc=rss</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/41282/guest@my.umbc.edu/aa3696b4ac94ade17030f694daaebc29/api/pixel</TrackingUrl>
<Tag>3m-company-mmm-nyse</Tag>
<Tag>data-centers</Tag>
<Tag>energy-efficiency</Tag>
<Tag>intel-corporation-intc-nasdaq</Tag>
<Tag>new</Tag>
<Tag>supercomputers</Tag>
<Tag>technology</Tag>
<Tag>tokyo-japan</Tag>
<Tag>york</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Tue, 11 Feb 2014 23:00:10 -0500</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="41261" important="false" status="posted" url="https://my3.my.umbc.edu/posts/41261">
<Title>Spy Chief Says Snowden Took Advantage of &#8216;Perfect Storm&#8217; of Security Lapses</Title>
<Body>
<![CDATA[
    <div class="html-content">James R. Clapper Jr., the director of national intelligence, said the technology was not yet fully in place to prevent another insider from stealing top-secret data, as Edward J. Snowden did.<br><div><table border="0"><tbody><tr><td>
    <a href="http://share.feedsportal.com/share/twitter/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F02%2F12%2Fus%2Fpolitics%2Fspy-chief-says-snowden-took-advantage-of-perfect-storm-of-security-lapses.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Spy+Chief+Says+Snowden+Took+Advantage+of+%E2%80%98Perfect+Storm%E2%80%99+of+Security+Lapses" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/twitter.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/facebook/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F02%2F12%2Fus%2Fpolitics%2Fspy-chief-says-snowden-took-advantage-of-perfect-storm-of-security-lapses.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Spy+Chief+Says+Snowden+Took+Advantage+of+%E2%80%98Perfect+Storm%E2%80%99+of+Security+Lapses" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/facebook.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/linkedin/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F02%2F12%2Fus%2Fpolitics%2Fspy-chief-says-snowden-took-advantage-of-perfect-storm-of-security-lapses.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Spy+Chief+Says+Snowden+Took+Advantage+of+%E2%80%98Perfect+Storm%E2%80%99+of+Security+Lapses" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/linkedin.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/gplus/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F02%2F12%2Fus%2Fpolitics%2Fspy-chief-says-snowden-took-advantage-of-perfect-storm-of-security-lapses.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Spy+Chief+Says+Snowden+Took+Advantage+of+%E2%80%98Perfect+Storm%E2%80%99+of+Security+Lapses" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/googleplus.png" style="max-width: 100%; height: auto;"></a> <a href="http://share.feedsportal.com/share/email/?u=http%3A%2F%2Fwww.nytimes.com%2F2014%2F02%2F12%2Fus%2Fpolitics%2Fspy-chief-says-snowden-took-advantage-of-perfect-storm-of-security-lapses.html%3Fpartner%3Drss%26emc%3Drss&amp;t=Spy+Chief+Says+Snowden+Took+Advantage+of+%E2%80%98Perfect+Storm%E2%80%99+of+Security+Lapses" rel="nofollow external" class="bo"><img src="http://res3.feedsportal.com/social/email.png" style="max-width: 100%; height: auto;"></a>
    </td></tr></tbody></table></div>
    <br><br><a href="http://da.feedsportal.com/r/186530526402/u/0/f/640387/c/34625/s/36fe4216/sc/1/rc/1/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186530526402/u/0/f/640387/c/34625/s/36fe4216/sc/1/rc/1/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/186530526402/u/0/f/640387/c/34625/s/36fe4216/sc/1/rc/2/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186530526402/u/0/f/640387/c/34625/s/36fe4216/sc/1/rc/2/rc.img" style="max-width: 100%; height: auto;"></a><br><a href="http://da.feedsportal.com/r/186530526402/u/0/f/640387/c/34625/s/36fe4216/sc/1/rc/3/rc.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186530526402/u/0/f/640387/c/34625/s/36fe4216/sc/1/rc/3/rc.img" style="max-width: 100%; height: auto;"></a><br><br><a href="http://da.feedsportal.com/r/186530526402/u/0/f/640387/c/34625/s/36fe4216/a2.htm" rel="nofollow external" class="bo"><img src="http://da.feedsportal.com/r/186530526402/u/0/f/640387/c/34625/s/36fe4216/a2.img" style="max-width: 100%; height: auto;"></a>
    </div>
]]>
</Body>
<Summary>James R. Clapper Jr., the director of national intelligence, said the technology was not yet fully in place to prevent another insider from stealing top-secret data, as Edward J. Snowden did.      </Summary>
<Website>http://www.nytimes.com/2014/02/12/us/politics/spy-chief-says-snowden-took-advantage-of-perfect-storm-of-security-lapses.html?partner=rss&amp;emc=rss</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/41261/guest@my.umbc.edu/ebb22cf0e5a7fee796472d3b024a441e/api/pixel</TrackingUrl>
<Tag>booz-allen-hamilton-holding-corp-bah-nyse</Tag>
<Tag>clapper-james-r-jr</Tag>
<Tag>computers-and-the-internet</Tag>
<Tag>espionage-and-intelligence-services</Tag>
<Tag>national-security-agency</Tag>
<Tag>new</Tag>
<Tag>senate-committee-on-armed-services</Tag>
<Tag>snowden-edward-j</Tag>
<Tag>technology</Tag>
<Tag>york</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Tue, 11 Feb 2014 21:50:03 -0500</PostedAt>
</NewsItem>

</News>
