text:
# Why we choose React at Eventbrite

## Ben Ilegbodu

[@benmvp](https://twitter.com/benmvp) | [benmvp.com](/) | [@evbeng](https://twitter.com/evbeng)

April 25, 2018

NOTES:
- My name is Ben Ilegbodu
- It was over 2 years ago that we mbarked on the journey of transitioning our frontend from Backbone to React
- So this talk is about the first part of that transition: convincing everyone that it was a good idea 😀
- Wanna pull back the covers on the rationales we used to make that switch
- Most ofo you are familiar with Backbone so hopefully this will explain the advantages of React
- This is a "polished" presentation, but I'm hoping we'll stop many times with questions
- Posted link to slides on twitter if you want to follow along

=====

[![Tweet from Jordan Harband about how people are hard](../../img/why-react/jordan-harband-people-are-hard.png)](https://twitter.com/ljharb/status/927606717793296384)

NOTES:
- I've been in the industry for about a dozen years now
- And I've come to realize that software development isn't just the code you commit
- There's an equally important human element to it
- Whenever doing something buy-in is just as important as the technical approach
- When difficulties arise, it can be the difference between folks complaining or rallying to find a
  solution, is buy-in

/////

  <video data-autoplay loop style="width: 55%">
    <source data-src="../../img/why-react/eventbrite-why-react-doc.m4v" />
  </video>

NOTES:
- We had actually tried React a couple of times, ran into issues, and people concluded "React is no good"
- So this time, in early 2016, I put together a loooong 19-page document to explain why our Frontend Platform team thought we should make the switch
- And as I said "cuz everybody is using it!" wasn't a good enough reason 😉
- The rest of the talk is a talk-friendly distillation of that doc

=====

# CORE STUFF

NOTES:
- Split this up into 2 main sections
- Start off with the Core Stuff
- Core ones will apply to everyone using React
- Part of the core React lib

=====

# 1. Declarative JSX

![Denzel Washington shouting](../../img/giphy/shouting-denzel-washington.gif)

NOTES:
- The first reason why we wanted to migrate from Backbone to React was its Declarative JSX

/////

## JSX

```js
<div>
  <span className="val">{this.state.value}</span>
  <button onClick={this._handleClick}>+</button>
</div>
```

NOTES:
- Here is some JSX
- Got a `<div>` wrapping a `<span>` display and a `<button>`
- Looks much like HTML and lives right w/in our JavaScript
- Many people didn't like the syntax at first
- But I find it very approachable
- What you may not realize is that this JSX gets converted into JavaScript

/////

## Transpiled JSX

```js
React.createElement(
  'div',
  null,
  React.createElement('span', {className: 'val'}, value),
  React.createElement('button', {onClick: this._handleClick}, '+'),
)
```

([Babel REPL](https://babeljs.io/repl/))

NOTES:
- Here it is transpiled; it's just JavaScript ultimately
- Thanks to the power of build tooling (aka Babel)
- We can write our code in friendly JSX
- But out comes normal JS
- I couldn't imagine building my React components like this

/////

## Markup, logic & data are together

```js
class Incrementer extends React.Component {
  state = {value: 0}

  _handleClick = () => {
    this.setState((prevState) => ({value: prevState.value + 1}))
  }

  render() {
    return (
      <div>
        <span className="val">{this.state.value}</span>
        <button onClick={this._handleClick}>+</button>
      </div>
    )
  }
}
```

NOTES:
- Here's the JSX in the context of a full component
- We'll go into the details of what the component does in following sections
- But we're returning the JSX w/in `render()` as if it's a regular object
- So markup is in the JavaScript right there with the logic
- So everything is together, which was very different than traditional MVC like Backbone

/////

## Traditional MVC equivalent

Handlebars template

```
<div>
  <span class="val">{{value}}</span>
  <button class="js-btn">+</button>
</div>
```

NOTES:
- This is the traditional MVC equivalent in Backbone
- You have a separate file for the template (markup) as well as model & view (logic)
- Nice things: a non-JS expert could come in and make changes in a familiar env
- We used `js-*` prefix in our templates to safely reference them in JavaScript

/////

## Traditional MVC equivalent

Backbone Model & Marionette View

```
var template = require('hb!./incrementer.handlebars');
var IncrementerModel = Backbone.Model.extend({
  defaults: {value: 0}
})
var IncrementerView = Marionette.ItemView.extend({
  template: template,
  ui: {
    incrementButton: '.js-btn'
  },
  events: {
    'click @ui.incrementButton': 'increment'
  },
  modelEvents: {
    'change': 'render'
  },
  increment: function() {
    this.model.set({value: this.model.get('value') + 1})
  }
})
```

NOTES:
- Here's the logic
- Focusing on how the view connected with the template
- The idea is that we wanted to have a "separation of concerns"
- But it didn't happen in practice
- But it was really "separation of technologies"
- But when the template changed, you needed to change the view
- When the model changed, you needed to change the template, and so on
- What we found was, as things got complex, hard to know the effects changing one would have on the other

/////

## JSX is not HTML!

```
class Label extends React.Component {
  render() {
    return (
      <label className="is-hidden" htmlFor={this.props.inputId}>
        {this.props.children}
      </label>
    )
  }
}
```

React JSX props mirror HTML DOM properties!

```
let labelNode = document.getElementById('label')
labelNode.className = 'is-hidden'
labelNode.htmlFor = this.props.inputId
```

NOTES:
- One other thing, is that although JSX looks like HTML, it's not
- We're creating a custom `<Label>` component
- The `className` & `htmlFor` props should make it clear that this isn't HTML
- React chose to mirror the JS DOM API for its props which are all camelCase
- And that's why its `className` & `htmlFor` instead of the HTML `class` & `for`
- It's also why it's `onClick`, `onChange`, etc.
- React is pretty good at giving great warnings if you forget or mess up
- Especially with React 16

**[ASK ABOUT QUESTIONS]**

=====

2. Component-driven

NOTES:
- The next motivation for the transition was React's component-based architecture

/////

## Everything is a component!

```js
export default class FormField extends React.Component {
  render() {
    const id = this.props.id
    return (
      <div>
        <Label inputId={id}>{this.props.label}</Label>
        <TextInput
          id={id}
          value={this.props.value}
          onChange={this.props.onChange}
        />
      </div>
    )
  }
}
```

NOTES:
_click through code highlights_

- The sole way you build your UI in React is with "custom" components
- Everything is a component!
- And you build bigger components by combining smaller components w/ markup
- One way we create components is by creating a `class` and extending from `React.Component`
- The component has a `render()` method which is where you define the UI & return JSX
- Here we have a `FormField` component made up of already defined `Label` & `TextInput` components
- Props are how a component is configured; it's an object
- **Click through props:** `FormField` defines 4 `props` (`id`, `label`, `value` & `onChange`)
- It lays out the `Label` & `TextInput` w/in `<div>` and then passes along those props as configuration

/////

## Everything is a component!

```js
import FormField from './FormField'
export default class NameForm extends React.Component {
  render() {
    return (
      <form onSubmit={this._handleSubmit}>
        <FormField
          id="fName"
          label="First"
          value={this.props.fields.fName}
          onChange={this.props.onFieldChange.bind(null, 'fName')}
        />
        <FormField id="lName" ... />
      </form>
    )
  }
}
```

NOTES:
- We include the component by importing it and then using it in `render()` like an HTML tag
- And we configure the props by passing them in via attributes, just like HTML
- Although we're in Javascript using JSX, the HTML-like syntax should feel familiar
- Then you can combine one or more `FormField` components to create a bigger `Form` component

/////

## Everything is a component!

```js
import NameForm from './NameForm'

export default class App extends React.Component {
  _handleFieldChange = (fieldName) => {
    // Do something
  }

  render() {
    return (
      <NameForm
        fields={ {fName: 'Ben', lName: 'Ilegbodu'} }
        onFieldChange={this._handleFieldChange}
      />
    )
  }
}
```

NOTES:
- And keep doing that until you have a full-fledged app
- `App` contains `NameForm` component
- And probably would contain other big components as well: header, footer, navigation, etc.

/////

NOTES:
- Component-driven development seems pretty obvious right?
- All the modern libraries/frameworks are component-driven in their own way
- But not Backbone; you simply could not nest Backbone views
- At Eventbrite, we began to use Marionette; an architecture layer on top of Backbone to help w/ more complex UIs
- The version we were using had Layouts, which could contain Views, which could _be_ layouts so nesting was possible
- But it was not nearly as effortless as what I just showed w/ React
- Configuring the nested views wasn't simple either
- Way too much code to try to put on a slide
- The problem was that the idea of "components" was an add-on in Backbone/Marionette
- As opposed to being a core feature w/ React

**[ASK ABOUT QUESTIONS]**

=====

3. All JavaScript*

NOTES:
- The 3rd reason was React being exclusively JavaScript based
- I have the asterisk there because obviously we're building web apps so CSS is obviously involved
- But I'm conveniently ignoring that for now 😀

/////

## Logic in the template (markup-driven)

```html
<select>
  {{#each values}}
    {{option_value}}
  {{/each}}
</select>
```

```js
Handlebars.registerHelper('option_value', function() {
  if (shouldShow(this)) {
    return new Handlebars.SafeString(
      '<option value="' + this.value + '">'
        + this.display + '</option>'
    )
  }
})
```

NOTES:
- Traditional UI frameworks, like Backbone, are driven by markup
- You create your markup templates separately and then layer interactivity in JS with the framework
- And doing any kind of fancy logic in the template got really, really messy
- Plus we'd basically have to basically learn a new language
- At Eventbrite we registered Handlebars "helpers" so we could call functions in templates
- _explain what is happening_
- Alternative is to do a whole lot of pre-computation in the view to enable the template to be dumb
- Ya know, handlebars didn't even have `else-if`
- So we'd have a nested `if` w/in an `else`'
- Handlebars was so simplistic in its language that it made Backbone a pain to use

/////

## Logic in React Component (logic-driven)

```js
class Selector extends React.Component {
  render() {
    const options = this.props.values.map((info) => {
      if (this._shouldShow(info)) {
        return (
          <option key={info.value} value={info.value}>
            {info.display}
          </option>
        )
      }
    })

    return (<select>{options}</select>)
  }
}
```

NOTES:
- But with React, since our markup is in JavaScript, the logic is in JS
- It's a little... different; not initially intuitive at first glance
- You see... _explain how it works_
- Backbone UI is template-driven, markup was primary and sprinkled in a little logic
- But React is reverse: logic is primary w/ JS and sprinkle in some markup
- We have the full use of JavaScript at our dispoable to build up the JSX to return
- Comes in handy

/////

[![Dan Abramov's tweet about no special JSX API for loops/conditionals](../../img/why-react/dan-abramov-jsx-tweet.png)](https://twitter.com/dan_abramov/status/929136989085093890)

(...but [StackOverflow](https://stackoverflow.com/questions/22876978/loop-inside-react-jsx) 😞)

NOTES:
- Dan tweeted this in response to a request to add conditionals and loops into JSX
- I ❤ JavaScript so the more I can do in JS the better
- I'm glad that I don't have to learn a new API to do conditionals/loops in React
- Because it's JS, I can do whatever JS can do
- But for some though, this is a drawback because you _have_ to know JS pretty well to be effective
- Before if you were solid at HTML/CSS, you could throw in some jQuery & do really well
- Looping and conditionals in JSX is not intuitive
- That's a StackOveflow question about loops that has > 300k views and 520 upvotes!
- Now it's JS or bust, which takes some getting used to

**[ASK ABOUT QUESTIONS]**

=====

4. State-driven

NOTES:
- So far we've talked about (1) JSX, (2) Component-driven & (3) JavaScript
- And so far we've basically been creating static user-interfaces; not user interaction
- To do that the state of the UI has to change over time
- So React components are state-driven instead event-driven, which is more familiar
- This is the hardest thing to wrap your head around if you're new to React
- It's just a different way of building UIs
- But I've found it to be very compelling
- And this is the 4th motivator for the transition away from Backbone to React

/////

## Event-driven jQuery

```html
<div>
  <span class="val">0</span>
  <button class="btnUp">+</button>
</div>
```

```js
$('.btnUp').click(function() {
  var $val = $('.val'),
      currentValue = parseInt($val.html(), 10)

  $val.html(currentValue + 1)
})
```

	0
	<button class="btnUp" style="font-size: 2em" onclick="$('.val').html(+$('.val').html() + 1)">  +  </button>

NOTES:
- Here's some event-driven jQuery code that should be pretty familiar
- Click a button and update `<span>`
- The driver is the event
- This is _really_ easy to follow (imperative), but as app grows in complexity, code turns into crazy spaghetti

/////

## State-driven React

```js
class Incrementer extends React.Component {
  state = {value: 0}

  _handleClick = () => {
    this.setState((prevState) => ({value: prevState.value + 1}))
  }

  render() {
    return (
      <div>
        <span className="val">{this.state.value}</span>
        <button onClick={this._handleClick}>+</button>
      </div>
    )
  }
}
```

NOTES:
_click through code highlights_

- Contrast this with the React code equivalent
- Simplest example of reactivity in React
- **First:** Start off with initial state
- **Second:** Then we render UI based on state (and props)
- **Third:** Handle user click of `+` button
- **Fourth:** Take the previous value of the state (`0`), increment by 1 and then update the state (`setState`)
- It's the handler that does the logic of incrementing the value; separation of concerns!
- And since `value` is already in `state` we don't have to get it from the DOM
- **Fifth:** Then calling `setState` causes `render` to be called again
- Click again and the cycle continues
- In the old world `_handleClick` would've directly manipulated the DOM
- But instead we update the state and that will indirectly update the DOM
- Layer of indirection is hard to wrap head around

/////

## React dev work can be boiled down to...

1. `render()` based on `props` & `state`
1. `onEvent` transform data → `setState()`
1. Profit 🎉

NOTES:
- So basically we do work in two main areas:
- 1/ Define what we're going to `render()` based on `props` & `state`
- Can have conditional logic, loops, other sophisticated logic to determine what to render
- **Skill:** Ability to build layouts with HTML & CSS
- 2/ When events happen, do stuff to transform data to generate new `state` (and `render` again)
- Can also do async transformation by making API calls
- **Skill:** Ability to transform data efficiently; algorithms are really handy
- And the loop continues

**[ASK ABOUT QUESTIONS]**

=====

5. Sophisticated reconciler

(aka Virtual DOM)

NOTES:
- Let's talk about our 5th reason for the transition:
- The killer feature of React: the Reconciler aka Virtual DOM
- Whenever anyone talks about React it's the cool feature they talk about
- Technically "Virtual DOM" is a misnomer

- So up until this point, it's looked like `render()` was rendering to the DOM
- But it's not...

/////

## React reconciler makes efficient updates easy 💯

```js
class Incrementer extends React.Component {
  state = {value: 0}

  _handleClick = () => {
    this.setState((prevState) => ({value: prevState.value + 1}))
  }

  render() {
    return (
      <div>
        <span className="val">{this.state.value}</span>
        <button onClick={this._handleClick}>+</button>
      </div>
    )
  }
}
```

NOTES:
_click through code highlights_

- Let's take our example from before...
- **First:** When we call `setState`...
- **Second:** React calls `render()` w/ updated state
- So it looks like are re-rendering the `<div>` + children each time
- **Third:** When we know all we _really_ are updating is _just_ the `innerHTML` of `<span>`
- `render()` is **not** updating DOM, but building up element hierarchy
- Basically a _new_ virtual representation of the DOM
- The reconciler (aka "Virtual DOM") keeps a copy of DOM, compares w/ newly rendered DOM and only updates changes
- So we don't have to do the hard work of figuring out how to make the "micro updates"
- We can just write our code the easy way: like it re-renders everything
- And React does the hard work of figuring out micro updates
- This is _really_ _really_ nice

/////

## No reconciler in Backbone 😩

```
var IncrementerView = Marionette.ItemView.extend({
  template: template,
  ui: {
    incrementButton: '.js-btn'
  },
  events: {
    'click @ui.incrementButton': 'increment'
  },
  modelEvents: {
    'change': 'render'
  },
  increment: function() {
    this.model.set({value: this.model.get('value') + 1})
  }
})
```

NOTES:
_click through code highlights_

- Here again is the equivalent Marionette code written to be "reactive"
- Probably not how it would normally be written; hard not to after knowing React
- It's pretty straightforward
- **First:** Clicking button calls `increment()`
- **Second:** `increment()` updates model
- **Third:** All `model` changes calls `render()`
- But this will actually re-render the whole template blowing away prev DOM
- This is super inefficient especially for bigger chunks of DOM; will get flashes

/////

## Manual update in Backbone 😭

```
var IncrementerView = Marionette.ItemView.extend({
  template: template,
  ui: {
    incrementButton: '.js-btn',
    value: '.val'
  },
  events: {
    'click @ui.incrementButton': 'increment'
  },
  increment: function() {
    this.model.set({value: this.model.get('value') + 1})
    this.ui.value.html(this.model.get('value'))
  }
})
```

NOTES:
- Instead of listening to model changes and re-rendering
- We _should_ just update the `innerHTML` of the `<span>` ourselves after updating the model
- Full `render` would only be for the initial render
- This is fine for this simple case; very easy to follow
- Nightmare when there are lots of events & states
- Confession: when I _have_ to go back to Marionette I just do it the easy way!
- If you see some UI flashing on Eventbrite, I may be to blame 😂

**[ASK ABOUT QUESTIONS]**

=====

# MORE STUFF

NOTES:
- So those were the Core Motivations
- The ones that will apply to everyone because they are part of the core lib

- Now let's jump into some additional motivations
- They applied to us at Eventbrite, but _may_ not apply to your situation

=====

6. Server-side rendering

(aka "Isomorphic React")

NOTES:
- Let's talk about the 6th reason: server-side rendering or "Isomorphic React"
- "Isomorphic JavaScript" or "Isomorphic React" is the idea of using the same templates rendered client-side on initial server render

/////

## Isomorphic React

Performance

SEO

Open Graph

NOTES:
- Three reasons:
- Performance: initial page render
- SEO: Google doesn't have to execute your JS to get meaningful data + they includes page render speed in ranking algorithm
- Open Graph: media previews
- React, unlike other JS frameworks/libraries, is setup to render server-side, as we'll see
- Want to emphasize that I'm talking about the _initial_ render

/////

## React components only define **WHAT** to render!

```js
class Incrementer extends React.Component {
  state = {value: 0}

  _handleClick = () => {
    this.setState((prevState) => ({value: prevState.value + 1}))
  }

  render() {
    return (
      <div>
        <span className="val">{this.state.value}</span>
        <button onClick={this._handleClick}>+</button>
      </div>
    )
  }
}
```

NOTES:
- Let's return to our old friend the `Incrementer` component
- Up until this point I've kind of made it seem like `render()` after reconciliation was rendering to the DOM
- But event that's not true!
- `render()` just informs _what_ elements & child components should be rendered
- It doesn't dictate _how_ they should be rendered

/////

## DOM rendering happens at the root

```js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'

const props = window.__SERVER_DATA__ || {}

ReactDOM.hydrate(
  <App {..props} />,
  document.getElementById('root')
)
```

([`ReactDOM.hydrate`](https://reactjs.org/docs/react-dom.html#hydrate) is new in React 16)

NOTES:
_click through code highlights_

- Rendering to the DOM typically happens in the entry point of your app
- **First:** You'll import from `react-dom`
- **Second:** Then use it's `hydrate()` function (new to React 16)
- Inserts your app into the DOM location
- When your app updates, it produces a new component hierarchy
- `react-dom` is what takes that difference from reconciler and applies it to the DOM
- I bring up that distinction because that separation between building your UI and rendering to DOM...

/////

## Render to string server-side!

```js
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import App from './App'

const props = {
  // Data coalesced from DB / API calls
  // Data coalesced from Express GET/POST params
  // Data coalesced from other environment params
}

const markup = ReactDOMServer.renderToString(<App {...props} />)

// return `markup` in HTML response
// assign `props` to `window.__SERVER_DATA__` in HTML response
```

NOTES:
- Allows for us to render the _exact same_ UI server-side to a string!
- Take that string and include it in HTML response
- This is such a huge feature!
- Before this, all UI libraries just assumed the DOM and browser
- So getting your templates to run server-side was at best a pain; at worst in possible
- But now React allows us to do isomorphic javascript

/////

+

([pybars](https://github.com/wbond/pybars3))

NOTES:
- At Eventbrite our backend is in Python/Django
- Currently solved the “dual rendering issue” using a lib called Pybars
- Our JS templates are written in Handlebars & Pybars converts the Handlebars into Python functions
  that return a string
- It's like what happens in the original JS
- Except it's super-duper slow because it was poorly written
- Tried to speed it up, but it was still like 10x slower than rendering in Django/Mako templates

**[ASK ABOUT QUESTIONS]**

=====

7. Testing

NOTES:
- The same component-based architecture that makes server-side rendering easy, also makes testing React components easy
- Since Backbone views were directly manipulating the DOM, they were hard to test
- Pretty much had to run tests in a browser or headless browser which brought a host of issues
- So the 7th reason for transition is about making testing life far simpler

/////

## Test public API only!

```js
class Incrementer extends React.Component {
  state = {value: 0}

  _handleClick = () => {
    this.setState((prevState) => ({value: prevState.value + 1}), () => {
      this.props.onIncrement(this.state.value)
    })
  }

  render() {
    return (
      <div>
        <span className="val">{this.state.value}</span>
        <button onClick={this._handleClick}>+</button>
      </div>
    )
  }
}
```

```
<Incrementer onIncrement={this._handleIncrement} />
```

NOTES:
- Again we have ol' faithful the `Incrementer` component
- Except this time after we click and update state, we also call `onIncrement` event handler prop
- We pass it `this.state.value` as a parameter
- At the bottom is an example of how you would call it
- We want to test the component's **public** API only:
- The markup that it renders and the callback handlers it calls
- That's it! Want to avoid testing implementation details like `state` changes

/////

## Testing Render

```js
import {mount} from 'enzyme'

it('renders a `.val`', () => {
  const wrapper = mount(<Incrementer />)

  expect(wraper.find('.val')).toBePresent()
  expect(wrapper.find('.val')).toHaveText('0')
})
```

[Jest](https://facebook.github.io/jest/) + [Enzyme](http://airbnb.io/enzyme/) +
[`jest-enzyme`](https://yarnpkg.com/en/package/jest-enzyme) = 😍

NOTES:
_click through code highlights_

- We can test `Incrementer` using Enzyme to test the public API
- Enzyme has a jQuery-like interface for manipulating React components _all without a browser_
- "Rendering" is creating an enzyme wrapper
- We use Jest as the test framework & assertion lib; also created by Facebook
- `jest-enzyme` provides additional enzyme-specific assertions to Jest
- **First:** Here we're asserting that `Incremener` renders an element with `.val` class
- **Second:** And that that `.val` element has the text "0" inside of it

/////

## Testing callbacks

```js
import {mount} from 'enzyme'

it('calls `onIncrement` prop with current value', () => {
  const onIncrement = jest.fn()
  const wrapper = mount(<Incrementer onIncrement={onIncrement} />)
  const button = wrapper.find('button')

  // simulate clicking twice
  button.simulate('click')
  button.simulate('click')

  expect(onIncrement).toHaveBeenCalledTimes(2)
  expect(onIncrement).toHaveBeenLastCalledWith(2)
  expect(wrapper.find('.val')).toHaveText('2')
})
```

NOTES:
- If you recall, when we click the button we call our `onIncrement` handler
- We want to verify that when we click the button that `onIncrement` gets called w/ the right parameter
- Well with enzyme we can simulate clicking the button w/o running in a browser!
- **First:** First with Jest we can create a mock function using `jest.fn()`
- **Second:** Then we pass that mock function as `onIncrement` when we shallow render the component
- **Third:** Then we simulate clicking button inside `Incrementer`
- Then we can assert things on that mock:
- **Fourth:** How many times it was called (twice for 2 clicks)
- **Fifth:** What arguments it was last called with (2)
- Again: we shouldn't inspect the `state` of the component (which would be 2)
- Instead we assert on the value in the handler (the public API)
- **Sixth:** Lastly we can assert that the display value has been updated
- Being able to unit test like this is a game-changer
- We don't even really bother in Backbone/Marionette

**[ASK ABOUT QUESTIONS]**

=====

8. React Native

(...and other renderers)

NOTES:
- Let's jump to the 8th reason for transitioning
- Eventbrite has 4 native apps: 2 on iOS & 2 on Android
- One set for people running events (organizer) / other set for people attending (attendee)
- We don't have any plans to replace our apps with React Native
- But should we need other native apps, being able to use React Native is appealing
- Ticketea uses React Native for their mobile apps!

/////

![Learn Once, Write Anywhere screenshot from react homepage](../../img/why-react/react-learn-once-write-anywhere.png)

NOTES:
- One of the benefits React mentions on its home page is that you can "Learn Once, Write Anywhere"
- Basically saying that once you learn React and its paradigms, you can build apps for _any_ environment
- Not just the web

/////

## React for the Web

```js
class Incrementer extends React.Component {
  state = {value: 0}

  _handleClick = () => {
    this.setState((prevState) => ({value: prevState.value + 1}))
  }

  render() {
    return (
      <div>
        <span className="val">{this.state.value}</span>
        <button onClick={this._handleClick}>+</button>
      </div>
    )
  }
}
```

NOTES:
- Let's bring back our good friend the `Incrementer` component one more time
- Here's what it looks like if we were writing for React in the web
- We're using HTML elements: `<div>`, `<span>` & `<button>`
- But...

/////

## React Native 😄

```js
import {View, Text, TouchableOpacity} from 'react-native'
class Incrementer extends React.Component {
  state = {value: 0}
  _handlePress = () => {
    this.setState((prevState) => ({value: prevState.value + 1}))
  }
  render() {
    return (
      <View>
        <Text style={...}>{this.state.value}</Text>
        <TouchableOpacity onPress={this._handlePress}>+</TouchableOpacity>
      </View>
    )
  }
}
```

NOTES:
- If replaced `<div>`, `<span>` & `<button>` w/ `View`, `Text` & `TouchableOpacity` components from
  `react-native`
- You've got the makings of a native app!
- I remember when I went to a React Native workshop and was blown away
- Everything I learned building React web apps, I could leverage in React Native
- Just like w/ the web there are special considerations for native of course
- For instance, layout engine is different
- But there are a bunch more pre-built components
- And React is not just for mobile devices...

/////

## React exists in many environments

  [`ink`](https://github.com/vadimdemedes/ink)
  [`noop-renderer`](https://github.com/facebook/react/blob/master/src/renderers/noop/ReactNoop.js)
  [`rax`](https://github.com/alibaba/rax)
  [`react-art`](https://github.com/reactjs/react-art)
  [`react-blessed`](https://github.com/Yomguithereal/react-blessed)
  [`react-canvas`](https://github.com/Flipboard/react-canvas)
  [_**`react-dom`**_](https://github.com/facebook/react/tree/master/packages/react-dom)
  [`react-fs-renderer`](https://github.com/ericvicenti/react-fs-renderer)
  [`React-Gibbon`](http://techblog.netflix.com/2017/01/crafting-high-performance-tv-user.html)
  [`React-GL`](https://github.com/PixelsCommander/React-GL)
  [`react-hardware`](https://github.com/iamdustan/react-hardware)
  [`react-html-email`](https://github.com/chromakode/react-html-email)
  [`react-konsul`](https://github.com/mohebifar/konsul)
  [_**`react-native`**_](https://github.com/facebook/react-native)
  [`react-pdf`](https://github.com/diegomura/react-pdf)
  [_**`react-sketchapp`**_](https://github.com/airbnb/react-sketchapp)
  [_**`react-test-renderer`**_](https://www.npmjs.com/package/react-test-renderer)
  [`react-three`](https://github.com/Izzimach/react-three)
  [`react-titanium`](https://github.com/yuchi/react-titanium)
  [`react-tvml`](https://github.com/ramitos/react-tvml)
  [_**`react-vr`**_](https://github.com/facebookincubator/react-vr)
  [`react-worker-dom`](https://github.com/web-perf/react-worker-dom)
  [`react-x11`](https://github.com/sidorares/react-x11)
  [`ReactLiberty`](https://github.com/LibertyGlobal/ReactLiberty)

Source: [`awesome-react-renderer`](https://github.com/chentsulin/awesome-react-renderer)

NOTES:
- React is everywhere! Got 24 renderers listed here!
- And the new Fiber architecture should make building new renderers easier
- Remember the Reconciler determines what in the UI should change on re-render
- The renderer actually applies the changes in the environment
- We're pretty excited about `react-sketchapp` from Airbnb
- Just discovered `react-html-email`; need to look into that one!
- These are all links so feel free to check them out!

**[ASK ABOUT QUESTIONS]**

=====

9. Miscellaneous

NOTES:
- Ok, the final reason that Eventbrite wanted to migrate to React is a sort of catch-all
- There are many other reason for going for React
- Don't really deserve their own section (and I don't have hours), but still important...

/////

## Other considerations

Deep commitment by Facebook

Dedicated Facebook dev staff

Rapid feedback loop

Huge ecosystem

Simple API

Popular

Stable

Evolving

Codemods

Developer Tools

Browser compatibility

Composable with existing apps

Thanks [Cory House 🏠](https://twitter.com/housecor/status/909145686498775040)!

NOTES:
- **Commitment**: Facebook uses it in their own products so less likely to go away
- **Staff**: is a big reason; it's not just some folks doing it in their spare time
- **Popular**: not a good enough reason by itself but doesn't hurt for recruiting/perception
- **Simple API**: I rarely have to go to the docs (except for prop types)
- **Ecosystem**: Similarly the eco-system is huge so if you need to do something probably already
  exists
- **Feedback**: React + webpack makes developing a sync with webpack dev server
- **Evolving + Stable**: React continues to grow greatly (Fiber) but few breaking changes & there
  are long deprecations
- **Codemods**: enable switching code when features are deprecated
- **Existing apps**: React _can_ be used with other libs like Backbone for a gradual transition
  (what we're doing)
- This list was lifted from a tweet from Cory, so thanks!

**[ASK ABOUT QUESTIONS]**

=====

## Recap

Declarative JSX

Component-driven

All JavaScript*

State-driven

Sophisticated reconciler

Server-side rendering

Testing

React Native

...and more!

NOTES:
- Again these are the reasons **we** made the switch to React
- I really wish I could've gone into more details on each one
- Each one literally could be its own talk
- Talked about how JSX provides great developer ergonomics
- The fact that it's component-driven not only makes it easy to build UIs
- But also enables the reconciler, server-side rendering, testing & dozens of other renders
- It's state-driven instead of event-driven and we can use at lot of the latest JavaScript in our apps
- And many other goodies!
- My favorite one is the sophisticated reconciler!

=====

## Eventbrite Design System

  <video data-autoplay loop style="width: 80%">
    <source data-src="../../img/why-react/eventbrite-design-system.m4v" />
  </video>

NOTES:
- It's filled with dozens of React components big and small
- But it's more than a component library; it's a design system
- Talks about _why_ components should be used, etc

=====

## Additional resources

- [The Beginner's Guide to ReactJS](https://egghead.io/courses/the-beginner-s-guide-to-reactjs)
- [Advanced React Component Patterns](https://egghead.io/courses/advanced-react-component-patterns)
- [Eventbrite React coding styleguide](https://github.com/eventbrite/javascript/tree/master/react)
- [Eventbrite ES6+ coding styleguide](https://github.com/eventbrite/javascript/tree/master/es6)
- [Eventbrite React Testing Best Practices](https://github.com/eventbrite/javascript/blob/master/react/testing.md)
- [React/Redux Links](https://github.com/markerikson/react-redux-links)

NOTES:
- Mark (w/ help) has collection a bazillion links to resources covering React, Redux, ES6 and more!

=====

![Jack Sparrow Thanks](../../img/giphy/thanks-jack-sparrow.gif)

## Ben Ilegbodu

[benmvp.com](/) | [@benmvp](https://twitter.com/benmvp) | [ben<EMAIL_ADDRESS>
[github/benmvp](https://github.com/benmvp)

Ask me anything! [benmvp.com/ama](http://www.benmvp.com/ama/)

NOTES:
- So before I close...
- My goal is for you to learn at least one thing you can take away to be a better dev
- Hopefully if you are in the same boat of wanting to transition, you've got some good material
- Slides are available on Twitter and Blog
- Would love to hear from you about things that were unclear, wanna know more about or general questions
- Ask on Twitter, via AMA or email

repository: tomByrer/slides

repo_name: tomByrer/slides


text:
# Box mount video magnifier
This setup uses a square box with a diagonal camera arm. Box and arm can be laser-cut, while you may want to 3d-print the camera enclosure or build it from plastic. If you position the magnifier on the side and not behind the object, you also have to adapt the ROTATION in the magni.py script. Image quality is worse when positioned sideways (with rotation 90 or 270).

This is more of a prototype that someone might want to expand on.

![Magni sideways](box-magni-with-book.jpg)

## Ingredients
* 2 Push-buttons (3cm diameter) and cables (like this [arcade set](https://www.amazon.de/dp/B06XDG6PC1))
* Wood glue
* ~A3 sized ply wood (4mm thick, laser-cuttable)
* Access to a laser-cutter
* LED lamp (optional, not shown here)

## Building
Cut the wood according to this [SVG for laser-cutter box](box-magni-laser-4mm.svg). Red lines should be cut, green just marked and blue can be carved for cables to add an LED light. The design hasn't taken into account that laser cuts also have a width, so the parts will not be stable just by combining them, but the wood needs to be glued.
For illustration purpose here's an older [pdf for laser-cutter box](box-magni-laser-a4.pdf), which does not contain the camera arm and may not be adapted to 4mm wood.

![Camera enclosing](box-magni-camera-case.jpg)

## Usage
One push-button steps through magnification levels, the other toggles colour inversion.

license: MIT

repository: ctrlw/magni

branch_name: refs/heads/master

extension: md

license_type: permissive

repo_name: ctrlw/magni


text:
---
abstract: "Are you a beginner worried about starting your first Django project? It\
  \ can be so intimidating! Add in costly mistakes and you\u2019ll find yourself scrapping\
  \ your project and starting over like I did. Twice. (Okay, fine. Three times.) Come\
  \ to this talk for a handful of tips, and a lot of high-fives."
accepted: true
category: talk
date: 2017-08-15 12:20:00 -0500
difficulty: Beginner
layout: session-details
permalink: /talks/stumbling-through-django-and-how-not-to/
presenters:
- bio: "Melanie is a creator, tinkerer, and prisoner of hope (h/t Cornel West). She\
    \ peddles happiness at [FiveUpApp.com](http://www.fiveupapp.com), and has been\
    \ known to engage in high-fivery. (Especially windmill high-fives.)\r\n\r\nMelanie\
    \ has been learning Python and Django for a handful of years and doesn't plan\
    \ to stop. She is an organizer with PyLadies San Diego, the San Diego Python User\
    \ Group, and Django Girls San Diego. She loves helping people get their feet wet\
    \ in programming, and helping promote diversity in tech.  And you."
  company: ''
  github: ''
  name: Melanie Crutchfield
  photo_url: 'https://www.gravatar.com/avatar/3c6d60e22a885e2725666dd57612d690?s=400'
  twitter: hellomelaniec
  website: http://www.melaniecrutchfield.com
room: 'Ballrooms B and C'
sitemap: true
slides_url: ''
title: Stumbling Through Django and How Not To
video_url: 'https://youtu.be/QnJx95MpWMg'
---

If you’re a beginner about to embark on a new Django project adventure, this talk is for you.

When I started my first Django project, I took the “Sure, I think I can figure that out” approach, which is fun! And also dangerous. But exciting! And also horrible because I caused myself a lot of trouble and barfed on my keyboard. (Metaphorically.) Oops.

My hope for this talk is to pass along lessons I learned the hard way, and save the world. Or at least prevent some frustration. :) We'll talk about version control, structuring your project, and how to handle top secret stuff. We’ll also talk about throwing house parties without causing anaphylaxis, pregnant daddy seahorses, velociraptors, and friends. I promise all of that is related to Django.


text:
# pep8.vim: A Vim quickfix plugin for Pep8

## About

pep8.vim runs [Pep8](https://pypi.python.org/pypi/pep8) on your Python code, and
lets you use the quickfix panel to bring it up to snuff.

It only requires `pep8` to be in your path.  The easiest way is via
[Pip](https://pypi.python.org/pypi/pip).  Install that, and then

    pip install pep8

## Installation

Use [Vundle](https://github.com/gmarik/vundle) or
[Pathogen](https://github.com/tpope/vim-pathogen/).  Easy!

## Usage

Open a file you want to de-lint, then simply do

    :Pep8

The quickfix window will open, and you can use `j` and `k` to navigate through
the error list, `<CR>` to select an error to jump to and fix, and `q` to close
the quickfix window.

## License

Copyright (c) 2013 A.N.M. "Roni" Imroz Choudhury

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.


text:
## Description

This test checks a POST operation to the Kubernetes API server for a SubjectAccessReview. It checks for delete access to the namespace of the request, and allows or denies the request.

## Expected Behavior

The test resource should be allowed to be created in the test namespace but not in the `default` namespace, as Kyverno cannot delete it.

## Reference Issues

https://github.com/kyverno/kyverno/issues/1717

https://github.com/kyverno/kyverno/issues/6857

repository: kyverno/kyverno

branch_name: refs/heads/main

gha_language: Go

repo_name: kyverno/kyverno


text:
[![Stories in Ready](https://badge.waffle.io/dairycart/dairycart.png?label=ready&title=Ready)](https://waffle.io/dairycart/dairycart?utm_source=badge)
# Dairycart  [![Build Status](https://travis-ci.org/dairycart/dairycart.svg?branch=master)](https://travis-ci.org/dairycart/dairycart) [![codecov](https://codecov.io/gh/dairycart/dairycart/branch/master/graph/badge.svg)](https://codecov.io/gh/dairycart/dairycart)

Dairycart is an open-source eCommerce platform written in Go.

## Status

Dairycart is currently pre-Alpha, and isn't suitable for production use as of yet. There is no stable, defined API, and until version 1.0 is released and tagged, any route should be considered volatile and subject to change with no notice.

## Dependencies

To run Dairycart locally, all you need is Docker, and a bash terminal. :simple-smile:

## Running

To run the Dairycart API server, simply execute `debug.sh` after cloning this repository locally.

## Testing

There are two test suites, currently, a set of unit tests for the API server, and a suite of integration tests, which attempt to test the API server with real-world style requests. You can run the unit tests by executing `run_unit_tests.sh`, and you can run the integraiton tests similarly by executing `run_integration_tests.sh`

## Trello

The Trello board for this project can be found [here](https://trello.com/b/z3lgKd59/dairycart)

## Reporting Issues

Thusfar, Dairycart's development has been a solo effort, and this may still be the case for some time. That being the case, there are most definitely issues with the
code that warrant reporting. Any issues can be reported using the [Github Issue Tracker](https://github.com/dairycart/dairycart/issues/new) for this repository. Please ensure any issues filed adhere to the [Code of Conduct](CODE_OF_CONDUCT.md).

## Getting involved

General instructions on _how_ to contribute can be found in [CONTRIBUTING](CONTRIBUTING.md).

## Open source licensing info

This project is licensed under the [MIT License](https://en.wikipedia.org/wiki/MIT_License)

A big thanks to the [CFPB](https://github.com/cfpb/open-source-project-template) for the template this file is based on.

repository: waffle-iron/dairycart

repo_name: waffle-iron/dairycart


text:
# sensor-monitor-switch-interrupt
A simple project that makes use of the [SensorMonitor](https://github.com/trojanc/SensorMonitor) library to poll a switch's state and uses an interrupt to force an immediate update.

## Prerequisites
You need to have platformio installed to run this code (If you feel like it, you can adapt it to run in the usual Arduino IDE). This code is also provided in the `examples` of the SensorMonitor library and can be opened in Arduino IDE directly.

Initialise the project with
```platformio init```

Change the board in `platformio.ini` to match your device

## Running the code
```platformio run --target upload```

## Monitor output
```platformio device monitor```

repository: trojanc/learn-arduino

repo_name: trojanc/learn-arduino


text:
---
layout: post
title: "No-code Site Builders for Making Struggle-First Landing Pages"
categories: struggle-first
tags: showcase tools
showcased:
  - sharpen.page
author: Pascal Laliberté
image: /assets/images/posts/2020-12-04-no-code-site-builders-for-struggle-first-landing-pages.jpg
published: true
related_posts:
  - 2020-07-10-visitors-will-excuse-your-unstyled-landing-page
  - 2020-07-03-communicating-your-product-when-hard-to-explain
  - 2020-05-22-bunch-of-example-landing-pages-with-mostly-just-text
  - 2020-05-08-too-much-text-what-to-do-about-that-feedback
  - 2020-04-17-best-order-of-elements-on-landing-page
  - 2020-01-17-level-3-sharpening-so-you-can-rely-less-on-sales
  - 2019-12-13-four-ways-to-say-theres-a-better-way
  - 2019-11-22-bounce-rate-overrated
  - 2019-11-01-sharp-example-applicationemail
  - 2019-10-25-minimum-to-get-struggle-based-landing-page
  - 2019-08-02-increase-ebook-sales-without-buy-now-popups
  - 2019-06-20-i-dont-know-if-my-page-is-good
excerpt:
  "Most no-code site builders will get you landing pages that look pretty typical: here's the product, here's the call to action, here are the features, three column layouts, buy now. But I lean towards text-heavy, struggle-first landing pages that make visitors feel understood. I took three no-code site builders, and checked how they fared. (They come out pretty good)."
---

We're fans here of creating landing pages that have a lot of text, that start off by mirroring to the visitor the struggle they're going through, and that use nice styling to make the page easy to scan, scroll, and read.

I call this type of landing page struggle-first pages.

Let's see if we can reproduce one of my own struggle-first pages using the following no-code site builders. (We can.)

* Squarespace (pretty good)
* WordPress using the Block Editor (surprisingly good)
* Carrd (my favorite so far)

## The Page We'll Be Reproducing And What I Was Looking For

The page I wanted to reproduce was the one for my old **/understand** service offering.

![Full page screenshot of the /understand service offering page](/assets/images/posts/2020-12-04-no-code-site-builders-for-struggle-first-landing-pages-01.jpg)
{: .img-zoom }

Most no-code site builders are good at making typical three column layouts, a big hero at the top, fixed-width text, image+text sections.

But can they do the following?

1. Allow having **text blocks with different widths**, but overall always being **left justified so the eye always scans** the left side of the screen;
2. **Allow differently-sized headings**, where the heading size is not bound to the h1/h2/h3 hierarchy (e.g. have a h2 that's larger than normal to **create contextual contrast**), and allow **differently-sized paragraph text**, also to create contextual contrast;
3. Bonus: **match the same visual styling as the existing page**.

## Videos to See Each Tool In Detail

Overall all three tools did okay.

**Squarespace** made it easy to change the width of text blocks. The page didn't end up having the same style, but in a pinch, I thought it made for a nice tool to work with and nicely-thought-out constraints to balance simplicity and flexibility. One constraint that wasn't too great: to change the size of a heading, you need to change to another heading level (e.g. h2 instead of h3).

{% include video-thumbnail.html video_id="2020-05-21-squarespace" %}

**WordPress using the Block Editor** was surprisingly good. The Block Editor allowed me to have text that's in boxes of different widths, plus I could easily change the size of a heading without changing to another heading level. I couldn't match the styling as much, however.

{% include video-thumbnail.html video_id="2020-05-29-wordpress-block-editor" %}

**Carrd** was my favorite tool so far. I could reproduce the layout, have different widths for different text blocks, I could change the text size at will, plus, I could achieve a very close styling. One important note: Carrd is for one-page websites. Overall, though, I was impressed with Carrd.

{% include video-thumbnail.html video_id="2020-06-04-carrd" %}

---

So overall I was pretty impressed with these no-code tools. Hope you give a struggle-first layout a shot for your next landing page.

Stay sharp.

gha_language: SCSS

gha_license_id: MIT


text:
---
identifier: MIR:00000578
name: Kyoto Encyclopedia of Genes and Genomes
description: Kyoto Encyclopedia of Genes and Genomes (KEGG) is a database resource for understanding high-level functions and utilities of the biological system, such as the cell, the organism and the ecosystem, from molecular-level information, especially large-scale molecular datasets generated by genome sequencing and other high-throughput experimental technologies.
prefix: kegg
pattern: ^([CHDEGTMKR]\d+)|(\w+:[\w\d\.-]*)|([a-z]{3,5})|(\w{2,4}\d{5})$
prefixed: 0
local_id: hsa00190
synonyms:
 - KEGG
resources:
 - identifier: MIR:00100773
   accessurl: http://www.kegg.jp/entry/${lid}
   keyword: phosphorylation
   description: KEGG at Kyoto University Bioinformatics Center
   homepage: http://www.kegg.jp/
   institution: Kyoto University Bioinformatics Center
   location: Japan
   official: false
---

repository: cmungall/registry

repo_name: cmungall/registry


text:
Common code needed by the other Yt gems
=======================================

Yt::Support provides common functionality to all Yt gems.
It is considered suitable for internal use only at this time.

The **source code** is available on [GitHub](https://github.com/fullscreen/yt-support) and the **documentation** on [RubyDoc](http://www.rubydoc.info/gems/yt-support/frames).

[![Build Status](http://img.shields.io/travis/Fullscreen/yt-support/master.svg)](https://travis-ci.org/Fullscreen/yt-support)
[![Coverage Status](http://img.shields.io/coveralls/Fullscreen/yt-support/master.svg)](https://coveralls.io/r/Fullscreen/yt-support)
[![Dependency Status](http://img.shields.io/gemnasium/Fullscreen/yt-support.svg)](https://gemnasium.com/Fullscreen/yt-support)
[![Code Climate](http://img.shields.io/codeclimate/github/Fullscreen/yt-support.svg)](https://codeclimate.com/github/Fullscreen/yt-support)
[![Online docs](http://img.shields.io/badge/docs-✓-green.svg)](http://www.rubydoc.info/gems/yt-support/frames)
[![Gem Version](http://img.shields.io/gem/v/yt-support.svg)](http://rubygems.org/gems/yt-support)

Yt::Support provides:

* [Yt.configure](http://www.rubydoc.info/gems/yt-support/Yt/Config#configure-instance_method)
* [Yt::Configuration](http://www.rubydoc.info/gems/yt-support/Yt/Configuration)
* [Yt::HTTPRequest](http://www.rubydoc.info/gems/yt-support/Yt/HTTPRequest)
* [Yt::HTTPError](http://www.rubydoc.info/gems/yt-support/Yt/HTTPError)
* [Yt::ConnectionError](http://www.rubydoc.info/gems/yt-support/Yt/ConnectionError)

How to contribute
=================

Contribute to the code by forking the project, adding the missing code,
writing the appropriate tests and submitting a pull request.

In order for a PR to be approved, all the tests need to pass and all the public
methods need to be documented and listed in the guides. Remember:

- to run all tests locally: `bundle exec rspec`
- to generate the docs locally: `bundle exec yard`
- to list undocumented methods: `bundle exec yard stats --list-undoc`


text:
# Development Roadmap

## Environments, tools and configurations

1. Set up the TravisCI([ref1](https://houssein.me/continuous-integration-angular-firebase-travisci), [ref2](https://angular.io/guide/testing))

   TODO: use cache to reduce build time

2. Initialize the project

3. Login, register and alert component

   1. TODO: alert service provide an observable to pass through message

   2. TODO: Use Angular Router Guard to forbid the user to visit before he has logined

   3.
## Tips

1. Use `npx` to run `angular cli` locally;


text:
---
# Display name
name: Alex Ludwig

# Username (this should match the folder name)
authors:
-aludwig25

# Is this the primary user of the site?
superuser: true

# Role/position
role: Assistant Professor of Liberal Arts

# Organizations/Affiliations
organizations:
- name: Berklee College of Music
  url: "berklee.edu"

# Short bio (displayed in user profile at end of posts)
bio: My research interests include Sonata Theory, Joseph Haydn, and Film Music.

interests:
- String Quartets
- Dies Irae
- Filmed Musicals

education:
  courses:
  - course: PhD in Musicology
    institution: Brandeis University
    year: 2010
  - course: MFA in Musicology
    institution: Brandeis University
    year: 2003
  - course: BM in String Performance, Cello
    institution: Boston University
    year: 2001

# Social/Academic Networking
# For available icons, see: https://sourcethemes.com/academic/docs/page-builder/#icons
#   For an email link, use "fas" icon pack, "envelope" icon, and a link in the
#   form<EMAIL_ADDRESS>or "#contact" for contact widget.
social:
- icon: envelope
  icon_pack: fas
  link: '#contact'  # For a direct email link, use<EMAIL_ADDRESS>- icon: twitter
  icon_pack: fab
  link: https://twitter.com/GeorgeCushen
- icon: google-scholar
  icon_pack: ai
  link: https://scholar.google.co.uk/citations?user=sIwtMXoAAAAJ
- icon: github
  icon_pack: fab
  link: https://github.com/gcushen
# Link to a PDF of your resume/CV from the About widget.
# To enable, copy your resume/CV to `static/files/cv.pdf` and uncomment the lines below.
# - icon: cv
#   icon_pack: ai
#   link: files/cv.pdf

# Enter email to display Gravatar (if Gravatar enabled in Config)
email: ""

# Organizational groups that you belong to (for People widget)
#   Set this to `[]` or comment out if you are not using People widget.
user_groups:
- Researchers
- Visitors
---

Alex Ludwig is an assistant professor of liberal arts at Berklee College of Music. I teach a variety of courses in music history, including topics in Rock History, Viennese Modernism, and Film Music. In addition, I catalogue examples of film that include musical references to the gregorian chant, "Dies Irae."

When I'm not in the classroom, I enjoy playing and coaching soccer, watching hockey, and studying movie musicals.


text:
witchcraft-go-params
====================
[![](https://godoc.org/github.com/palantir/witchcraft-go-params?status.svg)](http://godoc.org/github.com/palantir/witchcraft-go-params)

`witchcraft-go-params` defines the `wparams` package, which provides the `ParamStorer` interface and functions for
storing and retrieving `ParamStorer` implementations in from a context.

Conceptually, "params" are values that are associated with a specific key that provide context about an operation that
is being performed. Params are categorized as "safe" or "unsafe" -- "safe" params are parameters which are considered
safe to ship/export/expose off-premises, while "unsafe" parameters are parameters that should not leave the premises.
Param values are typically used by things such as loggers and errors to provide further context for an operation. Keys
are case-sensitive and must be unique across both safe and unsafe parameters.

The following is a short example of a canonical use case:

```go
type UserID int64

func UpdateUserInfo(ctx context.Context, userID UserID, info UserInfo) error {
	ctx = wparams.ContextWithSafeParam(ctx, "userId", userID)

	svc1log.FromContext(ctx).Info("Updating user information", svc1log.Params(wparams.ParamsFromContext(ctx)))
	if err := validateInput(ctx, info); err != nil {
		return err
	}
	// ...
	return nil
}

func validateInput(ctx context.Context, info UserInfo) error {
    if info.Name == "" {
        return werror.Error("invalid user info", werror.Params(wparams.ParamsFromContext(ctx)))
    }
	// ...
	return nil
}
```

In this example, "userId" and its value are registered as a safe parameter on the context at the beginning of the
`UpdateUserInfo` function. This function (and the other functions that it calls) extract the safe and unsafe parameters
from the context when performing operations such as logging or creating errors. This makes it such that the logger
messages and errors are provided with all of the relevant parameters for their operation, along with the knowledge of
whether the parameters are safe and unsafe.

If a specific type will be recorded as a parameter often and there is a sensible default value for its name and
safe/unsafe status, it may make sense to have the type implement the `ParamStorer` interface directly. For example, if
`UserID` is known to be safe and should always be recorded as "userId", the example above could be updated as follows:

```go
type UserID int64

func (id UserID) SafeParams() map[string]interface{} {
	return map[string]interface{}{
		"userId": id,
	}
}

func (id UserID) UnsafeParams() map[string]interface{} {
	return nil
}

func UpdateUserInfo(ctx context.Context, userID UserID, info UserInfo) error {
	ctx = wparams.ContextWithParams(ctx, userID)
    // the rest is the same as the first example
}
```

This pattern allows a type to dictate its default behavior for its name and whether it is safe/unsafe, which makes it
easier to ensure that the parameter is consistent across various usages.

License
-------
This project is made available under the [Apache 2.0 License](http://www.apache.org/licenses/LICENSE-2.0).


text:
# `resolve-storage-mongo`

This package serves as a driver for `resolve-storage` to store events using MongoDB.

## Usage

```js
import createDriver from 'resolve-storage-mongo';

const driver = createDriver({
    url: 'mongo_url',
    collection: 'events'
});
```

repository: alexey-semikozov/resolve

repo_name: alexey-semikozov/resolve


text:
Get Fake
=================================

A sinatra app which helps to get Fake data. It uses Ruby Faker gem to generate Fake data.

Introduction
------------
Check it out @ http://getfake.com

Anil Wadghule | github.com/anildigital | twitter.com/anildigital

repository: AteroConfigs/getfake

extension: markdown

repo_name: AteroConfigs/getfake


text:
## Hands-On Time

---

# Creating A Quickstart Project

## Creating A Project

---

```bash
jx create quickstart -l go -p jx-go -b

export GH_USER=[...] # Replace with your GitHub user

open "https://github.com/$GH_USER/jx-go"

ls -l jx-go

cat jx-go/Dockerfile

cat jx-go/jenkins-x.yml

cat jx-go/Makefile
```

## Creating A Project

---

```bash
cat jx-go/skaffold.yaml

ls -l jx-go/charts

ls -l jx-go/charts/jx-go

ls -l jx-go/charts/preview

open "https://github.com/$GH_USER/jx-go/settings/hooks"
```

## Browsing The Project

---

```bash
kubectl get pods

jx get activities --filter jx-go --watch # Cancel with ctrl+c

jx get build logs --filter jx-go
```

## Browsing The Project

---

```bash
jx get pipelines

jx get env

jx get applications -e staging

open "https://github.com/$GH_USER/jx-go/releases"

jx get applications

STAGING_ADDR=[...]

curl "$STAGING_ADDR"
```

<!-- .slide: data-background="../img/background/developer.jpeg" -->
## You Do NOT Need To Do Any Of That

---

# Focus On What You Should Do


text:
# ἐφ-ίστημι

<!-- Status: S2=NeedsEdits -->
<!-- Lexica used for edits:   -->

## Word data

* Strongs: G21860

* Alternate spellings:

* Principle Parts:

* Part of speech:

* Instances in Scripture: 21

* All Scriptures cited: Yes

## Etymology:

* LXX/Hebrew glosses:

in LXX for [נָצַב](//en-uhl/H5324) ni., [שִׁית](//en-uhl/H7896), [נָתַן](//en-uhl/H5414), etc. ;

* Time Period/Ancient Authors:

* Related words:

* Antonyms for all senses

* Synonyms for all senses:

## Senses

### Sense  1.0:

#### Definition:

#### Glosses:

to set upon;

#### Explanation:

by, set up;

#### Citations:

causal in pres., impf., fut., 1 aor., to set upon or by, set up, etc. (Æsch., Hdt.,   Arist., al).

### Sense  2.0:

#### Definition:

#### Glosses:

#### Explanation:

#### Citations:

Intrans. in mid, and in pf. and 2 aor. act.;

### Sense  2.1:

#### Definition:

#### Glosses:

to stand upon;

#### Explanation:

#### Citations:

to stand upon;

### Sense  2.2:

#### Definition:

#### Glosses:

to be set over;

#### Explanation:

#### Citations:

to be set over;

### Sense  2.3:

#### Definition:

#### Glosses:

to stand by, be present, be at hand, come on;

#### Explanation:

upon;

#### Citations:

to stand by, be present, be at hand, come on or upon: [Lk 2:38](Luk 2:38) [10:40](Luk 10:40) [[20](Act 22:20):1](Luk 20:1), [Ac 6:12](Act 6:12) [12:7](Act 12:7) [22:13](Act 22:13), 20 [23:27](Act 23:27), [II Ti 4:2](2Ti 4:2); c. dat. pers., [Lk 2:9](Luk 2:9) [24:4](Luk 24:4), [Ac 4:1](Act 4:1) [23:11](Act 23:11); c. dat. loc., [Ac 17:5](Act 17:5); seq. [έπί](), c. acc, [Ac 10:17](Act 10:17) [11:11](Act 11:11); of rain, [Ac 28:2](Act 28:2); of evils impending, c. dat. pers., [I Th 5:3](1Th 5:3); seq. [έπί ]()([Wi 6:9](Wis.6.9)), [Lk 21:34](Luk 21:34); of time, [II Ti 4:6](2Ti 4:6) (cf. [κατ-](), [συν-εφίστημι]()).†

repository: mandolyte/uw-obsidian

repo_name: mandolyte/uw-obsidian


text:
# [André Vitor Valle](http://andrevalle.co)

>My personal website.

[![Andre Valle](http://andrevalle.co/img/img-readme.png)](http://andrevalle.co)

### About me

My name is André valle. Working as Front-End Engineer, I'm 21 years old and I live in the city of Rio de Janeiro, Brazil :)

***feel free to contribute to my site:***

1. Install [Git](http://git-scm.com/downloads) and [Ruby](http://www.ruby-lang.org/pt/downloads/), in case you don't have them yet.

2. Once these dependencies installed, _Fork_ for your GitHub.

3. Open up the terminal and _Clone_ the project:

  ```sh
  $ git clone git@github.com:_YouUserName_/andrevvalle.github.io.git
  ```

4. Navigate to the project folder:

  ```sh
  $ cd andrevvalle.github.io
  ```

5. Now let's install the [npm](https://www.npmjs.org/) dependencies:

  ```sh
  $ npm install
  ```

6. Run [Grunt](http://gruntjs.com/):

  ```sh
  $ grunt
  ```

7. Make your changes and then _Commit_:

  ```sh
  $ git commit -a -m "YOU COMMIT"
  ```

8. Now, _Push_ the project.

  ```sh
  $ git push origin master
  ```

9. Sign In to your github and send your _PullRequest_

## Browser Support

![IE](https://cloud.githubusercontent.com/assets/398893/3528325/20373e76-078e-11e4-8e3a-1cb86cf506f0.png) | ![Chrome](https://cloud.githubusercontent.com/assets/398893/3528328/23bc7bc4-078e-11e4-8752-ba2809bf5cce.png) | ![Firefox](https://cloud.githubusercontent.com/assets/398893/3528329/26283ab0-078e-11e4-84d4-db2cf1009953.png) | ![Opera](https://cloud.githubusercontent.com/assets/398893/3528330/27ec9fa8-078e-11e4-95cb-709fd11dac16.png) | ![Safari](https://cloud.githubusercontent.com/assets/398893/3528331/29df8618-078e-11e4-8e3e-ed8ac738693f.png)
--- | --- | --- | --- | --- |
IE 8+ ✔ | Latest ✔ | Latest ✔ | Latest ✔ | Latest ✔ |

### Contact

- Mail<EMAIL_ADDRESS>- Twitter: @andrevalle1

### License

[MIT License](http://andrevalle.mit-license.org/) © Andre Valle

gha_language: HTML


text:
# ANEEB-2021-Python-Workshop

Workshop to learn about Python tools for working with Biomedical data. You will learn these tools while developing real world prototypes of cool projects

## Schedule

- https://bit.ly/3rGqnw9

# Contents

## Pandas
### Pandas 101

- [Learning Notebook](https://colab.research.google.com/github/vohcolab/ANEEB-2021-Python-Workshop/blob/main/Pandas/Pandas%20101/Learning%20notebook%20(Pandas%20101).ipynb)
- [Exercises Notebook](https://colab.research.google.com/github/vohcolab/ANEEB-2021-Python-Workshop/blob/main/Pandas/Pandas%20101/Exercise%20notebook%20(Pandas%20101).ipynb)

### Pandas Advanced

- [Learning Notebook](https://colab.research.google.com/github/vohcolab/ANEEB-2021-Python-Workshop/blob/main/Pandas/Pandas%20Advanced/Learning%20Notebook.ipynb)
- [Exercises Notebook](https://colab.research.google.com/github/vohcolab/ANEEB-2021-Python-Workshop/blob/main/Pandas/Pandas%20Advanced/Exercises%20Notebook.ipynb)

## Time Series with covid data

- [Learning Notebook](https://colab.research.google.com/github/vohcolab/ANEEB-2021-Python-Workshop/blob/main/Pandas/Time%20Series/Intro%20to%20Time%20series/Learning%20Notebook%20-%20Intro%20to%20Time%20Series.ipynb)
- [Exercises Notebook](https://colab.research.google.com/github/vohcolab/ANEEB-2021-Python-Workshop/blob/main/Pandas/Time%20Series/Intro%20to%20Time%20series/Exercise%20Notebook%20-%20Intro%20to%20Time%20Series.ipynb)

# Value for Health Colab

We are a research group that focus on health projects. Our team comes from a variety of backgrounds (economics, managing, linguistics, data science, computer science, ...) which allows us to collaborate in creative and effective ways. You can find more about us or contact us here: https://vohcolab.org. If you are interested in working with us, or having an internship with us, just send us a message :)


text:
# Environment Reference
## Parameters
These are parameters for `pommerman.make`:
### Configurations
Configurations that are included in Pommerman. This is the `config_id` parameter of `pommerman.make` as a String:

* `PommeFFACompetition-v0` - In this all agents are against each other
* `PommeTeamCompetition-v0` - In this teams of two agents each are set against each other. The teams are [Agent0, Agent2] and [Agent1, Agent3]
* `OneVsOne-v0` - In this two agents are against each other
* `PommeFFA-v1` - In this all agents are against each other while the board collapses uniformly by replacing the outermost square with walls
* `PommeTeamCompetition-v1` - This is similar to PommeFFA-v1 but with Teams instead of being Free-For-All
* `PommeRadio-v2` - This is similar to `PommeTeamCompetition-v0` but the agents can send a list of two integers in the range [1, 8] to their teammates on every turn.

### Agents
Agent classes that are included in Pommerman. This is the `agent_list` parameter of `pommerman.make` as a list of 4 agent classes. All of these can be found under `pommerman.agents`:

* `base_agent` - This is the class that all agents inherit from
* `random_agent` - This randomly selects an action and plays it out
* `simple_agent` - This is an agent based on a non-ML approach (This agent is prone to killing itself)
* `tensorforce_agent` - This agent calls [TensorForce](https://github.com/reinforceio/tensorforce) to return an action
* `player_agent` - This is an agent controlled by an keyboard. You can change the control scheme by feeding the `agent_control` parameter as either: `"arrows"` for Arrows = Move and Space = Bomb or `"wasd"` for W,A,S,D = Move, E = Bomb
* `http_agent` - This agent outputs to accepts input in the form of a REST requests to it
* `docker_agent` - This agent outputs and accepts inputs to an agent wrapped inside a Docker container
## Output
![Pommerman-enviroment Output](./assets/pom_env_output.png) *This is the output from env.step()*

It has the following format:

* Board: The 11x11 board is a numpy array where each value corresponds to one of the representations below. The first element in this 2D array corresponds to the configuration of topmost row of the board and so on.
    * Passage = 0
    * Wooden Wall = 1
    * Rigid Wall = 2
    * Bomb = 3
    * Flames = 4
    * Fog = 5: This is only applicable in the partially observed (2v2 Team Radio) setting.
    * Extra Bomb Power-Up = 6: adds ammo.
    * Increase Range Power-Up = 7: increases the blast_strength
    * Can Kick Power-Up = 8: can kick bombs by touching them.
    * AgentDummy = 9
    * Agent0 = 10
    * Agent1 = 11
    * Agent2 = 12
    * Agent3 = 13
* Position: A tuple of Ints of (X position, Y position)
* Ammo: An Int representing the amount of ammo this agent has.
* Blast Strength: An Int representing the blast strength of this agent's bombs.
* Can Kick: Whether this agent can kick bombs. This ability is gained by stepping on the can kick power-up.
* Teammate: One Int in [9, 13].  Which agent is this agent's teammate. In the FFA game, this is the AgentDummy.
* Enemies: A list of three Ints, each in [9, 13]. Which agents are this agent's enemies. There are three here to be amenable to all variants of the game. When there are only two enemies like in the team competitions, the last Int will be the AgentDummy to reflect the fact that there are only two enemies.
* Bomb Blast Strength: An 11x11 numpy int array representing the bombs' blast strengths in the agent's view. Everything outside of its view will be fogged out.
* Bomb Life: An 11x11 numpy int array representing the bombs' life in the agent's view. Everything outside of its view will be fogged out.
* Bomb Movement Direction: An 11x11 numpy int array representing the bombs' movement direction (in terms of an agent's action space: 1 -> up, 2 -> down etc...) in the agent's view. Everything outside of its view will be fogged out.
* Flame Life: An 11x11 numpy int array representing the flames' life in the agent's view. Everything outside of its view will be fogged out.
* Message: (Team Radio only) A list of two Ints, each in [0, 8]. The message being relayed from the teammate. Both ints are zero when a teammate is dead or it's the first step. Otherwise they are in [1, 8].

gha_language: Python


text:
# X3DEditor
3D Element editor of DecUI for VCMP (originally made for buildmode)

# Information
This snippet was made to allow people to easily find position, rotation and size of GUIElement in buildmode when converting an element to 3D. This snippet only supports elements made using DecUI.

#  Prerequisite
- [DecUI](https://github.com/newk5/decui/)

# Installation
1. Click the "Clone or download" button, select "Download ZIP".
1. Extract all the "X3DEditor-master/X3DEditor" folder to "store/script/..here"
1. Add the following code into your script:
```javascript
function Script::ScriptLoad() {
    dofile("X3DEditor/X3DEditor_Main.nut");
}

function Script::ScriptProcess() {
    Sq3DEditor.Process();
}
```

# Usage
Refer to the [wiki](https://github.com/newhere491/X3DEditor/wiki)


text:
---
title: "Swift"
---

# Swift

::: warning
This package is still under development. This page will get more content as it evolves more. In the meantime you can view its source on [Github](https://github.com/ArkEcosystem/swift-client/).
:::

[[toc]]

## Installation

```bash
...
```

## Basics

```swift
...
```

## Connections

```swift
...
```


text:
loose-interval
==============

`loose-interval` Is designed to be similar to `setInterval` but for tasks that you don't want to overlap. Instead of starting the process every `interval` milliseconds, it pauses `interval` milliseconds between the completion and next execution.

[![NPM](https://nodei.co/npm/loose-interval.png)](https://nodei.co/npm/loose-interval/)

```javascript
var looseInterval = require("loose-interval")

// your function must provide a callback to call when it is done
function someSlowTask(callback) {
  /* copy a bunch of files, or scrape a website or something */
  /* phew! that took a while, but I'm done now, let's callback */
  callback(some, cool, args)
}

// Run your task waiting a minute between finish & rexecution
var task = looseInterval(someSlowTask, 60000)

// Execute a callback whenever it completes
var task = looseInterval(someSlowTask, 60000, console.log)

// Stop recurrence of your task
task.stop()

// Run it one time
task.runOnce()
```

API
===

`looseInterval(fn [,interval] [,callback])`
-------------------------------------------

Create a task. Requires a function (which has a callback) to execute. If no interval is given, it will not be executed or recur without `.runOnce` or `.start` being called.

Interval is in milliseconds, and is the pause between your function's completion and next execution.

If a callback is provided, that callback will be executed with whatever arguments your function provides.

`.start(interval)`
------------------

Start or change the interval of a recurring task. Interval is in milliseconds.

`.stop()`
---------

Stop the task for recurring. Can still be executed with `.runOnce` or rescheduled with `.start`

`.runOnce()`
------------

Run the function a single time, without repeating. This does not respect a schedule version and can cause overlapping tasks.

LICENSE
=======

MIT


text:
---
name: Update Playground
about: Use this template when submitting an updated playground link
title: "[update] Playground"
labels: update playground
---

:warning: Do _NOT_ change the Issue Title

<!--
Please provide the project ID. This is the issue number that first created the project. You'll find it as a badge at the top of the project.
-->
## Project Id
- #

<!-- Please past your updated playground link below -->
## Playground
-

<!-- Please provide a short detailed reason for the update/change -->
## Reason

repository: mudlabs/NativeScript-Play-Pit

gha_language: JavaScript

repo_name: mudlabs/NativeScript-Play-Pit


text:
## [Jest](https://jestjs.io/)

```shell
$ quasar ext add @quasar/testing-unit-jest
```

This AE is meant to manage Quasar and Jest integration for you, both for JS and TS.

We have included:

- a preset configuration file (`jest.config.js`);
- a setup file with some common patterns you may want to enable (`/test/jest/jest.setup.js`);
- `mountQuasar` and `mountFactory` helpers which wrap mount functions from "@vue/test-utils";
- two example components (`App.spec` using Vue native `mount` helper, `QBtnDemo` using `mountQuasar` and [Double File Component](#double-file-components-dfc) fashion);
- some useful `package.json` scripts;
- Babel integration;
- TypeScript support.

This AE is a wrapper around official "@vue/test-utils" package, you won't be able to use this or understand most of the documentation if you haven't read [the official documentation](https://vue-test-utils.vuejs.org/).

### mountQuasar(component, options)

Quasar packs quite a lot of features and configuring correctly `mount`/`shallowMount` to work on Quasar CLI projects isn't trivial.
This function incapsulates the configuration needed to bring you up-and-running.

Usage:

```ts
import { mountQuasar } from '@quasar/quasar-app-extension-testing-unit-jest';
import { QBtn } from 'quasar'; // <= cherry pick only the components you actually use
import BookComponent from './BookComponent'; // <= note the absence of `.vue` extension, here we are importing the JS/TS part of a Double File Component

describe('BookComponent', () => {
  test('mounts without errors', () => {
    const wrapper = mountQuasar(BookComponent, {
      quasar: {
        components: {
          QBtn,
        },
      },
      propsData: {
        prop1: 'value',
      },
    });

    expect(wrapper).toBeTruthy();
  });
});
```

The second parameter accepts a configuration object with the following properties:

| Name             | Type                                                       | Default                                   | Description                                                                                |
| ---------------- | ---------------------------------------------------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `mount`          | Object                                                     | `{}`                                      | The [configuration object](https://vue-test-utils.vuejs.org/api/options.html#context) you'd usually provide to `mount` or `shallowMount` helpers                                                                                |
| `mount.type`     | `full` or `shallow`                                        | `shallow`                                 | Determine which mount helper should be used between `mount` or `shallowMount`                                                                                |
| `mount.localVue` | Vue instance                                               | Clean instance by `createLocalVue` helper | Same as corresponding [mount option](https://vue-test-utils.vuejs.org/api/options.html#localvue), except it generates a new one automatically if not provided. Most of the time you won't need to specify it                                                                 |
| `quasar`         | Object                                                     | None                                      | Quasar plugin configuration options, you'll mainly use this to register Quasar components to stub                                                                                |
| `propsData`      | Object                                                     | None                                      | Initial props for the component, will be merged (with precedence) with `mount.propsData`                                                                                |
| `plugins`        | Array of `VuePlugin` or `[VuePlugin, ...VuePluginOptions]` | `[]`                                      | Vue plugins which must be added to the localVue instance (eg. `VueCompositionAPI`). If your plugin needs options, you can provide it as an array where the first element is the plugin itself and following elements are the options (eg. `[VueCompositionAPI, ...options]`) |

### mountFactory(component, options)

Most of the time `mountQuasar` configuration will be the same for all tests inside a test-suite, while initial props will change.
`mountFactory` addresses this scenario: it accepts the same parameters as `mountQuasar`, but returns a function accepting a `propsData` object and returning a wrapper instance.

Usage:

```ts
import { mountFactory } from '@quasar/quasar-app-extension-testing-unit-jest';
import { QBtn } from 'quasar'; // <= cherry pick only the components you actually use
import BookshelfComponent from './BookshelfComponent'; // <= note the absence of `.vue` extension, here we are importing the JS/TS part of a Double File Component

const factory = mountFactory(BookshelfComponent, {
  // mount: { type: 'full' } <= uncomment this line to use `mount`; `shallowMount` is used by default as it will stub all **registered** components found into the template
  quasar: { components: { QBtn } },
});

describe('BookshelfComponent', () => {
  test('mounts without errors', () => {
    const wrapper = factory(); // <= when no props are needed
    // const wrapper = factory({ propName: propValue }); <= when props are needed
    expect(wrapper).toBeTruthy();
  });
});
```

### AE Options

#### SFC Test code block

We have included the optional ability to place your test code inside your vue files, should you choose to do so. It will be rendered by webpack HMR. To run these tests, run `$ quasar test --unit jest --dev` (requires you to use `@quasar/app-extension-testing` to manage testing harnesses).

```vue
<test lang="jest">
  /* your complete test file here */
</test>
```

##### Syntax highlighting

You may notice that your IDE doesn't know how to parse the test block. Follow the instructions below to enable syntax highlighting and/or autocomplete in your specific IDE.

###### Webstorm

- Go to the `<test/>` block, press `<Alt> + <Enter>`
- Select `inject language or reference`
- Then select `javascript`
  - This will grant `<test/>` blocks autocomplete

###### VS Code

The [Vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur) VS Code extension is required.
If you don't already have the Vetur extension installed:

- Launch VS Code Quick Open (`<Ctrl> + <P>`)
- Paste the following command `ext install octref.vetur` then press `<Enter>`

Once you have the Vetur extension installed, you need to configure the custom code block in Vetur.

- Press `<Ctrl> + <Comma>` to launch the _settings editor_ window
- In the search field type `Custom Blocks` to narrow the focus down to `Vetur > Grammar > Custom Blocks`
- Click `Edit in settings.json`
  - This will populate the settings file with the existing configuration block and we will add the following:

```json5
  "vetur.grammar.customBlocks": {
    "test": "js",
    // ... existing block definitions
  }
```

_Note: If you're using TypeScript you can set the language to `ts` instead of `js`._

- Save the changes to `settings.json` (`<Ctrl> + <S>`)
- Launch _'Show All Commands'_ (`<Ctrl> + <Shift> + <P>` or `F1`) and paste `Vetur: Generate grammar` then press `<Enter>`
  - This will regenerate the Vetur grammar file to include the new custom block definition
- Launch _'Show All Commands'_ again (`<Ctrl> + <Shift> + <P>` or `F1`) and paste `Reload Window` then press `<Enter>`
  - This will reload VS Code and apply the new syntax highlighting

---

#### Wallaby.js

You can choose to install Wallaby.js to do inline testing. Although it is not freeware, it is an amazing tool and comes highly recommended. https://wallabyjs.com

#### Majestic

You can choose to install Majestic, which is a UI interface to see how your tests are doing. https://github.com/Raathigesh/majestic

### Caveats

#### Mock i18n

If you're using `VueI18n`, you may want to mock translations. You can easily create Jest mocks for all translation functions and provide them into `options.mocks`.

```ts
import { mountFactory } from '@quasar/quasar-app-extension-testing-unit-jest';
import BookshelfComponent from './BookshelfComponent';

const $t = jest.fn();
$t.mockReturnValue(''); // <= will always provide an empty string
const $tc = jest.fn();
const $n = jest.fn();
const $d = jest.fn();

const factory = mountFactory(BookshelfComponent, {
  mount: {
    mocks: { $t, $tc, $n, $d },
  },
});

describe('BookshelfComponent', () => {
  // ...
});
```

#### Testing QPage components

`QPage` usually only work when placed inside a `QLayout` component because the latter provide some references to other layout components.
You can use `qLayoutInjections` helper function to get an injection stub which will allow you to test `QPage`s in isolation.

```ts
import {
  mountFactory,
  qLayoutInjections,
} from '@quasar/quasar-app-extension-testing-unit-jest';
import BookshelfPage from './BookshelfPage';

const factory = mountFactory(BookshelfPage, {
  mount: {
    provide: qLayoutInjections(),
  },
});

describe('BookshelfPage', () => {
  // ...
});
```

#### Use with VueRouter

You can use VueRouter adding it to a custom `localVue` instance you later provide into `options.mount.localVue`.

```ts
import { mountFactory } from '@quasar/quasar-app-extension-testing-unit-jest';
import VueRouter from 'vue-router';
import BookshelfPage from './BookshelfPage';
import { createLocalVue } from '@vue/test-utils';

const localVue = createLocalVue();
localVue.use(VueRouter);

const factory = mountFactory(BookshelfPage, {
  mount: {
    localVue,
    router: new VueRouter(),
  },
});

describe('BookshelfPage', () => {
  // ...
});
```

#### Use with Vuex

You can use Vuex adding it to a custom `localVue` instance you later provide into `options.mount.localVue`.

```ts
import { mountFactory } from '@quasar/quasar-app-extension-testing-unit-jest';
import Vuex from 'vuex';
import BookshelfPage from './BookshelfPage';
import { createLocalVue } from '@vue/test-utils';

const localVue = createLocalVue();
localVue.use(Vuex);

const factory = mountFactory(BookshelfPage, {
  mount: {
    localVue,
    store: new Vuex({}),
  },
});

describe('BookshelfPage', () => {
  // ...
});
```

#### SSR context

You could need an SSR context if your component uses `Cookies` plugin, `Platform` plugin or `preFetch` feature and you want to test how it behaves into SSR mode. In those cases, you can get a mock via `ssrContextMock`.

#### Cookies

If you're testing `Cookies` usage into your app, you can use `setCookies` helper function. \
If the test involves SSR mode, you can use `ssrContextMock` helper function to get a mock of the SSR context and provide it to `setCookies`.

```ts
import {
  getCookies,
  ssrContextMock,
} from '@quasar/quasar-app-extension-testing-unit-jest';

const cookies = {
  // ...
};

setCookies(cookies);
setCookies(cookies, ssrContextMock());
```

#### TypeScript limitations

There are a couple of limitations due to Vue and TS incompabilities.
These limitations also affect JS users to some degree, as under-the-hood code autocomplete is powered by TypeScript.

##### Double File Components (DFC)

TypeScript cannot infer a component type from a SFC, because it cannot understand the content of files which are not JS or TS.
To allow correct inference of the component type, you shall separate the `<script>` tag content of your SFC into a standalone file, adopting a DFC (Double File Component) fashion.

```ts
// BookComponent.ts
export default {
  name: 'BookComponent',
  // ...
};
```

```html
<!-- BookComponent.vue -->
<script lang="ts" src="./book-component.ts"></script>

<template></template>

<style scoped></style>
```

##### `propsData` autocomplete

The configuration object `propsData` property isn't currently typed after the component instance props.
This is due to Vue components complicated typings and multiple flavours, as we still haven't found the way to both extract props typings AND get a correctly typed wrapper instance for all flavours: Composition, Class and Options API all have different and partially incompatible types.
We are open to contributions and will try to solve this problem when switching to Vue 3, which should have easier typings.

#### Jest watch mode

`jest --watch` will not work if you don't have a version control system (Git, Mercurial) in place, as jest relies on it to track which files should be watched for changes.

repository: j-karg-dcu/quasar-testing

repo_name: j-karg-dcu/quasar-testing


text:
# Awesome Playwright [![Awesome](https://awesome.re/badge.svg)](https://awesome.re)

> A curated list of awesome tools, utils and projects using Playwright

[Playwright](https://github.com/microsoft/playwright) is a Node.js library to automate Firefox, WebKit and Chromium based browsers via a single API.

## Contents

- [Integrations](#integrations)
- [Utils](#utils)
- [Showcases](#showcases)

## Integrations

- [jest-playwright](https://github.com/playwright-community/jest-playwright/) - Jest adapter for running Playwright.
- [CodeceptJS](https://github.com/Codeception/CodeceptJS) - Supercharged End 2 End Testing Framework for Node.js.
- [QA Wolf](https://github.com/qawolf/qawolf) - Create browser tests 10x faster.
- [playwright-aws-lambda](https://github.com/JupiterOne/playwright-aws-lambda) - Support for running Microsoft's Playwright on AWS Lambda and Google Cloud Functions.
- [playwright-amazon-linux-build](https://github.com/help-14/playwright-amazon-linux-build) - Browser build for Playwright to run on Amazon Linux 2.
- [playwright-sharp](https://github.com/kblok/playwright-sharp) - Playwright port to .NET with C#.
- [playwright-github-action](https://github.com/microsoft/playwright-github-action) - GitHub Action to install all the required dependencies.

## Utils

- [Try Playwright](https://try.playwright.tech) - Interactive playground for running Playwright tests.
- [query-selector-shadow-dom](https://github.com/Georgegriff/query-selector-shadow-dom) - Extend the selectors engine by selecting Shadow DOM roots.
- [playwright-video](https://github.com/qawolf/playwright-video) - Record your Chromium browser sessions.
- [playwright-fluent](https://github.com/hdorgeval/playwright-fluent) - Fluent API Wrapper around Playwright.
- [playwright-ci](https://github.com/qawolf/playwright-ci) - Set up Playwright in your CI easily.
- [headless-testing](https://headlesstesting.com) - Connect your Playwright tests with browsers in the Cloud.
- [expect-playwright](https://github.com/playwright-community/expect-playwright) - Utility functions for Jest to perform expect based checks.
- [eslint-plugin-jest-playwright](https://github.com/playwright-community/eslint-plugin-jest-playwright) - ESLint globals for the usage with Jest Playwright.
- [Moon](https://github.com/aerokube/moon) - Tools for executing Playwright tests in parallel in a Kubernetes cluster.

## Showcases

- [playwright-jest-examples](https://github.com/playwright-community/playwright-jest-examples) - Examples of the Jest Playwright tools in combination to test popular sites.
- [playwright-demos](https://github.com/nmanikiran/playwright-demos) - Playwright demos for scrapping and UI testing / automate testing workflows.
- [VS Code](https://github.com/microsoft/vscode) - Playwright is used to run cross-browser tests on their web builds.
- [TypeScript](https://github.com/microsoft/TypeScript) - Playwright is used test typescript.js across browsers.
- [Elastic APM JS agent](https://github.com/elastic/apm-agent-rum-js) - Playwright is used to run benchmark tests across browsers.
- [Blockstack](https://github.com/blockstack/ux) - Playwright is used to run cross-browser UI tests.
- [xterm.js](https://github.com/xtermjs/xterm.js) - Playwright is used to run cross-browser integration tests.

## Contribute

Contributions welcome! Read the [contribution guidelines](contributing.md) first.

repository: vania-pooh/awesome-playwright

repo_name: vania-pooh/awesome-playwright


text:
# ansible_role_consul_config

ansible role to configure consul

https://galaxy.ansible.com/suzuki-shunsuke/consul_config

[![GitHub last commit](https://img.shields.io/github/last-commit/suzuki-shunsuke/ansible_role_consul_config.svg)](https://github.com/suzuki-shunsuke/ansible_role_consul_config)
[![GitHub tag](https://img.shields.io/github/tag/suzuki-shunsuke/ansible_role_consul_config.svg)](https://github.com/suzuki-shunsuke/ansible_role_consul_config/releases)

This role doesn't install consul.
If you want to install, please use [akoi](https://github.com/suzuki-shunsuke/akoi) and [suzuki-shunsuke.akoi](https://github.com/suzuki-shunsuke/ansible_role_akoi).

```yaml
packages:
  consul:
    url: "https://releases.hashicorp.com/consul/{{.Version}}/consul_{{.Version}}_linux_amd64.zip"
    version: 1.2.1
    files:
    - name: consul
      archive: consul
```

## Directory Structure

* user: `consul_user` default:consul
* group: `consul_group` default:consul

```
data_dir/ default:/opt/consul
consul_pid_file default:/var/run/consul/consul.pid
consul_config_file default:/etc/consul/consul.json
consul_configd_path/ default:/etc/consul/consul.d/
  service.json
consul_service_unit_file default:/etc/systemd/system/consul.service
```

## Requirements

Nothing.

## Role Variables

Required variables are nothing.
Please see

* [defaults/main.yml](defaults/main.yml)
* [vars/main.yml](vars/main.yml)
* [tasks/assert.yml](tasks/assert.yml)

## Handlers

### `restart consul`

If `consul_use_systemd` is `true`, systemd's service is restarted.

You can define custom handlers.
For example, if you manage consul with supervisor,

```yaml
handlers:
- name: restart consul (supervisor)
  supervisorctl:
    name: consul
    state: restarted
  listen: restart consul
```

## Example Playbook

```yaml
- hosts: servers
  roles:
  - role: suzuki-shunsuke.consul_config
    consul_path: /usr/local/bin/consul
    consul_config_files:
      web:
        service:
          name: web
          tags:
          - rails
          port: 80
    become: yes
```

## Change Log

See [CHANGELOG.md](CHANGELOG.md).

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md).

## License

[MIT](LICENSE)

gha_language: Shell