text:
# propuesta-de-investigacion

A repository for my course on writing research proposals, and learning about skills that would improve my applications for tenure-track faculty positions (i.e., assistant professor positions).

## Organization of the Repository

+ docs
	- LICENSE: MIT License for this repository.
+ homework
	- 1st-assignment
		* Files for a set of *LaTeX* presentation slides, for my presentation to
			provide the course instructor, Prof. Zhijian Pei, and my classmates
			information about me.
	- last-assignment
		* LaTeX source code for a set of *LaTeX* presentation slides, for
			my presentation about what I have learned in the class, and what
			I want others to remember about me and know.
		* [Shortcut to slides](https://github.com/eda-ricercatore/propuesta-de-investigacion/blob/master/homework/last-assignment/homework-assignment-13-zhiyang-ong.pdf)
		* [Backup slides](https://drive.google.com/file/d/1D9op2K9DUeetltOa8kvk6CpbIZ-CPZop/view?usp=sharing)

#	Author Information

The MIT License (MIT)

Copyright (c) <2016> Zhiyang Ong

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Email address: echo "cukj -wb- 23wU4X5M589 TROJANS cqkH wiuz2y 0f Mw Stanford" | awk '{ sub("23wU4X5M589","F.d_c_b. ") sub("Stanford","d0mA1n"); print $5, $2, $8; for (i=1; i<=1; i++) print "6\b"; print $9, $7, $6 }' | sed y/kqcbuHwM62z/gnotrzadqmC/ | tr 'q' ' ' | tr -d [:cntrl:] | tr -d 'ir' | tr y "\n"		Don't compromise my computing accounts. You have been warned.


text:
Gluegun provides a builder that lets you initialize and configure Gluegun to work with your CLI. It lets you load & execute commands, extensions, and plugins.

_Note: Check out the [sniff](./sniff.md) module for detecting if your environment is able to run._

Here's a kitchen sink version, which we're about to cover.

```js
const { build } = 'gluegun'

const cli = build('movie')
  .src(__dirname)
  .plugin('~/.movie/movie-imdb')
  .plugins('./node_modules', { pattern: 'movie-' })
  .help()
  .version()
  .defaultCommand()
  .command({ name: 'hi', run: toolbox => toolbox.print.info('hi!') })
  .exclude(['filesystem', 'semver', 'system', 'prompt', 'http'])
  .checkForUpdates(5) // check for updates randomly about 5% of the time
  .create()

await cli.run()
```

## build

Grab the `build` function from `gluegun`.

```js
const { build } = require('gluegun')
```

Now let's build a `gluegun` cli environment by configuring various features.

```js
const cli = build('mycli')
```

The `mycli` brand that you pass into `build` is used through-out gluegun for things like configuration file names and folder names for plugins. You can also set it later, like this:

```js
const cli = build().brand('movie')
```

Out of the box, this CLI does very little. And by very little I mean nothing. So let's configure this. We'll be chaining the `build()` function from here.

## src

This sets where the default commands and extensions are located, in
`commands` and `extensions` folders, respectively.

```js
const cli = build('movie').src(__dirname)
```

When you run a command, it'll first load extensions in this folder and then check the commands in this folder for the right command.

```sh
# run a command with arguments
$ movie actors Kingpin

# run a command with arguments & options
$ movie producers "Planes, Trains, & Automobiles" --sort age
```

## plugin

Additional functionality can be added to the `gluegun` object with [plugins](./plugins.md). Plugins can be yours or your users.

_Hint: `src` and `plugin` are almost identical under the hood. The only thing they do differently is `src` will be loaded first and be the "default plugin"._

A plugin is a folder (or, more often, an NPM package) that contains a structure - something like this:

```
movie-credits
  commands
    actors.js
    producers.js
  extensions
    retrieve-imdb.js
  templates
    actor-view.js.ejs
  movie.config.js
```

You can load a plugin from a directory:

```js
const cli = build('movie')
  .src(__dirname)
  .plugin('~/.movie/movie-imdb')
```

## plugins

You can also load multiple plugins within a directory.

```js
const cli = build('movie')
  .src(__dirname)
  .plugin('~/.movie/movie-imdb')
  .plugins('./node_modules', { pattern: 'movie-' })
```

`plugins` supports a `fs-jetpack` [matching pattern](https://github.com/szwacz/fs-jetpack#findpath-searchoptions) so you can filter out a subset of directories instead of just all.

```js
  .plugins('./node_modules', { matching: 'movies-*' })
```

If you would like to keep plugins hidden and not available at the command line:

```js
  .plugins('./node_modules', { matching: 'movies-*', hidden: true })
```

When plugins are hidden they can still be run directly from the cli.

## help

Gluegun ships with a somewhat adequate `help` screen out of the box. Add it to your
CLI easily by calling `.help()`.

```js
const cli = build('movie')
  .src(__dirname)
  .plugins('./node_modules', { pattern: 'movie-' })
  .plugin('~/.movie/movie-imdb')
  .help()
```

You can also pass in a function or command object here:

```js
  .help(toolbox => toolbox.print.info('No help for you!'))
  .help({
    name: 'help',
    alias: 'helpmeplease',
    hidden: true,
    dashed: true,
    run: toolbox => toolbox.print.info('No help for you!')
  })
```

## version

You usually like to be able to run `--version` to see your CLI's version from the command
line, so add it easily with `.version()`.

```js
const cli = build('movie')
  .src(__dirname)
  .plugins('./node_modules', { pattern: 'movie-' })
  .plugin('~/.movie/movie-imdb')
  .help()
  .version()
```

Just like `help` above, you can pass in a function or command object to configure it further.

## defaultCommand

If the user runs your CLI and doesn't supply any matching parameters, it'll run this command
instead. Note that you can do this by supplying a `<brand>.js` file in your `./commands`
folder as well.

```js
const cli = build('movie')
  .src(__dirname)
  .plugins('./node_modules', { pattern: 'movie-' })
  .plugin('~/.movie/movie-imdb')
  .help()
  .version()
  .defaultCommand()
```

Just like `help` and `version` above, you can pass in a function or command object if
you prefer more control.

## command

If you want to pass in commands directly to the runtime builder, you can do that with `.command()`.

```js
const cli = build('movie')
  .src(__dirname)
  .plugins('./node_modules', { pattern: 'movie-' })
  .plugin('~/.movie/movie-imdb')
  .help()
  .version()
  .defaultCommand()
  .command({ name: 'hi', run: toolbox => toolbox.print.info('hi!') })
```

In this case, if you ran `movie hi`, it would run the function provided and print out 'hi!'.

You must provide an object with at least a `name` and a `run` function, which can be
`async` or regular.

## exclude

If you don't need certain core extensions, you can skip loading them (thus improving startup time) by using `.exclude()`. Just pass in an array of string names for the core extensions you don't need.

```js
const cli = build('movie').exclude([
  'meta',
  'strings',
  'print',
  'filesystem',
  'semver',
  'system',
  'prompt',
  'http',
  'template',
  'patching',
])
```

If you find you need one of these extensions for just _one_ command but don't want to load it for _all_ of your commands, you can always load it separately from the Gluegun toolbox, like this:

```js
const { prompt } = require('gluegun')
// or
const { prompt } = require('gluegun/prompt')
```

For reference, the core extensions that incur the biggest startup performance penalty are (timing varies per machine, but this gives some sense of scale):

```
prompt +100ms
print +45ms
http +30ms
system +10ms
```

_Note about TypeScript and `exclude`:_ Please note that the TypeScript type `GluegunToolbox` (as of Gluegun 2.1.x) always assumes that core extensions are included, even if you excluded them in the builder. In this case, it's recommended that you create your own `FooToolbox` (or similar) and update the interface to match your preferred configuration. Example:

```typescript
// wherever your types are, say, `./src/types.ts`
import { GluegunToolbox } from 'gluegun'
export interface FooToolbox extends GluegunToolbox {
  prompt: null
  print: null
  http: null
  system: null
}

// in a command
import { FooToolbox } from '../types'
module.exports = {
  run: async (toolbox: FooToolbox) => {
    // ... use toolbox with your excluded extensions
  },
}
```

## checkForUpdates

This allows you to check for updates every so often. Because we don't track how often your CLI is run, instead, we allow you to set a percentage chance of checking for updates. We recommend somewhere between 1-20, depending on how often your CLI is run. If you want to run it every time, set it to 100.

```js
const cli = build('movie')
  .src(__dirname)
  .plugins('./node_modules', { pattern: 'movie-' })
  .plugin('~/.movie/movie-imdb')
  .help()
  .version()
  .defaultCommand()
  .command({ name: 'hi', run: toolbox => toolbox.print.info('hi!') })
  .checkForUpdates(5)
```

## create

At this point, we've been configuring our CLI. When we're ready, we call `create()`:

```js
const cli = build('movie')
  .src(__dirname)
  .plugins('./node_modules', { pattern: 'movie-' })
  .plugin('~/.movie/movie-imdb')
  .help()
  .version()
  .defaultCommand()
  .command({ name: 'hi', run: toolbox => toolbox.print.info('hi!') })
  .checkForUpdates(5)
  .create()
```

This command applies the configuration that you were just chaining, and turns it into a `runtime cli` which supports calling `run()`.

And now we're ready to run:

```js
cli.run()
```

With no parameters, `gluegun` will parse the command line arguments looking for the command to run.

```sh
# list the plugins
$ movie

# run a command
$ movie quote

# run a command with options
$ movie quote --funny

# run a command with arguments
$ movie actors Kingpin

# run a command with arguments & options
$ movie producers "Planes, Trains, & Automobiles" --sort age
```

## run

`gluegun` can also be `run()` with options.

```js
await cli.run('quote random "*johnny"', {
  funny: true,
  genre: 'Horror',
  weapon: 'axe',
})
```

There's a few situations that make this useful.

1.  Maybe you like to use `meow` or `commander` to parse the command line.
2.  Maybe your interface isn't a CLI.
3.  Maybe you want to run several commands in a row.
4.  Maybe this is your program and you don't like strangers telling you how to code.

Bottom line is, you get to pick. It's yours. `gluegun` is just glue.

## configuration

Each plugin can have its own configuration file where it places defaults. These defaults can then be overridden by reading defaults from a configuration file or entry in `package.json`. We use [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) for this.

It will read the plugin name from the `name` key and the defaults will be read from the `defaults` section. Each section underneath `default` can be used to override the sections of the plugin. Since that was horribly explained, here's an example.

```js
// in movies.config.js
module.exports = {
  name: 'movies',
  defaults: {
    movie: {
      cache: '~/.movies/cache',
    },
    another: {
      count: 100,
    },
  },
}
```

license: MIT

repository: infinitered/gluegun

branch_name: refs/heads/master

extension: md

gha_language: TypeScript

gha_license_id: MIT

license_type: permissive

repo_name: infinitered/gluegun


text:
---
layout: post
title: "Sync your React Native SQLite database between devices with Dropbox"
date: 2018-12-05 22:01
comments: true
tags: [React Native, SQLite, TypeScript, Dropbox, mobile, apps]
published: true
---
In the previous two posts we have bootstrapped a React Native project [with TypeScript and CocoaPods](/blog/2018/10/12/react-native-typescript-cocoapods/), and then integrated an SQLite plugin to enable [storing relational data on-device](/blog/2018/11/06/react-native-offline-first-db-with-sqlite/). Next, let's take a look at using the Dropbox HTTP API to backup our database and enable synchronization between devices. We’ll begin by walking through support for the Dropbox v2 authorization flow in a React Native app, and then use the token we are granted to enable synchronization of our database file via the Dropbox `files` HTTP endpoints.

![Demo app settings screen showing that the user has linked their Dropbox account]({{ site.baseurl }}/images/react-native/dropbox-sync/linked_with_dropbox.png)

This post is accompanied by a fully-functional demo app that illustrates the approach:

[github.com/blefebvre/react-native-sqlite-demo](https://github.com/blefebvre/react-native-sqlite-demo)

## Goal

When I began looking into this topic, my goal was to provide a way to backup and sync my user's data _without_ storing it on a server that I would need to implement (and maintain). I envisioned a use case where my app could be installed on more than one device (say, a user's iPhone and iPad), and up-to-date data would be available on each device. While the app would depend on an internet connection to support this feature, it was important to me that the app continue to work "offline first" in the absence of connectivity.

At a high level, my concept for the overall experience looked like this:

* App is installed on an end user's device.
* User inputs data into the app, and wishes to have a backup of their work.
* User authorizes with the Dropbox API. A token is granted to the app.
* App uses this token to upload the database file to Dropbox.
* App is installed by the same end user onto another device, such as an iPad.
* On the iPad now, the user authorizes with Dropbox and is granted another token.
* The app checks if a database file exists already on Dropbox.
* Since it does, the user is prompted to replace their local database with the Dropbox copy.
* Later on, each time the app starts up, the Dropbox API will be queried for the last updated timestamp of the database file.
* If the remote copy is newer than the device's DB, the user will be prompted to download it and overwrite their local DB.
* On each subsequent write to the database, the database file will be sent to Dropbox via the HTTP API.

As a bonus: Dropbox keeps revision history for each file, so this approach would enable the user to go back in time to a previous version of their database, without requiring any additional code in the app to support this!

Like the other posts in this series, I am going to focus on iOS for any platform-specific configuration that is required.

## Getting started

If you search for "react native dropbox" on Google, as I did, you may be encouraged by the number of relevant-looking results that are returned. However, digging a bit deeper will reveal a number of GitHub repos with big deprecation warnings, as well as some all-in-one authentication solutions which seemed overkill for what I was trying to do.

The approach below details how you can use the Dropbox API without installing any additional auth-related SDKs or packages.

The first step is to create an App on Dropbox's developer page. Head to [dropbox.com/developers](https://www.dropbox.com/developers), and follow the "Create your app" link to begin.

![Dropbox new app wizard settings]({{ site.baseurl }}/images/react-native/dropbox-sync/dropbox-create-app.png)

For "1. Choose an API", select "Dropbox API".

For "2. Choose the type of access you need", select "App folder".

For "3.  Give it a relevant name for your project.

Click "Create app" to proceed.

## Dropbox app console settings

You should now be looking at the Dropbox [app console](https://www.dropbox.com/developers/apps) entry for your new app. There are a few settings which we'll update here before we get into the code.

First, make note of your `App key`. We will need this value later on when constructing the request to authenticate from our React Native app. We will not need `App secret` for this use case.

Next, in the OAuth2 section, add a new Redirect URI in the following format:

    unique.id.for.your.app://oauthredirect

For example, I have used `com.brucelefebvre.rnsqlitelistapp.oauth://oauthredirect` for my [demo list app](https://github.com/blefebvre/react-native-sqlite-demo). Later on, we'll need to set this id (the part before `://oauthredirect`) as one of the `CFBundleURLSchemes` that our iOS app will respond to, so we can receive the token from Dropbox once our end user has granted the app permission.

Tap "Add" to add your Redirect URI.

With that, we're ready to roll as far as the Dropbox app console is concerned. Before going live you will want to make sure you come back to this page and update your app's branding with an icon, app description, publisher details, and a link to your app's website.

## React Native project setup

There are a number of ways that Dropbox could be integrated into a React Native app; what follows is merely my suggestion. This approach has worked well for me in the small side project app I shipped earlier this year. That said, I'd be interested to hear any thoughts you have on this approach in the comments.

There are a few 3rd party dependencies that I've added to help with various aspects of this feature, including:

- [react-native-fs](https://www.npmjs.com/package/react-native-fs): for dealing with the filesystem
- [rn-fetch-blob](https://www.npmjs.com/package/rn-fetch-blob): uploading and downloading remote files in an efficient manner
- [moment](https://www.npmjs.com/package/moment): working with timestamps
- [react-native-restart](https://www.npmjs.com/package/react-native-restart): reloading the app
- [shitty-qs](https://www.npmjs.com/package/shitty-qs): parsing query strings

These can all be added with the following command:

    npm install --save react-native-fs rn-fetch-blob moment react-native-restart shitty-qs

The libraries that include native code need to be linked up to our Xcode project, so we'll add three lines to our `ios/Podfile` (Where, exactly? Check out the [complete Podfile](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/ios/Podfile#L15)):

    pod 'RNFS', :path => '../node_modules/react-native-fs'
    pod 'rn-fetch-blob', :path => '../node_modules/rn-fetch-blob'
    pod 'RCTRestart', :path => '../node_modules/react-native-restart/ios'

Next, install the new Pods:

    cd ios/
    pod install

For the complete TypeScript experience, let's install type definitions for the dependencies we just added:

    npm install --save @types/react-native-fs

A keen eye will note that we're only installing types for 1 of the 5 dependencies we installed above. Well, lucky for us, `moment` includes TypeScript support in it's main npm package. `rn-fetch-blob` has a merged [pull req](https://github.com/joltup/rn-fetch-blob/pull/184) to include a type definition in it's package, but it's not been released to npm at the time of writing.

If you're _really_ a TypeScript keener, as I am, you can take the not-yet-released index.d.ts [from master](https://github.com/joltup/rn-fetch-blob/blob/master/index.d.ts) and create the corresponding file in your project's `node_modules/rn-fetch-blob/` directory. Note that since this directory _should be_ ignored by source control, taking this action will not benefit anyone else on your team, and will get overwritten if you install a new version of `rn-fetch-blob` later on.

![TypeScript support for rn-fetch-blob showed off in VS Code]({{ site.baseurl }}/images/react-native/dropbox-sync/rn-fetch-blob-types.png)

Much better! Are you new to Cocoapods or TypeScript? I wrote a little post on bootstrapping a React Native project with both tools wired up: [Get started with React Native, TypeScript, and CocoaPods](/blog/2018/10/12/react-native-typescript-cocoapods/)

## iOS project configuration

On the iOS project side, we need to ensure we have the `RCTLinkingIOS` React Cocoapod subspec included in our Podfile (which the demo app [already does](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/ios/Podfile#L8)), as well as a bit of Objective-C code added to `AppDelegate.m` to support handling deep links into our app. The official React Native docs have details on the code snippet that you'll need to [handle deep links](https://facebook.github.io/react-native/docs/linking#handling-deep-links) (immediately below the paragraph that states, "If you also want to listen to incoming app links during your app's execution...").

Our app needs to know which URL schemes to respond to. With our project's `*.xcworkspace` file opened in Xcode, open the app's properties editor and navigate to the Info tab. Here you will find the "URL Types" setting. Add a new item with the "URL Schemes" field set to the Redirect URI `id` value you chose during the Dropbox app console setup above (`com.brucelefebvre.rnsqlitelistapp.oauth` in my demo app's case):

![Xcode properties page for handling deep links]({{ site.baseurl }}/images/react-native/dropbox-sync/deep_links_xcode_setup.png)

For more detail on this step, check out the "Register Your URL Scheme" section of the [Apple dev docs](https://developer.apple.com/documentation/uikit/core_app/allowing_apps_and_websites_to_link_to_your_content/defining_a_custom_url_scheme_for_your_app).

And with that, we're ready to get into the code.

## Authorizing with Dropbox

In an attempt to keep this post readable, I am going to keep the code that I embed to a minimum and link to my (fully functional) [demo app](https://github.com/blefebvre/react-native-sqlite-demo) whenever possible.

Before we can sync anything with Dropbox we will need our user's permission to do so. I've broken down the sync-related code into two interfaces in the demo app: [Authorize](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/sync/Authorize.ts) and [DatabaseSync](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/sync/DatabaseSync.ts). I attempted to keep these interfaces generic enough that another backend could replace the Dropbox implementation, if ever needed. You'll find the Dropbox implementation of these interfaces in the `src/sync/dropbox/` directory.

The `Authorize` interface defines 3 functions: one to authorize, one revoke the app's token, and one to query if the user has already authorized:

<!--
{% highlight js %}

{% endhighlight %}
-->

{% highlight js %}
export interface Authorize {
  authorize(): Promise<void>;
  revokeAuthorization(): Promise<void>;
  hasUserAuthorized(): Promise<boolean>;
}
{% endhighlight %}

In the Dropbox implementation, the `authorize` function opens the device's browser to [dropbox.com/oauth2/authorize](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/sync/dropbox/DropboxConstants.ts#L7) complete with our app's [client_id](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/sync/dropbox/DropboxAuthorize.ts#L33) (generated by Dropbox above), redirect_uri, a requested response type (`token`), and a randomly generated `state` value included as query parameters.

_Aside!_ Why is this optional `state` value included? From the [Dropbox API docs](https://www.dropbox.com/developers/documentation/http/documentation#authorization): [state can contain] "Up to 500 bytes of arbitrary data that will be passed back to your redirect URI. This parameter should be used to protect against cross-site request forgery (CSRF)." In other words, it enables us to verify if the deep link response from Dropbox is the one we are expecting, as opposed to a malicious user crafting a link that opens up our app with a Dropbox token that links to _another_ account. I highly recommend that you make use of it in your implementation as well.

Once the user indicates they would like to link their Dropbox account (perhaps by tapping a button in the app), a web browser will open up to dropbox.com and either ask them to sign in, or take them right to the authorization step (if already signed in). How this page looks can be configured in the Dropbox app console to include your app's logo and other metadata:

![Authorize step on dropbox.com]({{ site.baseurl }}/images/react-native/dropbox-sync/authorize_on_dropbox.png)

Let's take a closer look at the Dropbox implementation in the demo list app, in [DropboxAuthorize.ts](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/sync/dropbox/DropboxAuthorize.ts#L29). The React Native `Linking.openURL()` call returns a Promise which, once resolved, we attach a listener to the "uri" type (using `Linking.addEventListener()`). This enables our app's JS code to be notified when the app is opened with a deep link that matches the URL Scheme we specified in Xcode.

With this logic in place, and our Xcode project configured correctly, the user will see a dialog like this asking if they would like to be taken back to our app once they tap the blue "Allow" button:

![Authorize step on dropbox.com, step 2 where the user is asked to open back up our app]({{ site.baseurl }}/images/react-native/dropbox-sync/open_in_app.png)

As "Open" is tapped, our Linking event listener callback will fire. In [this function](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/sync/dropbox/DropboxAuthorize.ts#L117), we then parse the deep link's query string, ensure that our `state` value matches what was passed back to the app, and lastly record the Dropbox access token and account ID values that were granted to us in `AsyncStorage`.

## When to authorize?

In both my side project app and the [SQLite list demo](https://github.com/blefebvre/react-native-sqlite-demo), authorizing with Dropbox is an optional step. Therefore, I did not include it in the app onboarding, and instead tucked it away in a settings screen. Your apps requirements may vary!

The settings screen I am describing is named [SettingsModal.tsx](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/components/SettingsModal.tsx) and provides a button to kick off the authorization flow. Once authorized, the text and button change to enable the user to unlink the app from Dropbox.

I bring up this screen because it is also the first time that an authorized app will interface with Dropbox. If this is the 2nd (or 3rd, 4th, etc.) device that this same Dropbox user is linking to their account, we need to provide the option to overwrite the local database with the version that is available in their account:

![Prompt on-device to see if the user would like to replace their local DB with the Dropbox copy]({{ site.baseurl }}/images/react-native/dropbox-sync/replace_local_db.png)

The code to support this check is of interest to the next piece of the puzzle: `DatabaseSync.ts`.

## Syncing a database file

As with the authorization code, I have included a TypeScript interface in the demo app to define how a database sync implementation would look:
[DatabaseSync.ts](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/sync/DatabaseSync.ts):

{% highlight js %}
export interface DatabaseSync {
  upload(): Promise<void>;
  download(): Promise<void>;
  hasSynced(): Promise<boolean>;
  hasRemoteUpdate(): Promise<boolean>;
  hasLastUploadCompleted(): Promise<boolean>;
}
{% endhighlight %}

#### hasRemoteUpdate()

The Dropbox implementation of `hasRemoteUpdate()` is a good place to jump in to the sync code since it will be our first call to the Dropbox API, post-authorization. And it's relatively simple. From [DropboxDatabaseSync.ts](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/sync/dropbox/DropboxDatabaseSync.ts#L72):

{% highlight js %}
public hasRemoteUpdate(): Promise<boolean> {
    // [ Code omitted to check connectivity, and determine path of remote file ]
    return fetch(DROPBOX.GET_METADATA_URL, {
        method: "POST",
        headers: {
            Authorization: `Bearer ${dropboxAccessToken}`,
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            path: dropboxFilePath
        })
    }).then(response => {
        // [ Code omitted to process response and compare to last uploaded timestamp ]
    });
}
{% endhighlight %}

The key bits to note are that we are making a standard `fetch` call in this function, and must include `Bearer <Dropbox access token>` as the `Authorization` header value. Including this token will be required for all future interactions with the Dropbox API.

#### upload()

When the app is initially linked to a user's Dropbox account, there will be no existing database file present. The first step in this case is to perform the first upload of the database. The code which performs this upload is the `upload` function in [DropboxDatabaseSync.ts](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/sync/dropbox/DropboxDatabaseSync.ts#L23).

The `upload` code can be broken down into 2 distinct operations. First, the connection to the DB is closed and a [copy of the database file](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/sync/dropbox/DropboxDatabaseSync.ts#L46) is made, from `FILE_NAME` to `BACKUP_FILE_NAME` (defined in src/database/[Constants.ts](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/database/Constants.ts#L6)). I use the [react-native-fs](https://www.npmjs.com/package/react-native-fs) package to efficiently handle deleting the previous backup file and creating the new copy. Once complete the database is reopened and the `upload()` function's Promise is resolved.

_Why is the Promise resolved already? The upload hasn't even begun yet!_ Sticking with the offline first approach, I need to avoid blocking the UI while waiting for an upload to complete. Since mobile networks can be unreliable -- for example, reporting connectivity but not supporting enough bandwidth to actually do anything -- I took the approach that the upload should happen in the background. With this approach I do the minimum amount of work necessary while the database is closed (the copy operation), and then kick off the upload after the fact.

The 2nd part of the upload is the actual file upload. In order to support efficient binary file transfers I have incorporated the [rn-fetch-blob](https://www.npmjs.com/package/rn-fetch-blob) package, which avoids the Base64 bridging typically needed for file access in React Native. I found this the best way to actually upload content to Dropbox, after a number of failed attempts of uploading without it (related [issue](https://github.com/facebook/react-native/issues/14445) and [post](https://www.dropboxforum.com/t5/API-Support-Feedback/The-Dropbox-API-V2-not-compatible-with-React-Native/td-p/226203) on the subject).

The key piece of this operation is the call to `RNFetchBlob.fetch()` in the [uploadDBToDropbox()](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/sync/dropbox/DropboxDatabaseSync.ts#L381) function:

{% highlight js %}
RNFetchBlob.fetch(
    "POST",
    DROPBOX.UPLOAD_URL,
    {
        Authorization: `Bearer ${dropboxAccessToken}`,
        "Content-Type": "application/octet-stream",
        "Dropbox-API-Arg": JSON.stringify({
            path: dropboxFilePath,
            mode: "overwrite"
        })
    },
    RNFetchBlob.wrap(localFilePath)
)
{% endhighlight %}

Note that we're "wrapping" the path to our local DB backup file, and that we're not using the standard `fetch` call but instead using the one provided by `RNFetchBlob`.

#### download()

If our hypothetical user were to then install our app on another device and link it to the same Dropbox account, the initial call to `hasRemoteUpdate()` would return `true`. The user would then be prompted to replace their local database with the version from Dropbox. Upon their agreement, the `download()` function would be called.

Like upload, this function also makes use of the [rn-fetch-blob](https://www.npmjs.com/package/rn-fetch-blob) package. The key piece of code that performs the download looks as follows, and can be found in [DropboxDatabaseSync.ts](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/sync/dropbox/DropboxDatabaseSync.ts#L200):

{% highlight js %}
RNFetchBlob.config({
    // Downloaded DB will be saved to this path
    path: this.getLocalDBFilePath()
}).fetch("POST", DROPBOX.DOWNLOAD_URL, {
    Authorization: `Bearer ${accessToken}`,
    "Dropbox-API-Arg": JSON.stringify({
        path: this.getDropboxFolder() + this.getDatabaseBackupName()
    })
})
{% endhighlight %}

The last important step of this process is to record the timestamp that we received as part of the response from Dropbox:

{% highlight js %}
// Store client modified value (contained in clientModifiedString)
return AsyncStorage.setItem(
    DROPBOX.MOST_RECENT_BACKUP_TIMESTAMP_KEY,
    clientModifiedString
);
{% endhighlight %}

If, for whatever reason, we do not complete the `download()` call, this timestamp will not be recorded and the download will be attempted again the next time the app is launched. Speaking of `DROPBOX.MOST_RECENT_BACKUP_TIMESTAMP_KEY` (one of the [DropboxConstants](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/sync/dropbox/DropboxConstants.ts#L16))...

#### hasSynced()

This function will simply check for a value stored in AsyncStorage at the `DROPBOX.MOST_RECENT_BACKUP_TIMESTAMP_KEY` key. It is a helper function to enable the [DatabaseSynchronizer](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/database/DatabaseSynchronizer.ts) class to determine if it needs to bother checking for an update at all.

#### hasLastUploadCompleted()

Another helper function. Like `hasSynced()`, a call to this function will check the value of a key in AsyncStorage. If `DROPBOX.LAST_UPDATE_STATUS_KEY` is set to the value of `DROPBOX.UPDATE_STATUS_FINISHED`, true will be resolved. If the key is unset or set to any other value, the function will resolve false.

This function is called from the `DatabaseSynchronizer` class [reconcileDatabaseChanges()](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/database/DatabaseSynchronizer.ts#L35) function. If it returns `false`, then we know that the previous upload to Dropbox never completed. Therefore, assuming there was not a conflicting change made to the Dropbox file from another device, we will attempt the upload again.

## Triggering an upload

The action that triggers an upload of the database to Dropbox is completely up to you. It can be a manual step, or it can happen each time the database is written to. The latter approach is the one I have taken with the demo list app.

To implement the upload-on-each-write approach, I have added a `databaseSync.upload()` call to the end of each of the Database functions which INSERTs, UPDATEs, or DELETEs data. For an example, check out [Database.ts](https://github.com/blefebvre/react-native-sqlite-demo/blob/dropbox-sync/src/database/Database.ts#L84).

{% highlight js %}
    // Queue database upload
    return this.databaseSync.upload();
{% endhighlight %}

Since all of the database functions already return a `Promise`, it was simple to add this call right at the end of each function's existing Promise chain. You'll recall from above that the `upload()` call briefly closes the database, but it's Promise chain will resolve immediately after the copy is complete and the database is reopened; it does not wait for the upload itself to complete.

## Downsides to this approach

This approach has worked well for me, but it is not going to work for _many_ apps. Perhaps most apps. Apps that would not be good candidates for this approach would likely have one or more of the following characteristics:

- Require frequent database writes that occur in quick succession (for example, an app that records location data a few times per second)
- Contain a large database. Since we back up the entire database on each save, this approach does not make sense when the database is big.
- Require sharing data with other users of the app. The database is self-contained on device, so there is no way to have a relationship with another user's data.

## In conclusion

I hope this post has shed some light on how I was able to implement an SQLite database sync feature in a React Native app without supporting a server of my own. I welcome any thoughts or questions you have on the approach I have taken.

If you would like to see this code in action, I recommend checking out the demo app that I have been referencing throughout this post. It is completely functional out-of-the-box on iOS (includes my sample Dropbox client ID generated above). You can check it out on GitHub here:

[github.com/blefebvre/react-native-sqlite-demo](https://github.com/blefebvre/react-native-sqlite-demo)

_What's next, Bruce?_ I have a post in the works on component & end-to-end testing, and plan to cover the process of updating to the latest React Native release shortly after that.

branch_name: refs/heads/gh-pages

extension: markdown

gha_language: JavaScript

gha_license_id: NOASSERTION


text:
---
layout: default
---

# 1995-09-20 - Re: My Day

## Header Data

From<EMAIL_ADDRESS>(Mike McNally)

To: Bill Sommerfeld<EMAIL_ADDRESS>Message Hash: 5de5f935b1fdb49c2962cffc1bd9223f009bebabc6975756f92c5289a9ce7b0b

Message ID: \<9509201248.AA09892@alpha\>

Reply To<EMAIL_ADDRESS>UTC Datetime: 1995-09-20 12:49:32 UTC

Raw Date: Wed, 20 Sep 95 05:49:32 PDT

## Raw message

```
{% raw  %}From<EMAIL_ADDRESS>(Mike McNally)
Date: Wed, 20 Sep 95 05:49:32 PDT
To: Bill Sommerfeld<EMAIL_ADDRESS>Subject: Re: My Day
In-Reply-To<EMAIL_ADDRESS>Message-ID: <9509201248.AA09892@alpha>
MIME-Version: 1.0
Content-Type: text/plain

Bill Sommerfeld writes:
 > >   the second 32bit seed is the "tick count", which I'm told is the number of
 > > milliseconds since windows started.
 >
 > A 32-bit ms-resolution counter wraps roughly every 50 days.  Very few
 > Windoze PC's stay up that long :-).

Also (and note that it's been a while since I've messed around with
PC's, but since the "architecture" remains chained to an early-80's
design I suspect they're still the same) the PC clock frequency is
generally pretty low.  PC UNIX implementations usually run it at about
100 Hz, I think.  There aren't a lot of available timers on the PC.
One of them used to be used as the DRAM refresh timer; I don't know
whether they still do that.

On the other hand, getting at a Windows PC over the network is a whole
'nuther enchilada, though if I want to keep my day job I need to get
that figured out real soon now.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Nobody's going to listen to you if you just | Mike McNally<EMAIL_ADDRESS>|
| stand there and flap your arms like a fish. | Tivoli Systems, Austin TX    |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

{% endraw %}
```

## Thread

+ Return to [September 1995](/archive/1995/09)

+ Return to "[Bill Sommerfeld <sommerfeld@orchard.medford.ma.us>](/authors/bill_sommerfeld_sommerfeld_at_orchard_medford_ma_us_)"
+ Return to "["Ed Carp [khijol SysAdmin]" <khijol!erc>](/authors/ed_carp_khijol_sysadmin_khijolerc_)"
+ Return to<EMAIL_ADDRESS>(Ian Goldberg)](/authors/iagoldbe_at_csclub_uwaterloo_ca_ian_goldberg_)"
+ Return to<EMAIL_ADDRESS>(Jeff Weinstein)](/authors/jsw_at_neon_netscape_com_jeff_weinstein_)"
+ Return to<EMAIL_ADDRESS>(Mike McNally)](/authors/m5_at_dev_tivoli_com_mike_mcnally_)"
+ Return to "["Perry E. Metzger" <perry@piermont.com>](/authors/perry_e_metzger_perry_at_piermont_com_)"
+ Return to<EMAIL_ADDRESS>(Richard Todd)](/authors/rmtodd_at_servalan_servalan_com_richard_todd_)"
+ Return to "[sameer <sameer@c2.org>](/authors/sameer_sameer_at_c2_org_)"
+ Return to "["W. Kinney" <kinney@bogart.Colorado.EDU>](/authors/w_kinney_kinney_at_bogart_colorado_edu_)"

+ 1995-09-20 (Tue, 19 Sep 95 21:09:35 PDT) - [My Day](/archive/1995/09/98609761b523f2974d6d4ddbb5bb61eb1a25989e6533e2241195b723bf394e5c) -<EMAIL_ADDRESS>(Ian Goldberg)_
  + 1995-09-20 (Wed, 20 Sep 95 03:38:58 PDT) - [Re: My Day](/archive/1995/09/2c5bff3c8b306e08b2e73b53b362e5d1ff03bf62c6575497c0b0971a04050b29) -<EMAIL_ADDRESS>(Jeff Weinstein)_
    + 1995-09-20 (Wed, 20 Sep 95 05:25:33 PDT) - [Re: My Day](/archive/1995/09/3f48fc48c84f03328599aac7c792b7c01b0892e293303bff4325c5d3cf3a9e01) - _Bill Sommerfeld<EMAIL_ADDRESS>      + 1995-09-20 (Wed, 20 Sep 95 08:58:33 PDT) - [Re: My Day](/archive/1995/09/7ab2aee43e62e64c46918aeebac7014da0fa130263e2a4ff1547b5c1d8b26d8c) - _"Ed Carp [khijol SysAdmin]" \<khijol!erc\>_
        + 1995-09-20 (Wed, 20 Sep 95 09:48:46 PDT) - [Re: My Day](/archive/1995/09/c7c6aca2e74d58b8e5ed6ba7c64d221dc1c27789af82f066f3c8f60b4612ff08) - _"W. Kinney"<EMAIL_ADDRESS>          + 1995-09-20 (Wed, 20 Sep 95 10:11:43 PDT) - [Re: My Day](/archive/1995/09/927228003e5df6b06aa4067f8f631bc63c907258004642584768268a5c053a6d) - _sameer<EMAIL_ADDRESS>    + 1995-09-20 (Wed, 20 Sep 95 05:49:32 PDT) - Re: My Day -<EMAIL_ADDRESS>(Mike McNally)_
      + 1995-09-20 (Wed, 20 Sep 95 08:07:08 PDT) - [Re: My Day](/archive/1995/09/285da31081bfc895a5c6d295f462faed18ba0d4a769fc95c46582d338905cd1f) - _"Perry E. Metzger"<EMAIL_ADDRESS>    + 1995-09-20 (Wed, 20 Sep 95 10:30:18 PDT) - [Re: My Day](/archive/1995/09/a0d327e2352e47a674d5b400d6abff19fe63e91ee4d3d2b0bd135d1b98d93874) -<EMAIL_ADDRESS>(Richard Todd)_


text:
# Data Types

Programming can be thought of as consiting of 2 things:

1. Data
2. Operations on data

Everything else is just sugar.

Before continuing,
be sure to read [chapter 2](https://benlauwens.github.io/ThinkJulia.jl/latest/book.html#chap02) of _Think Julia_,
which introduces you to different kinds of values.

The next page will expect you do have read
[chapter 3](https://benlauwens.github.io/ThinkJulia.jl/latest/book.html#chap03),
which introduces you to the operations part (functions).

These chapters also introduce a number of important concepts like
variable assignment, expressions, flow of execution, and arguments.
All of these concepts will come up again and again,
so if you're still a bit fuzzy on them,
that's ok.

## Practice for Variables, Expressions and Statements

The following examples are intended to reinforce and extend what you've learned.
In many cases, they are intended to expose behavior that may be unintuitive,
or lead to errors that are worth understanding.

!!! warning "Checking Questions"
    1. For each of the following expressions,
       What is the `type` of the value that gets returned after execution?

       ```julia
       julia> 1+2
       3

       julia> 3 / 2
       1.5

       julia> "42 * 6"
       "42 * 6"

       julia> "42" * "6"
       "426"
       ```

    2. Assign each of these values to a different variable (eg `my_sum = 1+2`).
       And use the `typeof()` function to test your answers above.
       For example

       ```julia
       julia> x = "42" * "6"
       "426"

       julia> typeof(x)
       String
       ```

    3. What is the difference between the following expressions?

       ```julia
       julia> "AATTCC"^2
       "AATTCCAATTCC"

       julia> println("AATTCC"^2)
       AATTCCAATTCC
       ```

       What happens if you assign each of these expressions to a variable?

    4. What is the difference between `Float64` and `Int64`?

       Are there situations where one is obviously preferred over the other
       in a math problem?

    5. Without evaluating the following expressions,
       try to guess what the return type will be, `Int64` or `Float64`.

       ```julia
       julia> 1 + 1

       julia> 2. - 2.

       julia> 3 * 3.

       julia> 4. * 4

       julia> 5 / 5

       julia> "6" + "6.0"

       julia> 1e7 + 1
       ```

       Now evaluate them - did you get them right?
       use `typeof()` if you're not sure.

!!! tip
    When you are working with really big numbers such as `1,000,000`, do not include the commas if you want `julia` to recognize it as an integer. For example, if you were to run this code:

    ```julia
    julia> 1,000,000
    (1, 0, 0)
    ```

    you can see that `julia` thinks that `1,000,000` is a group of 3 integers (`1`, `0`, and `0`)!
    Instead, `julia` allows you to use underscores to break up large integers.

    ```julia
    julia> 1_000_000
    1000000
    ```

    !!! note
        But be careful! ["Overflow"](https://en.wikipedia.org/wiki/Integer_overflow)
        can occur when you try to use giant numbers.
        Watch:

        ```julia
        julia> 2^61
<PHONE_NUMBER>213693952

        julia> 2^62
<PHONE_NUMBER>427387904

        julia> 2^63
        -9223372036854775808

        julia> 2^64
        0
        ```

        What happened?
        Integers, like all types of data,
        are stored in memory as bits -
        sequences of `1`s and `0`s.
        In julia, the primary integer type is `Int64`,
        which uses 64 bits,
        63 of which are used for the magnitude,
        and one for the sign (`+` or `-`).

        The value `2^63` would require 65 bits
        to hold in memory.


text:
Android-FileLogger
============================

A general-purpose logging library with built-in support to save logs to file.

For performance concern, I/O operation is buffered and executed in background thread.

Usage
-----
```gradle
dependencies {
    compile 'com.github.bosphere.android-filelogger:filelogger:1.0.7'
}
```

Please refer to the sample app for more details.

```java
FL.init(new FLConfig.Builder(this)
        .logger(...)       // customise how to hook up with logcat
        .defaultTag("Default Tag")   // customise default tag
        .minLevel(FLConst.Level.V)   // customise minimum logging level
        .logToFile(true)   // enable logging to file
        .dir(directory)    // customise directory to hold log files
        .formatter(...)    // customise log format and file name
        .retentionPolicy(FLConst.RetentionPolicy.FILE_COUNT) // customise retention strategy
        .maxFileCount(FLConst.DEFAULT_MAX_FILE_COUNT)    // customise how many log files to keep if retention by file count
        .maxTotalSize(FLConst.DEFAULT_MAX_TOTAL_SIZE)    // customise how much space log files can occupy if retention by total size
        .build());

// overall toggle to enable/disable logging
FL.setEnabled(true);

// to log with default tag
FL.d("this is a debug message");

// to log with placeholder and interpolation
FL.d("this is a %s message", "debug");

// to log with specified tag
FL.d("Tag", "this is a %s message", "debug");

// to log exception
FL.e("Tag", throwable);
FL.e("Tag", throwable, "extra %s info", "debug");

```

Compatibility
-------------

API 9 (Android 2.3) and up

License
-------

Copyright 2018 Yang Bo

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


text:
---
layout: post
title: Tell Michael McCaul to Publicly Comment on Revised Travel Ban!
#meta-title: Let's Go See McCaul
subtitle: CALL TO ACTION – TELL MCCAUL TO GO ON THE RECORD ABOUT TRAVEL BAN ORDER!
#meta-description: CALL TO ACTION - February 20th - 24th, 2017
tags: [front,action-alert]
share-img: /img/site-logo-borderless.png
---
On Wednesday, in a ruling that applies nationally, a United States District Judge for the District of Hawaii issued an injunction against the Trump administration in its efforts to impose the latest travel ban Executive Order. As reported in The Washington Post, “In finding the ban violated the establishment clause, the court found ‘significant and unrebutted evidence of religious animus.’”

In Maryland, another federal District Judge also issued an order stopping the travel ban from going forward.

At a rally last night, Trump himself admitted that the revised order was simply a “watered-down version” of the first Executive Order.

Representative McCaul has stated,

>I have offered advice to President Trump on how to develop better, common-sense security checks for immigrants and refugees, and as the administration weighs next steps, I will press for responsible screening policies that keep Americans safe while upholding our values.

**CALL Congressman McCaul and ask him to PUBLICLY COMMENT on the revised travel ban.**

## SAMPLE SCRIPT
>Hello, my name is _____, and I am a constituent of Representative McCaul. I am calling to let the Representative know how distressed I am by the revised travel ban Executive Order. Mr. Trump himself stated that it was simply a “watered-down version” of the original order. Even this revision has been blocked by 2 United States district judges. Representative McCaul has stated that he offered advice to the President on how to develop better security checks. Did the President follow his advice? If not, then I would urge Representative McCaul to publicly comment on the flawed revision.

## ADDITIONAL RESOURCES
[Trump loses again on Muslim ban — and then makes it worse](https://www.washingtonpost.com/blogs/right-turn/wp/2017/03/16/trump-loses-again-on-muslim-ban-and-then-makes-it-worse/?utm_term=.946e925cab4b)
[Federal judge in Hawaii blocks new travel ban nationwide; Trump vows to pursue his case 'all the way](http://www.latimes.com/nation/la-na-travel-ban-court-20170315-story.html)
[2 Federal Judges Rule Against Trump’s Latest Travel Ban](https://www.nytimes.com/2017/03/15/us/politics/trump-travel-ban.html?_r=0)
[IN-DEPTH: Inside Trump's ‘Extreme Vetting,’ Temporary Halt On Immigrants From Jihadi Hotbeds; 'Not A Muslim Ban,' Officials Stress](http://www.hstoday.us/industry-news/general/single-article/in-depth-inside-trump-s-extreme-vetting-temporary-halt-on-immigrants-from-jihadi-hotbeds-not-a-muslim-ban-officials-stress/44701c1e32735855ef4c81f2b0716a87.html)

## CONTACT INFO:

**Rep. Michael McCaul**\\
D.C. office:<PHONE_NUMBER>\\
Austin office:<PHONE_NUMBER>\\
Katy office:<PHONE_NUMBER>\\
Tomball office:<PHONE_NUMBER>\\
Brenham office:<PHONE_NUMBER>

**#StandIndivisible**


text:
# debenstack-techblog

Dockerising of techblog stack

# Setup
1. Clone repository
2. Copy the `config.example.js` file within the repository. Rename to `config.js` and update with appropriate configs
3. Load for local development with `docker-compose up`

Note: that the `config.example.js` specifies what port and ip to listen on for the ghost blog stack. For docker the host must be `<IP_ADDRESS>`. For the port, make sure this maps correctly with docker and `docker-compose.yaml`

# Project Structure
| Folder | Description |
| ------ | ----------- |
| content | Contains assets and themes for the blog. See READMEs within these folders for more details |
| core | Core ghost functionality code |
| docs | Archive of README and other assorted data for the project |

# Debug Mode
To run the project in debug mode, giving more output etc. Edit the `startup.sh` script and remove the `--production` flag from the npm install command

repository: debenstack/debenstack-techblog

repo_name: debenstack/debenstack-techblog


text:
# DerivativeCalc-Cpp
A library to calculate derivatives of mathematical equations, written and usable in C++, as well as any derived langauges (D).
This is derivatives in the calculus sense.
The function uses a variadic function (`va_list`) to be able to work with polynomials of any degree, and only can do the power rule on positive integer terms.

## Usage
All code is in the derive.h file, which can be included with the simple
```cpp
#include "derive.h"
```
The function is called `derive(degree, ...)`
The mathematical equation must be expressed in coefficient form, which may not work for all equations.
This means that for the equation 3x2 + 234x + 45, it is already in coefficient form, because it is ax2 + bx + c.
The function returns a string containing the full function.
The example below is for the functions 3x2 + 9x + 43 and 9x5 + 4x3 + 3x2 + 4x, relatively.
```cpp
// 3x^2 + 9x + 43 (2nd degree equation)
derive(2, 3, 9, 43);

// 9x^5 + 4x^3 + 3x^2 + 4x (5th degree equation)
derive(5, 9, 0, 4, 3, 4)

// In general:
derive(degree, a, b, c, ...);
```
The function will not work with any decimals, both in the coeffients and the exponents, and will not work with negative exponents.

## Todo
 - Work with decimal (float) coefficients
 - Work with negative exponents
 - Work with decimal exponents
 - Work with forms other than coefficient form

repository: hmwildermuth/DerivativeCalc-Cpp

repo_name: hmwildermuth/DerivativeCalc-Cpp


text:
Open Rust document in Vim
=========================

`cargo` has a nice feature to generate document.  But it doesn't have a feature to search it yet.
This plugin searches documents (standard libraries, libraries your crate depends on, and so on) from Vim.

- Open a document for the word under cursor `std`

![screenshot](https://raw.githubusercontent.com/rhysd/screenshots/master/rust-doc.vim/rust-doc.vim.gif)

- Search documents with [unit.vim](https://github.com/Shougo/unite.vim) interface

![unite screenshot](https://raw.githubusercontent.com/rhysd/screenshots/master/rust-doc.vim/unite-rust-doc.gif)

## Usage

- __`:RustDoc` command__

```
:RustDoc {crate or module name} [{identifier name}]
```

For example, assume that your crate uses [rand](http://doc.rust-lang.org/rand/rand/index.html).

1. `:RustDoc rand` opens the document for crate `rand`.
2. `:RustDoc rand::distributions` opens the document for module `rand::distributions`.
3. `:RustDoc rand Rng` opens the document for trait `rand::Rng`.

All arguments of the command can be completed.  Please enter `<Tab>` to complete them.

Of course you can search standard libraries.

```
:RustDoc std::vec
```

And `:RustDocFuzzy` and `:RustDocModule` are also available.
Please see [document for them](https://github.com/rhysd/rust-doc.vim/blob/master/doc/rust-doc.txt) for more detail.

- __Mapping `K`__

Entering key `K` in your Rust source opens a document most corresponding to a word under the cursor.

`K` mapping is available in normal mode and visual mode.  In normal mode, the word under the cursor is used.
In visual mode, the selected text is used.

- __[unite.vim](https://github.com/Shougo/unite.vim) source__

```
:Unite rust/doc
```

You can select from all document candidates with unite.vim interface.
And if you want to use unite.vim for `K` mapping, you can setup in your vimrc as follows.

```vim
let g:rust_doc#define_map_K = 0
augroup vimrc-rust
    autocmd!
    autocmd FileType rust nnoremap <buffer><silent>K :<C-u>Unite rust/doc:cursor -no-empty -immediately<CR>
    autocmd FileType rust vnoremap <buffer><silent>K :Unite rust/doc:visual -no-empty -immediately<CR>
augroup END
```

It may takes some time to prepare candidates.  If you don't want to wait and it is enough for you to search only module names,
please specify `modules` to the argument of `rust/doc` source as below.

```
:Unite rust/doc:modules
```

- __[denite.nvim](https://github.com/Shougo/denite.nvim) source__

```
:Denite rust/doc
```

You can select from all document candidates with denite.nvim interface.
And if you want to use denite.nvim for `K` mapping, you can setup in your vimrc as follows.

```vim
let g:rust_doc#define_map_K = 0
augroup vimrc-rust
    autocmd!
    autocmd FileType rust nnoremap <buffer><silent>K :<C-u>DeniteCursorWord rust/doc<CR>
augroup END
```

It may takes some time to prepare candidates.  If you don't want to wait and it is enough for you to search only module names,
please specify `modules` to the argument of `rust/doc` source as below.

```
:Denite rust/doc:modules
```

## Installation

### 1. Install This Plugin

If you use some plugin manager, please follow the instruction of them.
For example, you can install this plugin with [neobundle.vim](https://github.com/Shougo/neobundle.vim) as below.

```vim
NeoBundle 'rhysd/rust-doc.vim'
```

If you use no plugin manager, copy all directories and files in `autoload`, `plugin`, `ftplugin`
and `doc` directories to your `~/.vim` directory's corresponding directories.

Or you can also use Vim's standard package management. Please read `:help packages`.

### 2. (Optional) Setup Standard Library Documents

rust-doc.vim searches documents downloaded by [rustup](https://github.com/rust-lang-nursery/rustup.rs).
If there is a toolchain installed by rustup, rust-doc.vim tries to use documentations in it.

If you want to see your own standard library documents, you must set `g:rust_doc#downloaded_rust_doc_dir`.
The variable should be string type and contain the path to rust documents bundled in downloaded rust tar.

__e.g.__:

```sh
$ wget https://static.rust-lang.org/dist/rust-1.0.0-i686-unknown-linux-gnu.tar.gz
$ tar xf rust-1.0.0-i686-unknown-linux-gnu.tar.gz
$ mv rust-1.0.0-i686-unknown-linux-gnu/rust-doc ~/Documents/
```

Then set the variable as below

```vim
let g:rust_doc#downloaded_rust_doc_dir = '~/Documents/rust-docs'
```

## Customization

- `g:rust_doc#vim_open_cmd`

Vim command to open the path to a document.  rust-doc.vim uses it to open the document if it is not empty.
The command must take a url to the local file.

- `g:rust_doc#open_cmd`

Shell command to open the path to a document.  rust-doc.vim uses it to open the document if it is not empty.
The command must take a url to the local file.

- `g:rust_doc#do_not_ask_for_module_list`

If the value is `1`, rust-doc.vim never ask if it shows the list of modules/identifiers when no document is found.
The default value is `0`.

- `g:rust_doc#define_map_K`

If the value is `1`, `K` mappings described above is defined. The default value is `1`.

- `g:rust_doc#downloaded_rust_doc_dir`

As described above, the path to directory of rust standard library documents.

## License

This plugin is distributed under [the MIT License](http://opensource.org/licenses/MIT).

```
Copyright (c) 2015 rhysd
```

gha_language: Vim script


text:
<demo>

### Customised icon.

Pass `icon` attribute to set the icon.

```jsx live
<Result
  status="success"
  title="You order has been delivered!"
  icon={<Icon name="delivered" color="#52c41a" size={80}/>}
  extra={[
    <Button btnType="primary" key="console">
      Go Console
    </Button>
  ]}
/>
```

</demo>

repository: wangdicoder/tiny-ui

repo_name: wangdicoder/tiny-ui


text:
# Exercise #4 - Ancient Numerals

A team of researchers is uncovering the ruins of a forgotten ancient civilisation.

A text is scanned into an array of numerals. Numerals are scanned row by row into an array of strings. Each array of strings represents a row of the numeral, and each element in that array represents a row of the symbol that is present in the numeral.

You are tasked with parsing the digitised texts into numbers for later analysis.

**Example:**

Input:

```
input: [
    [
        [ '****', '****' ],
        [ '****', '....' ],
        [ '****', '....' ],
        [ '****', '****' ],
    ],
    [
        [ '....' ],
        [ '****' ],
        [ '****' ],
        [ '....' ],
    ],
]
```

Output:

```
'92 4'
```

**Deliverables:**

Write a function named `parseAncientText` accepting one parameter:

* `input` - array of digitised ancient numerals.

The function requirements are:

1. The function must return a string result displaying ancient numerals as numbers. If there is more than one numeral in the input, the numbers are separated by a space.
3. The `input` parameter must be a valid array of numerals.

**Challenge inputs:**

#1

```
input: [
  [
    [ '****', '....', '....', '****' ],
    [ '....', '****', '....', '****' ],
    [ '....', '****', '....', '****' ],
    [ '****', '....', '....', '****' ],
  ],
  [
    [ '*..*', '.*..' ],
    [ '*..*', '.*..' ],
    [ '*..*', '.*..' ],
    [ '*..*', '.*..' ],
  ],
  [
    [ '....', '*...', '.**.' ],
    [ '****', '*...', '.**.' ],
    [ '....', '*...', '.**.' ],
    [ '....', '*...', '.**.' ],
  ],
  [
    [ '****' ],
    [ '....' ],
    [ '....' ],
    [ '....' ],
  ],
]
```

**Tips:**

* [Explore the String global object on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)
* [Explore the Array global object on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)
* Test your function using different arguments to ensure error and edge-cases are handled correctly


text:
Description
===========

This cookbook exists to automatically make a RAID array using all the Ephemeral block devices (aka "disks", but we cannot know for sure what they are) it can find present to the system it runs on.

The cookbook's default RAID level is 0 - maximum performance with absolutely no redundancy. You must change the attribute to something else if you are worried about dataloss.

The Ephemeral block devices typically have higher performance than other volumes and due to their Ephemeral nature are ideal for high-IO throw-away work or clustered loads that run with sufficient levels of distributed data redundancy: i.e. multi-AZ or multi-region data replication.

These block devices are also typically included with the instance you choose - at no extra cost.

Cloud providers may be sneaky however, since only one of these block devices are available by default when you launch an instance without requisite block device mappings.

See the Usage section for further info on how to get the drives to show up in one example.

This cookbook does not create filesystems, but there is a cookbook out there that does just that : the filesystem cookbook.

Use Case
========

For EC2: See http://aws.amazon.com/ec2/instance-types/ for an up to date list of how many ephemeral block devices/disks there are for each instance type - these devices/disks are otherwise referred to as 'Instance Storage'.

This recipe is only really worth using if there is more than one block device available. At the time of writing the instances that this cookbook suits being run upon are:

* `m1.large` 2 x 420 HDD
* `m1.xlarge` 4 x 420 HDD
* `c1.xlarge` 4 x 420 HDD
* `cc2.8xlarge` 4 x 840 HDD
* `m2.4xlarge` 2 x 840 HDD
* `cr1.8xlarge` 2 x 120 SSD
* `hi1.4xlarge` 2 x 1,024 SSD
* `hs1.8xlarge` 24 x 2,048 HDD
* `cg1.4xlarge` 2 x 840 HDD

Default Behaviour
=================

By default this cookbook grabs all the ephemeral block devices it finds, cleans them up and then creates a raid level 0 array out of them with mdraid.

Suggested Use Pattern
=====================

This cookbook should be used with the [filesystem] cookbook.

Requirements
============

* A relatively recent common Linux distribution. This recipe is linux-only.

* A cloud provider that Ohai recognises.

* Two or more mapped Ephemeral block devices.

* `mdadm` - This is needed for forming the raid device. We use it via the chef provider.

Recipes
=======

* `default.rb` : A dummy recipe pointing to install.rb
* `install.rb` : Installs everything by calling the rest of the recipes in the right order i.e. once packages have been installed.
* `cleanup.rb` : Unmounts devices and clears partition tables.
* `makeraid.rb` : Creates the raid device, using the mdadm provider.

Attributes
==========

See the contents of `attributes/default.rb` where there are accurate comments and self-explanatory attribute names.

Usage
=====

When you run your instances or create your autoscaling configuration, in the following case for EC2 `m1.xlarge` instances, you must specify the four free emphemeral devices like so:

`--block-device-mapping "/dev/xvdb=ephemeral0,/dev/xvdc=ephemeral1,/dev/xvdd=ephemeral2,/dev/xvde=ephemeral3"`

While we recommend you retain most of the default behaviour, your needs may differ so consider the following example, which includes filesystem creation:

`run_list` ephemeral_raid, filesystem

````JSON
{
  "ephemeral": {
    "raid": {
      "level": "10",
    }
  },
  "filesystems": {
    "raidfs": {
      "device": "/dev/md0",
      "mount": "/mnt",
      "fstype": "xfs",
      "optons": "noatime,nobarrier",
      "mkfs_options": "-d sunit=128,swidth=2048"
    }
  }
}
````

Development
===========

See the [Github page][https://github.com/mdsol/ephemeral_raid_cookbook]

Authors
=======

* Author: Alex Trull<EMAIL_ADDRESS>with plenty of ideas bouncing around with Benton Roberts<EMAIL_ADDRESS>
Special Thanks
==============

* This cookbook was built on the shoulders of giants such as Mike Heffner<EMAIL_ADDRESS>who originated the original recipe provided significant suggestions for improvement.
* The ephemeral devices helper was taken from Apache 2.0 licensed work by RightScale. Their quality is awesome.

Copyright: 2013–2013 Medidata Solutions, Inc.

gha_language: Ruby


text:
#OpenDataNetwork.com#

---

##Summary##

This document describes the data-driven aspects of the OpenDataNetwork.com website, details how and where the site is hosted and the lists location of the source tree.

## Development

This is a [Node.js](https://nodejs.org/) site.
Install `node` along with `npm` to get started.

### Dependencies

Install all dependencies with `npm install`.

### Build

The build process is automated using `gulp` and configured with `gulpfile.js`.
 - `gulp js`: build javascript
 - `gulp css`: build css
 - `gulp build`: build javascript and css
 - `gulp watch` (or `gulp`): rebuild source on change
 - `gulp start`: run local webserver at [localhost:3000](http://localhost:3000)

##Source Files##

The Open Data Network web site source files are located in Github.

[https://github.com/socrata/opendatanetwork.com](https://github.com/socrata/opendatanetwork.com)

All the JSON files which hold the data to be displayed in the slider, the tiles list, the decision tree on the /explore page and the list of data portals is stored in /data folder.

[https://github.com/socrata/opendatanetwork.com/tree/master/data](https://github.com/socrata/opendatanetwork.com/tree/master/data)

##JSON Data Files##

###Category-Metadata.json###

Holds icon, description and showcase items for each category.

##Hosting##

The Open Data Network website is hosted on Heroku and is located here:

[https://dashboard.heroku.com/apps/opendatanetwork/resources](https://dashboard.heroku.com/apps/opendatanetwork/resources)

Paul Paradise can grant access to the dashboard.

Currently the site is hosted under the preview.opendatanetwork.com sub-domain.

[http://preview.opendatanetwork.com](http://preview.opendatanetwork.com)

##Deploying##

Once you have compressed your CSS and JS, committed and pushed to Github, and you want to push your changes to Heroku, issue to the following command:

	$ git push heroku master

The sources will be pushed into your dyno and the site will be running the lastest bits.  The Heroku toolbelt and dashboard support rollbacks in case of a buggy build.

More details about deploying with git to Heroku, including setting up the remote, can be found here:

[https://devcenter.heroku.com/articles/git](https://devcenter.heroku.com/articles/git)

###Robots.txt###

***NOTE***:  The site currently has a robots.txt with disallow all in place.  When the site goes live, delete the robots.txt or the site won't show up in Google search results.


text:
---
layout: post
title: AppMon 7.0 - Web Dashboards and Javascript
header_image: /images/headerimages/appmon7-web-dashboards-js-header.gif
categories: [appmon, dynatrace, web dashboards]
---

One of the coolest features of AppMon 7.0 is the ability to add custom JS and CSS to your dashboards. Let’s see what’s possible…

---

Update: 04/03/2018
The capabilities described in the following post are available in Dynatrace AppMon v7.0.0 – v7.0.9. After v7.0.9 the javascript and CSS functionality was removed for security reasons.

v7.0.9 and onwards include the ability to define variables and perform mathematical operations on variables as an out-of-the-box piece of functionality – no debug flags or workarounds required.

---

Dynatrace application monitoring (AppMon) 7.0 introduced the ability to include custom Javascript and CSS in your web dashboards. This makes for some pretty powerful visualisation and dashboarding abilities.

## Prerequisites

To follow this tutorial you’ll need:

- A working and licensed AppMon server and collector.
- An instrumented Apache server with my [wait.php file](https://github.com/agardnerIT/XAMPP-Pages/blob/master/wait.php).
- Put the client into debug mode (`Ctrl + F9`) then set the `com.dynatrace.diagnostics.webui.tmtAllowJsAndCss` debug flag to `true` (server settings > general tab > debug options).

![]({{ site.baseurl }}/images/postimages/appmon7-web-dashboards-1.jpg)

## Intelligent Dashboards

AppMon 7 allows markdown and measure substitution within that markdown (meaning {1} will be replaced with a response time, for example) but wouldn’t it be great if we could take that a step further and actually do maths in the dashboards themselves?

Let’s get the basics set up first. Verify that your Apache server is instrumented correctly, then fire some requests at the wait.php page to generate some purepaths.

![]({{ site.baseurl }}/images/postimages/appmon7-web-dashboards-2.jpg)

Create a response time measure on the wait.php page.

![]({{ site.baseurl }}/images/postimages/appmon7-web-dashboards-3.jpg)

Open the web dashboards (https://DT-SERVER:9911), create a new dashboard and chart the measure. You should have something resembling this:

![]({{ site.baseurl }}/images/postimages/appmon7-web-dashboards-4.png)

## Text & Measurement Dashlet

Let’s use another new feature of AppMon 7 – the text replacement feature.

Add a new text and measures tile to your dashboard and add the `wait.php` measure twice (one aggregation set to average and one set to maximum). The {1} and {2} will be dynamically replaced with the average and maximum response times respectively.

```
Average response time of Wait Page: {1}
Maximum response time of Wait page: {2}
```

![]({{ site.baseurl }}/images/postimages/appmon7-web-dashboards-5.png)

CUSTOM JAVASCRIPT

Taking things a step further, we can even use these replacements in custom javascript code.

The following code takes the average response time, divides it by 10 the stores it into a JS variable called `myVar`. I can then use this as standard JavaScript code, so if `myVar` is above `myThreshold`, I visually warn the user with new message and a red background:

```
<style>
#status
{
  border: 1px solid black;
  text-align: center;
}
</style>
<p id="status">Status: OK</p>

<script>
var myVar = {1} / 10;
var myThreshold = 10;

if (myVar > myThreshold)
{
  document.getElementById(‘status’).innerHTML="Status: Warning!";
  document.getElementById(‘status’).style.color="white";
  document.getElementById(‘status’).style.backgroundColor="red";
}
</script>
```

(click video for full resolution version)
![]({{ site.baseurl }}/images/postimages/appmon7-web-dashboards-6.gif)

## Bonus: CSS Animations

How about combining all of this into a nice, slick CSS animated warning message?

```
<style>
#status
{
  border: 1px solid black;
  text-align: center;
}
</style>
<p id="status">Status: OK</p>

<script>
var myThreshold = 10;
if (myVar > myThreshold)
{
  document.getElementById("status").innerHTML = "Status: Warning!";
  document.getElementById("status").style.animationName = "warningAnimation";
  document.getElementById("status").style.animationDuration = "2s";
  document.getElementById("status").style.animationIterationCount = "infinite";
}
</script>
<style>
/* Safari 4.0 – 8.0 */
@-webkit-keyframes warningAnimation {
  to {background-color: red; color: white;}
}

/* Standard syntax */
@keyframes warningAnimation {
  to {background-color: red; color: white;}
}
</style>
```

(click video for full resolution version)
![]({{ site.baseurl }}/images/postimages/appmon7-web-dashboards-7.gif)

Has this sparked your curiosity or creativity? [Drop me a line](contact) and let me know what you’re thinking of building!

repository: agardnerIT/site

repo_name: agardnerIT/site


text:
# Debian / Ubuntu
## Add new user + grant sudo
```
# as root
# create user
sudo adduser <username>
# grant sudo privileges
visudo

# add this line
# User privilege specification
<username>  ALL=(ALL:ALL) ALL
```

## Copy ssh key onto new machine
```
$ ssh-copy-id -i ~/.ssh/<ssh-key>.pub <user>@<server>
# OR
$ cat ~/.ssh/<ssh-key>.pub | ssh <user>@<server> "mkdir -p ~/.ssh && cat >>  ~/.ssh/authorized_keys"
```

repository: theatlasroom/snippets

repo_name: theatlasroom/snippets


text:
GrooScript
==========

Converts your Groovy code to JavaScript(Groovy 2.0 to Javascript ECMAScript 5).

For run JavaScript need grooscript.js

**Version 0.1 is out!**

In sonar maven repository:

https://oss.sonatype.org/content/groups/public/
org.grooscript:grooscript:0.1

Please all feedback welcome, thanks!

Missing some Groovy stuff:
--------------------------

Basic inheritance, not super except in constructors.

Not class, instanceof, super,... Types not supported.

Not allowed same number of parameters in methods / constructors.

Can add methods and properties with metaclass, but some problems with primitive types as String and Number.

Losing pretty print, had to function == (equals), and I suppose same for other operators.

Javascript 'split' not the same, maybe will translate to tokenize.

String.length() not work, cause length is property in Javascript.

---

Twitter: @jfrancoleza

Website URL (can try conversions there): http://www.grooscript.org

repository: SMIDEC/grooscript

repo_name: SMIDEC/grooscript


text:
__A simple assertion library to ensure pre conditions, post conditions and
invariants are correct.__ Supports automatic removal of assertion calls
from production builds.

---

Table of Contents

1. [API Overview](#api)
2. [Usage Example](#usage-example)
3. [Usage Example in Typescript](#usage-example-in-typescript)
4. [Usage Example in Typescript using ES6 Modules](#usage-example-in-typescript-using-es6-modules)
5. [Usage Example with Webpack](#usage-example-with-webpack)
6. [Automatic Assertion Removal](#automatic-assertion-removal)
7. [Usage with an Event Emitter](#usage-with-an-eventemitter)

---

## API

| Function Signature | Description |
|--------------------|-------------|
| `ASSERT(cond[, msg])` | throws an error (and optionally emits an event) if condition is `false`. An optional error message may be passed as second argument. |
| `ASSERT_NOT_REACHED()` | always throws an error (and optionally emits an event). |
| `IN_DEVELOPMENT_ONLY(fn)` | `fn` is only executed in development environments. See *usage with the C preprocessor* below. |

| Function Signature | Description |
|--------------------|-------------|
| `is_num(v)` | true if the given value is a finite number. therefore `is_num(infinity)`, `is_num(nan)` and `is_num("1")` are `false`. `is_num(-1)`, `is_num(1)` and `is_num(42.42)` are `true`. |
| `is_int(v)` | like `is_num`, but only `true` for integers. |
| `is_int_in_range(v, range)` | like `is_num`, but restricted to the range `[a, b]`. |
| `is_non_negative_int(v)` | `true` for integers greater than or equal to zero. |
| `is_positive_int(v)` | `true` for integers greater than zero. |
| `is_array(v)` | `true` for arrays. `false` for typed arrays. |
| `is_func(v)` | returns `true` if the given argument is a function. |
| `is_string(v)` | returns to `true` for strings and string objects. |
| `is_undef(v)` | evaluates to `true` for `null` and `undefined`. |
| `is_obj(v)` | evaluates to `true` for values that are not `null` or `undefined`. |
| `is_ctor(this, classref)` | `true` if the function was called with `new`, `false` if it was omitted. |

There are shorthand notations that are equivalent to calling a boolean function and asserting its return value.
They should be used in most cases, as they provide better default error messages:

| Function Signature | Call Target |
|--------------------|-------------|
| `ASSERT_IS_INT(v [, msg])` | is_int |
| `ASSERT_IS_INT_IN_RANGE(v, range, [, msg])` | is_int_in_range |
| `ASSERT_IS_NON_NEGATIVE_INT(v [, msg])` | is_non_negative_int |
| `ASSERT_IS_POSITIVE_INT(v [, msg])` | is_positive_int |
| `ASSERT_IS_ARRAY(v [, msg])` | is_array |
| `ASSERT_IS_FUNC(v [, msg])` | is_func |
| `ASSERT_IS_STRING(v [, msg])` | is_string |
| `ASSERT_IS_UNDEF(v [, msg])` | is_undef |
| `ASSERT_IS_OBJ(v [, msg])` | is_obj |
| `ASSERT_IS_NUM(v) [, msg]` | is_num |
| `ASSERT_IS_CTOR(this, classref [, msg])` | is_ctor |

Uppercase function calls will be stripped from the source code if you compile the code with
a C preprocessor. Lowercase function calls are not stripped.

## Usage Example

```js
/**
 * Instantiate a new data object representing a rectangular raster image
 * region.
 *
 * All options given can later be read using the same property name.
 * Note that the constructor can be used as copy constructor:
 *
 * ```js
 * new ImgRegion(new ImageRegion({ ... }));
 * ```
 *
 * @param {int} opts.width   the width of the image region
 *
 * @param {int} opts.height  the height of the image region
 *
 * @param {int} opts.offsetX the position of the image region
 *                           relative to origin in x-direction.
 *
 * @param {int} opts.offsetY the position of the image region
 *                           relative to origin in y-direction.
 */
function ImgRegion(opts) {
	ASSERT_IS_CTOR(this, ImgRegion)
	ASSERT_IS_OBJ(opts)
	ASSERT_IS_POSITIVE_INT(opts.width)
	ASSERT_IS_POSITIVE_INT(opts.height)
	ASSERT_IS_NON_NEGATIVE_INT(opts.offsetX)
	ASSERT_IS_NON_NEGATIVE_INT(opts.offsetY)

	this.width   = opts.width;
	this.height  = opts.height;
	this.offsetX = opts.offsetX;
	this.offsetY = opts.offsetY;
}
```

`assert.is_ctor` ensures that the function is called using the `new` keyword.
Note that semicolons are optional in javascript. The code above is valid
javascript without a compilation step.

## Usage Example in Typescript

```js
/// <reference types="assert-js"/>

/**
 * Instantiate a new data object representing a rectangular raster image
 * region.
 *
 * All options given can later be read using the same property name.
 * Note that the constructor can be used as copy constructor:
 *
 * ```js
 * new ImgRegion(new ImageRegion({ ... }));
 * ```
 *
 * @param {int} opts.width   the width of the image region
 *
 * @param {int} opts.height  the height of the image region
 *
 * @param {int} opts.offsetX the position of the image region
 *                           relative to origin in x-direction.
 *
 * @param {int} opts.offsetY the position of the image region
 *                           relative to origin in y-direction.
 */
export class ImgRegion {

    readonly width   :number;
    readonly height  :number;
    readonly offsetX :number;
    readonly offsetY :number;

    constructor(opts : {
        width:   number,
        height:  number,
        offsetX: number,
        offsetY: number
    }) {
	ASSERT_IS_POSITIVE_INT(opts.width)
	ASSERT_IS_POSITIVE_INT(opts.height)
	ASSERT_IS_NON_NEGATIVE_INT(opts.offsetX)
	ASSERT_IS_NON_NEGATIVE_INT(opts.offsetY)

        this.width   = opts.width;
        this.height  = opts.height;
        this.offsetX = opts.offsetX;
        this.offsetY = opts.offsetY;
    }
}
```
## Usage Example in Typescript using ES6 Modules

```js
import {ASSERT} from 'assert-js/es6';
ASSERT("something");
```

## Usage Example with Webpack

As Webpack supports the ES6 module syntax, you can use the import-from-syntax
shown above. You can get rid of the `/es6` suffix, by adding an alias to
your `webpack.config.js`:

```js
/* ... */
resolve: {
	alias: {
		"assert-js": "assert-js/es6.js"
	}
},
/* ... */
```

```js
import {ASSERT} from 'assert-js';
ASSERT("something");
```

#Automatic Assertion Removal

You can automatically remove all assertion calls from your source code using
the [C preprocessor](https://en.wikipedia.org/wiki/C_preprocessor). To do this
execute the following command for each source file:

```
gcc -E -D UNCHECKED_PRODUCTION_BUILD -P -include assert.c -C -x c -o out.js input.js
```

The following code for example

```js
function is_positive(val) {
	ASSERT_IS_INT(val))
	return val > 0;
}
```
will be reduced to

```js
function is_positive(val) {

	return val > 0;
}
```

You can also define your own functions, that will be removed in production
builds and called when the code was not preprocessed as follows:

```js
IN_DEVELOPMENT_ONLY(function() {
	console.info("this is not a production build!");
});
```

Calling the C preprocessor on the library file `assert.js` itself, will reduce
the file to

```js
var IN_DEVELOPMENT_ONLY = function(fn) {
	if(this.ASSERT) {
		fn();
	} else {
		console.warn('Call to <IN_DEVELOPMENT_ONLY> in production build. ' +
			     'Did you forget to compile some files?');
	}
};
```

This snippet will be removed by your minifier in production environments,
as all calls should have been removed by the preprocessor.

## Usage With an EventEmitter

If you include an EventEmitter package (e.g.
[EventEmitter3](https://github.com/primus/eventemitter3)) first, you can call
`assert.eventEmitter.addListener("assertion failure", myLoggerFunc)`, where
`myLoggerFunc` is one of your functions.

repository: reiner-dolp/assert-js

repo_name: reiner-dolp/assert-js


text:
vs-settings
===========

_file naming note: VS 2013.2 - its VS 2013 with Update 2 installed, may work on VS 2013/VS 2013.1 but I can't guarantee that_

To you Colour Theme for VS, please instal [Visual Studio 2013 Color Theme Editor](http://visualstudiogallery.msdn.microsoft.com/9e08e5d3-6eb4-4e73-a045-6ea2a5cbdabe). I do not use `Toos | Option | Environment | Fonts and Colors`. I'm only changing font size there and that's.

For colours samples, scroll down.

**ReSharper-CodeStyle.DotSettings**

R# settings for code style - like when to insert space and when to move code to new line.

**VS-2013.2-TextEditor.vssettings**

Same as with R# but for VS (exported from VS 2013.2) plus few other settings like adding line numbers, opening XAML in XAML editor not Designer, how tabs for me are set up etc.

**VS-2013-TextEditor.vssettings**

Same as with _VS-2013.2-TextEditor.vssettings_. However I've noticed that its not working as it should when imported to VS 2013.2.

**VS-2013.2-Monokai.vstheme**

My colour theme for VS 2013.2. Its based on Monokai Sublime theme - however with few drawbacks. Not everything can be setup same way as in Sublime :(. However I think that it's _good enough_ and ready to be used. I've done some extra work on R# colour settings, but ITS NOT GOOD ENOUGH :) So if you are using R# colour settings then please contribute, thanks :)

**VS-2013-Monokai.theme**

Same as _VS-2013.2-Monokai.vstheme_ but for pure VS 2013 and VS with Update 1. Not sure if it will work with VS 2012 but you can try it.

repository: marcelo-mason/vs-settings

repo_name: marcelo-mason/vs-settings


text:
# Changelog / Release Notes

All notable changes to `Cerberus Ruby Client` will be documented in this file. `Cerberus Ruby Client` adheres to [Semantic Versioning](http://semver.org/).

### Added

- Initial open source code drop for the Cerberus Ruby client by [Joe Teibel](https://github.com/junosw).
- AssumedRoleCredentialsProviderChain added by [Neil Fairweather](https://github.com/neildf)

repository: Nike-Inc/cerberus-ruby-client

repo_name: Nike-Inc/cerberus-ruby-client


text:
# Template

::: warning
The current template implementation might still change. `lit-html` has been replaced by `htm` +
`vhtml` combo to allow more flexibility and a simpler setup, but since it's more focussed on
(p)react compatibility, it requires a bit more effort to use raw HTML rendering.
:::

Templates in Muban mostly serves a role during development, since the whole reason Muban exists is
to make components for HTML rendered on the server. But to help local development to become easier,
and not require waiting on complex server integrations before development can start, it plays an
important role in the daily use of Muban.

The two small use cases it has for production are:

1. For dynamic templates that have to be rendered from JavaScript, after receiving JSON data from
   an API, or complex local interaction is needed.

2. Although not built or marketed as such, with Muban it's possible to statically generate pages
   based on mock data and its templates. This is mostly used to generate static preview builds to
   showcase full pages for testing and sign-of, but can be used in production with some
   additional care.

## TypeScript

There are a lot of template languages in existence, and most of them have 2 things in common;

1. It's a text-based format, with its own syntax for variables, control flow, inclusion of child
   templates, passing down context, etc.
2. There is no type checking between the data you pass when rendering the template (or including
   child templates), and how you use that data inside your template itself. It doesn't help you
   while writing your templates, and only warns you when running them with the wrong data.

The purpose of adding TypeScript in the equation of templates, is to offer a solution to both
problems described above. React has proven that writing your templates in a language familiar to
everyone works just fine, and a vast amount of people even prefer it. And if your templates are
just functions that receive props, and output the resulting template based on the passed data,
you have support of typing within your template, and when passing data from the outside.

What's used inside the template functions is less important, and could even be as simple as
string concatenation. Whatever solution is chosen, keep in mind that the only purpose is to render
out an HTML string to the DOM. There is no interactivity or event binding in place. The purpose
is to simulate HTML that is rendered on the server, which is also just plain text.

The bare-bones version of any template would look like this:

```ts
type MyTemplateProps = {
  products: Array<MyProductTemplateProps>;
};

function myTemplate({ products }: MyTemplateProps) {
  // return ...
}
```

## mhtml

Currently, muban exposes it's own template language (mhtml), comprised of [htm](https://github.com/developit/htm)
and [vhtml](https://github.com/developit/vhtml) with some custom modifications and utils.
It makes use of tagged template strings, is very light-weight, directly returns strings as
template results.

### Guide for composing 2 simple templates

A typical template would look like this:

```ts
import { html } from '@muban/template';
import classnames from 'classnames';

type AccordionSlideProps = {
  heading: string;
  content: string;
  expanded?: boolean;
};

export function accordionSlide({ heading, content, expanded }: AccordionSlideProps, ref?: string) {
  return html`<div
    data-component=${AccordionSlide.displayName}
    data-ref=${ref}
    data-expanded=${expanded}
  >
    <div data-ref="slide-wrapper" class=${classnames({ expanded: !!expanded })}>
      <h4 data-ref="slide-heading">${heading}</h4>
      <p data-ref="slide-content">${content}</p>
    </div>
  </div>`;
}

export type AccordionProps = {
  slides: Array<AccordionSlideProps>;
  activeIndex?: number;
};

export function accordion({ slides, activeIndex }: AccordionProps) {
  return html`<div data-component=${Accordion.displayName}>
    ${slides.map(
      (slide, index) => accordionSlide({ ...slide, expanded: index === activeIndex }, 'accordion-slide'),
    )}
  </div>`;
}
```

Let's go step by step and see how we would write a template.

#### 1. Starting with the props and template function

If we know what our template should render, we can already define the template function and its
props, so we can start rendering it to see how it looks.

```ts
import { html } from '@muban/template';

type AccordionSlideProps = {
  heading: string;
  content: string;
  expanded?: boolean;
};

export function accordionSlide({ heading, content, expanded }: AccordionSlideProps) {
  return html`<div></div>`;
}
```

A template should return a `string`. Using the `html` tagged template string will do exactly that.

```ts {2}
export function accordionSlide({ heading, content, expanded }: AccordionSlideProps) {
  return html`<div></div>`;
}
```

#### 2. Add the template HTML with some data filled in

Next we can just create our HTML, and start adding

```ts {3-6}
export function accordionSlide({ heading, content, expanded }: AccordionSlideProps) {
  return html`<div>
    <div>
      <h4>${heading}</h4>
      <p>${content}</p>
    </div>
  </div>`;
}
```

Notice that we're just using `${}` placeholders to render our variables, just like we normally do
in your template strings.

#### 3. Add the data-component attribute

If we know our template is going to be for a component, we should add the `data-component`
attribute.

```ts {2}
export function accordionSlide({ heading, content, expanded }: AccordionSlideProps) {
  return html`<div data-component=${AccordionSlide.displayName}>
    <div>
      <h4>${heading}</h4>
      <p>${content}</p>
    </div>
  </div>`;
}
```

This is just a string, but if we already have our TS component, we can just reference it from
there, so we always know they are in sync.

#### 4. Add other data

We still have to manage how our `expanded` property should behave. Let's add it as a css class on
the container div, and as a `data-` attribute on the component.

```ts {6,8}
import { html } from '@muban/template';
import classnames from 'classnames';

export function accordionSlide({ heading, content, expanded }: AccordionSlideProps) {
  return html`<div
    data-component=${AccordionSlide.displayName}
    data-expanded=${expanded}
  >
    <div class=${classnames({ expanded: !!expanded })}>
      <h4>${heading}</h4>
      <p>${content}</p>
    </div>
  </div>`;
}
```

By setting the `data-expanded` attribute, our TS component can pull it in as property to set it's
initial state correctly.

For setting the `class` attribute we can use the `classnames` module; it applies any classes
which value is truthy.

::: warning Component state
If the component should update the visual representation after interaction, and from the server
it can be rendered in either of those options, the rendered HTML should always make sure both the
visual representation is correctly rendered, along with providing the state in a `data-` attribute.

The component should read that state through the props, and set up the same bindings to reflect
that visual representation, so both are in sync.
:::

#### 5. Define your refs

After that you should know what parts of your HTML your component is interested in updating
through the bindings. Those elements should add a `data-ref` attribute with a semi-unique value,
so your component can query those elements.

```ts {6-8}
export function accordionSlide({ heading, content, expanded }: AccordionSlideProps) {
  return html`<div
    data-component=${AccordionSlide.displayName}
    data-expanded=${expanded}
  >
    <div data-ref="slide-wrapper" class=${classnames({ expanded: !!expanded })}>
      <h4 data-ref="slide-heading">${heading}</h4>
      <p data-ref="slide-content">${content}</p>
    </div>
  </div>`;
}
```

The value of the `data-ref` should be unique within your component (tree). Some things to keep
in mind about those refs:
* When using `refElement` to select refs, it uses `querySelector` to pick the first matching
  element.
* When using `refCollection`, it uses `querySelectorAll` to select al matching refs it finds.
* When using `refComponent` or `refComponents`, and passing the `ref` value, the same behaviour
  as above is applied. When not passing a `ref`, it uses the `data-component` attribute, and the
  same behaviour applies.

::: tip data-ref
Rather than selecting arbitrary css classnames that can change over time, or abuse js-foo
classnames that are only used to query from JS, we use dedicated `data-ref` attributes to make
the intent of use fully transparent.
:::

#### 6. Define your own component's ref

When your component template is rendered inside other component templates, it might want to
target this component as part of a collection or as a specific single element. To allow this, we
must also accept a `ref` parameter in our template function, and render it in our root element.

 ```ts {1,4}
export function accordionSlide({ heading, content, expanded }: AccordionSlideProps, ref?: string) {
  return html`<div
    data-component=${AccordionSlide.displayName}
    data-ref=${ref}
    data-expanded=${expanded}
  >
    <div data-ref="slide-wrapper" class=${classnames({ expanded: !!expanded })}>
      <h4 data-ref="slide-heading">${heading}</h4>
      <p data-ref="slide-content">${content}</p>
    </div>
  </div>`;
}
 ```

#### 7. Doing the same for our parent component

First we specify our template props, and rendering the outer element, filling the `data-component`
attribute with the component's name.

```ts {2}
export type AccordionProps = {
  slides: Array<AccordionSlideProps>;
  activeIndex?: number;
};

export function accordion({ slides, activeIndex }: AccordionProps) {
  return html`<div data-component=${Accordion.displayName}></div>`;
}
```

Note that we're composing our prop types by referencing `AccordionSlideProps`. We can do this
because we're actually going to render our child template here, and passing that data along.

```ts {3-5}
export function accordion({ slides, activeIndex }: AccordionProps) {
  return html`<div data-component=${Accordion.displayName}>
    ${slides.map(
      (slide, index) => accordionSlide({ ...slide, expanded: index === activeIndex }, 'accordion-slide'),
    )}
  </div>`;
}
```

We're just using the `${}` tokens to inline our child templates. We map over our slides Array,
invoke our child template function, and pass our data for each slide as props. Additionally, we
pass the `ref` we want as the 2nd argument.

### Rendering raw HTML

#### unsafeHTML

To render raw HTML, we can use the `unsafeHTML` util. By default, all our variables will be
considered unsafe and thus escaped. If your data contains HTML that needs to be rendered in your
template, you can use this helper.

```ts
import { html, unsafeHTML } from '@muban/muban';

const content = 'Hello <strong>World</strong>!';

html`<div>${unsafeHTML(content)}</div`;
```

#### dangerouslySetInnerHTML

Because `htm`/`vhtml` are built to support JSX use cases, another way to render "innerHTML" is using
the `dangerouslySetInnerHTML` attribute on any HTML element. We use that internally in some other
helpers as well, for example:

```ts
html`<script
        type="application/json"
        dangerouslySetInnerHTML=${{
          __html: JSON.stringify(content),
        }}
      ></script>`;
```

#### Html entities

::: warning html entities
Because the way the `htm` parser works, any "text content" that contains HTML characters might
confuse it. Always use `<` and similar escaped entities if you need to render them.

Unfortunately there aren't any errors shown, the rendered HTML will just be out of sync.
:::

```ts
// don't - this will break in your browser
html`<p>It's < 9000</p>`;

// do this
html`<p>It's < 9000</p>`;
```

repository: skulptur/muban

repo_name: skulptur/muban