openapi: 3.0.1
info:
  version: '1.0-oas3'
  title: httpbin
  description: An unofficial OpenAPI definition for [httpbin.org](https://httpbin.org).

servers:
  - url: https://httpbin.org
  #- url: http://httpbin.org
  - url: https://eu.httpbin.org
  #- url: http://eu.httpbin.org

tags:
  - name: auth
    description: Operations for testing various authentication types
  - name: HTTP methods
    description: Operations for testing different HTTP methods
  - name: Status codes
    description: Return the specified HTTP status code, or a random status code if more than one are given

# All paths & parameters are described in
# https://github.com/kennethreitz/httpbin/blob/master/httpbin/core.py

externalDocs:
  url: http://httpbin.org/legacy

paths:
  # New operations for parsing time
  /:
    get:
      summary: The current time, in a variety of formats
      tags:
        - time
      servers:
        - url: https://now.httpbin.org
        #- url: http://now.httpbin.org
      #externalDocs:
      #  url: /docs # ???
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  now:
                    $ref: '#/components/schemas/Timestamp'
                  urls:
                    type: array
                    items:
                      type: string
                    example:
                      - /
                      - /docs
                      - '/when/:human_timestamp'
                      - '/parse/:machine_timestamp'
                required:
                  - now
                  - urls

  /when/{human_timestamp}:
    get:
      tags:
        - time
      servers:
        - url: http://now.httpbin.org
        #- url: https://now.httpbin.org
      parameters:
        - in: path
          name: human_timestamp
          required: true
          schema:
            anyOf:
              - type: string # ????
      x-kong-plugin-request-validator:
        enabled: true
      responses:
        '200':
          $ref: '#/components/responses/TimestampResponse'
        '500':
          description: oops

  /parse/{machine_timestamp}:
    get:
      tags:
        - time
      servers:
        - url: http://now.httpbin.org
        #- url: https://now.httpbin.org
      parameters:
        - in: path
          name: machine_timestamp
          required: true
          schema:
            anyOf:
              - type: string # ????
              - type: number
      responses:
        '200':
          $ref: '#/components/responses/TimestampResponse'
        '500':
          description: oops

  /get:
    get:
      tags:
        - HTTP methods
      summary: |
        Returns the GET request's data. Accepts any query parameters and any headers.
      parameters:
        - $ref: '#/components/parameters/freeFormQuery'
      responses:
        '200':  # Change to 'default' ???
          description: OK
          content:
            application/json:
              schema:
                type: object

  /delete:
    delete:
      tags:
        - HTTP methods
      summary: |
        Returns the DELETE request's data. Accepts any query parameters and any headers.
      parameters:
        - $ref: '#/components/parameters/freeFormQuery'
      responses:
        200:
          description: OK

  /post:
    post:
      tags:
        - HTTP methods
      # summary: POSTs a pizza order and returns the POSTed data.
      summary: Returns the POSTed data
      parameters:
        - $ref: '#/components/parameters/freeFormQuery'
      requestBody:
        description: Data provided in the request body will be returned in the response.
        content:
          application/json:
            schema: {}
            example:
              message: Hello, world!
          application/vnd+json:
            schema: {}
            examples:
              pizzaOrder:
                summary: Pizza order data
                description: Longer description ...
                value:
                  custname: Alice
                  custtel: '+1-202-555-0100'
                  custemail: alice@wonderland.net
                  size: medium
                  topping: [cheese, mushroom]
                  delivery: '19:00'
                  comments: Ring the door bell three times
              simpleObject:
                summary: sample object
                value:
                  foo: bar
          application/xml:
            schema:
              type: object
            example:
              message: Hello, world!
          text/plain:
            schema:
              type: string
              example: Hi there
          application/x-www-form-urlencoded:
            schema:
              # anyOf:
              #   - type: object
              #     additionalProperties: true

              #   - description: Pizza order
              type: object
              properties:
                custname:
                  type: string
                  example: Alice
                  description: Customer name
                custtel:
                  type: string
                  example: '+1-202-555-0100'
                  description: Customer phone number
                custemail:
                  type: string
                  format: email
                  example: alice@wonderland.net
                  description: Customer email address
                size:
                  type: string
                  enum:
                    - small
                    - medium
                    - large
                  description: Pizza size
                topping:
                  type: array
                  items:
                    type: string
                    enum:
                      - bacon
                      - cheese
                      - mushroom
                      - onion
                  description: Pizza toppings
                delivery:
                  type: string
                  example: '13:30'
                  description: Delivery time
                comments:
                  type: string
                  example: ASAP
                  description: Comments
            examples:
              pizzaOrder:
                summary: Pizza order data
                description: Longer description ...
                value:
                  custname: Alice
                  custtel: '+1-202-555-0100'
                  custemail: alice@wonderland.net
                  size: medium
                  topping: [cheese, mushroom]
                  delivery: '19:00'
                  comments: Ring the door bell three times
              simpleObject:
                summary: sample object
                value:
                  foo: bar
          # multipart/form-data: {}  # TODO
          '*/*':   # is this valid?
            schema: {}
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CommonResponse'
              #schema:
              #  type: object

  # /put: {}
  # /patch: {}
  # /delete: {}
  # /response-headers:
  #   parameters:
  #     - in: query
  #       name: headers
  #       # Arbitrary key=value pairs
  #       schema:
  #         type: object
  #         example:
  #           Server: unicorn
  #       style: simple
  #   get: {}
  #   post: {}

  /ip:
    get:
      summary: Returns Origin IP.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  origin:
                    type: string
                    description: >
                      The IP address, or a comma-separated list of IP addresses.
                      For example, "10.100.10.10, 10.100.20.254, 52.91.14.13"'
                    example: 10.100.10.10
                required:
                  - origin
              examples:   # Content examples override schema-level examples
                oneIp:
                  description: Example of a single IP
                  value:
                    origin: 10.100.10.10
                multipleIps:
                  description: Example of multiple IPs
                  value:
                    origin: 10.100.10.10, 10.100.20.254, 52.91.14.13

  /user-agent:
    get:
      summary: Returns the user agent.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  user-agent:
                    type: string
                    example: curl/7.37.0
                required:
                  - user-agent

  /headers:
    get:
      summary: Returns the request headers.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  headers:
                    type: object
                    additionalProperties:
                      type: string
                    # wrong syntax!
                    #example:
                    #  $ref: '#/components/examples/headers'
                required:
                  - headers

  # /anything:
  #   summary: Returns request data, including method used.
  #   get: {}
  #   post: {}
  #   put: {}
  #   patch: {}
  #   delete: {}
  #   trace: {}
  #   options: {}

  # /anything/{anything}:
  #   summary: Returns request data, including method used.

  #   parameters:
  #     - in: path
  #       name: anything
  #       required: true
  #       schema:
  #         type: string
  #       description: An arbitrary subpath

  #   get: {}
  #   post: {}
  #   put: {}
  #   patch: {}
  #   delete: {}
  #   trace: {}
  #   options: {}

  /delay/{n}:
    get:
      summary: Delays responding for min(n, 10) seconds.
      parameters:
        - name: n
          in: path
          required: true
          description: Response delay, in seconds.
          schema:
            type: integer
            minimum: 0
            maximum: 10
      responses:
        '200':
          description: OK
          content:
            application/json: {}
              # schema:
              #   type: object

  /basic-auth/{user}/{password}:
    get:
      summary: Challenges HTTPBasic Auth.
      tags:
        - auth
      security:
        - basicAuth: []
      parameters:
        - $ref: '#/components/parameters/user'
        - $ref: '#/components/parameters/password'
      responses:
        '200':
          $ref: '#/components/responses/200BasicAuth'
        '401':
          description: >-
            Unauthorized (The username and password used for Basic auth do not
            match those in the URL path.)
          headers:
            Www-Authenticate:
              schema:
                type: string
                example: 'Basic realm="Fake Realm"'

  /hidden-basic-auth/{user}/{password}:
    get:
      summary: Hidden Basic authentication
      tags:
        - auth
      description: Returns 404 Not Found unless the request is authenticated.
      security:
        - basicAuth: []
      parameters:
        - $ref: '#/components/parameters/user'
        - $ref: '#/components/parameters/password'
      responses:
        '200':
          $ref: '#/components/responses/200BasicAuth'
        '404':
          description: >-
            Unautorized (the username and password used for Basic auth do not
            match those in the URL path.)

  /bearer:
    get:
      summary: Tests Bearer authentication
      tags:
        - auth
      security:
        - basicAuth: []
        #- bearerAuth: []
      responses:
        '200':
          description: Authorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  authenticated:
                    type: boolean
                    example: true
                  token:
                    type: string
                    description: Bearer token specified in the request
        '404':
          description: Unauthorized

  /status/{statusCode}:
    summary: Returns the specified HTTP status code, or a random status code if more than one are given
    parameters:
      - name: statusCode
        in: path
        required: true
        description: The status code to return, or a weighted list of statuses to pick from, such as `200:4,500:0.3,418`.
        schema:
          type: array
          items:
            description: HTTP status code. May include optional weight, e.g. `200:0.9`
            oneOf:
              - type: string
              - type: integer
          minItems: 1
          example:
            - '200:5'
            - '500:0.3'
            - 418
        style: simple

    get:
      tags:
        - Status codes
      responses:
        default:
          description: A response with the requested status code.
    post:
      tags:
        - Status codes
      responses:
        default:
          description: A response with the requested status code.
    patch:
      tags:
        - Status codes
      responses:
        default:
          description: A response with the requested status code.
    put:
      tags:
        - Status codes
      responses:
        default:
          description: A response with the requested status code.
    delete:
      tags:
        - Status codes
      responses:
        default:
          description: A response with the requested status code.

  /xml:
    get:
      summary: Returns some XML.
      responses:
        '200':
          description: OK
          content:
            application/xml: {}

  /html:
    get:
      summary: Returns an HTML page
      responses:
        '200':
          description: OK
          content:
            text/html: {}

  /image/{format}:
    get:
      summary: Returns an image with the specified format.
      tags:
        - images
      parameters:
        - in: path
          name: format
          required: true
          schema:
            type: string
            enum:
              - png
              - jpeg
              - webp
              - svg
      responses:
        '200':
          $ref: '#/components/responses/Image'

  /image:
    get:
      summary: Returns an image based on the Accept header.
      tags:
        - images
      responses:
        '200':
          $ref: '#/components/responses/Image'
        '406':
          description: Client did not request a supported media type.

  /cache:
    get:
      summary: >-
        Returns 200 unless an If-Modified-Since or If-None-Match header is
        provided, when it returns a 304.
      parameters:
        - in: header
          name: If-Modified-Since
          required: false
          description: >
            For testing purposes this header accepts any value. (???)
            See also https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-Modified-Since
          schema:
            type: string
            example: 'Wed, 21 Oct 2015 07:28:00 GMT'
        - in: header
          name: If-None-Match
          required: false
          description: >
            For testing purposes this header accepts any value. (???)
            See also https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match
          schema:
            type: string
          examples:
            etag:
              value: '"bfc13a64729c4290ef5b2c2730249c88ca92d82d"' # Quotes are part of the value
            etags:
              value: 'W/"67ab43", "54ed21", "7892dd"'
            asterisk:
              value: '*'
      responses:
        '200':
          description: Neigher If-Modified-Since nor If-None-Match header is provided
        '304':
          description: If-Modified-Since or If-None-Match header is provided

  /cookies:
    get:
      x-kong-plugin-correlation-id:
        name: correlation-id
      tags:
        - Cookies
      summary: Returns cookie data
      responses:
        200:
          description: OK
  /cookies/set:
    get:
      tags:
        - Cookies
      summary: Sets one or more simple cookies
      parameters:
        - $ref: '#/components/parameters/freeFormQuery'
      responses:
        200:
          description: OK
  /cookies/delete:
    get:
      tags:
        - Cookies
      summary: Delete one or more simple cookies
      parameters:
        - $ref: '#/components/parameters/freeFormQuery'
      responses:
        200:
          description: OK

#################################
# Reusable things
#################################
components:
  schemas:
    CommonResponse:
      description: Response returned by `/get`
      type: object
      properties:
        args:
          type: object
          additionalProperties:
            type: string
          description: Query string parameters specified in the request URL.
        headers:
          type: object
          additionalProperties:
            type: string
          description: >
            Headers (standard or custom) used in the request. Some typical headers are:
              - Accept
              - Accept-Encoding
              - Content-Length
              - Content-Type
              - Host
              - Origin
              - Referred
              - User-Agent
          # not valid syntax
          #example:
          #  $ref: '#/components/examples/headers'
        origin:
          type: string
          description: The origin IP from which the request was made.
          example: '10.100.10.10, 10.100.10.44, 52.91.14.13'
        url:
          type: string
          format: uri
          description: The endpoint URL to which the request was made.
          example: https://httpbin.org/post
      required:
        - args
        - headers
        - origin
        - url

    PostResponse:
      description: Response returned by /post, /put, /patch and /delete
      allOf:
        - $ref: '#/components/schemas/CommonResponse'
        - type: object
          properties:
            data: {}    # Always a plain text string???
              # ???
              # oneOf:
              #   - type: string
              #   - type: object
            files: {}
            #  type: object
            #  description: ???
            form:
              type: object
              additionalProperties:
                type: string
              description: >
                Form parameters specified in "application/x-www-form-urlencoded" and
                `multipart/form-data` requests.
            json:
              description: >
                JSON value sent in the payload.
                Can be object, array, string, number, boolean or `null`.
              nullable: true
              # oneOf:
              #   - type: object
              #   - type: array
              #   - type: string
              #   - type: number
              #   - type: boolean

    TimestampWrapper:
      type: object
      properties:
        timestamp:
          $ref: '#/components/schemas/Timestamp'
      required:
        - timestamp

    Timestamp:
      type: object
      properties:
        epoch:
          type: number
          format: double
          example: 1498229228.0671656
        slang_date:
          type: string
          example: today
        slang_time:
          type: string
          example: now
        iso8601:
          type: string
          # format: ???
          example: '2017-06-23T14:47:08.067166Z'
        rfc2822:
          type: string
          # format: ???
          example: 'Fri, 23 Jun 2017 14:47:08 GMT'
        rfc3339:
          type: string
          # format: ????
          example: '2017-06-23T14:47:08.06Z'
      required:
        - epoch
        - slang_date
        - slang_time
        - iso8601
        - rfc2822
        - rfc3339
      example:
        epoch: 1485183550.84644
        slang_date: Jan 23
        slang_time: 4 months ago
        iso8601: '2017-01-23T14:59:10.846440Z'
        rfc2822: Mon, 23 Jan 2017 14:59:10 GMT
        rfc3339: '2017-01-23T14:59:10.84Z'
      # schema does NOT support plural "examples"
      # examples:
      #   Now:
      #     value:
      #       epoch: 1498229228.0671656
      #       slang_date: today
      #       slang_time: now
      #       iso8601: '2017-06-23T14:47:08.067166Z'
      #       rfc2822: Fri, 23 Jun 2017 14:47:08 GMT
      #       rfc3339: '2017-06-23T14:47:08.06Z'
      #   DateInPast:
      #     description: Example of a date in the past
      #     value:
      #       epoch: 1485183550.84644,
      #       slang_date": Jan 23
      #       slang_time": 4 months ago
      #       iso8601: '2017-01-23T14:59:10.846440Z'
      #       rfc2822: Mon, 23 Jan 2017 14:59:10 GMT
      #       rfc3339: '2017-01-23T14:59:10.84Z'

  securitySchemes:
    basicAuth:
      type: http
      scheme: basic
      description: Use the same username and password as you will provide in path parameters.
      x-kong-security-basic-auth:
        config:
          hide_credentials: true
    bearerAuth:
      type: http
      scheme: bearer

  parameters:
    user:
      name: user
      in: path
      required: true
      description: Username. Use the same username in the path AND for authorization.
      schema:
        type: string
    password:
      name: password
      in: path
      required: true
      description: Password. Use the same password in the path AND for authorization.
      schema:
        type: string
    freeFormQuery:
      name: freeform
      in: query
      schema:
        type: object
        additionalProperties: true
      # This is the default serialization method, so it can be omitted
      style: form
      explode: true
      description: >
        Enter free-form query parameters in the JSON format
        `{ "param1": "value1", "param2": "value2", ... }`.

        Note that the parameters will be actually sent as
        `?param1=value1&param2=value2&...`

  responses:
    200BasicAuth:
      description: OK
      content:
        application/json:
          schema:
            type: object
            properties:
              authenticated:
                type: boolean
                example: true
              user:
                type: string
                description: The user name specified in the request.
    Image:
      description: OK
      content:
        image/png, image/jpeg, image/webp:
          schema:
            type: string
            format: binary
        image/svg+xml: {}  # string? object?
        image/svg: {}  # string? object?

    TimestampResponse:
      description: OK
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TimestampWrapper'

  examples:
    headers:
      value:
        Accept: '*/*'
        Connection: close
        Host: httpbin.org
        User-Agent: curl/7.37.0

    Now:
      value:
        epoch: 1498229228.0671656
        slang_date: today
        slang_time: now
        iso8601: '2017-06-23T14:47:08.067166Z'
        rfc2822: Fri, 23 Jun 2017 14:47:08 GMT
        rfc3339: '2017-06-23T14:47:08.06Z'
    DateInPast:
      description: Example of a date in the past
      value:
        epoch: 1485183550.84644,
        slang_date": Jan 23
        slang_time": 4 months ago
        iso8601: '2017-01-23T14:59:10.846440Z'
        rfc2822: Mon, 23 Jan 2017 14:59:10 GMT
        rfc3339: '2017-01-23T14:59:10.84Z'


"private": true,
"version": "2.2.1",
"main": "index.js",
"insomnia": {
"name": "kong-themes"
}
}

"name": "kong-themes",
"core": true,
"unlisted": true

// @flow
import * as React from 'react';
import autobind from 'autobind-decorator';
import Modal from '../base/modal';
import ModalBody from '../base/modal-body';
import ModalHeader from '../base/modal-header';

type Props = {};
type State = {
  title: string,
  body: React.Node,
  bodyHTML: ?string,
  tall: ?boolean,
  skinny: ?boolean,
  wide: ?boolean,
};

@autobind
class WrapperModal extends React.PureComponent<Props, State> {
  modal: ?Modal;

  constructor(props: Props) {
    super(props);

    this.state = {
      title: '',
      body: null,
      bodyHTML: null,
      tall: false,
      skinny: false,
      wide: false,
    };
  }

  _setModalRef(m: ?Modal) {
    this.modal = m;
  }

  show(options: Object = {}) {
    const { title, body, bodyHTML, tall, skinny, wide } = options;
    this.setState({
      title,
      body,
      bodyHTML,
      tall: !!tall,
      skinny: !!skinny,
      wide: !!wide,
    });

    this.modal && this.modal.show();
  }

  render() {
    const { title, body, bodyHTML, tall, skinny, wide } = this.state;

    let finalBody = body;
    if (bodyHTML) {
      finalBody = <div dangerouslySetInnerHTML={{ __html: bodyHTML }} className="tall wide pad" />;
    }

    return (
      <Modal ref={this._setModalRef} tall={tall} skinny={skinny} wide={wide}>
        <ModalHeader>{title || 'Uh Oh!'}</ModalHeader>
        <ModalBody>{finalBody}</ModalBody>
      </Modal>
    );
  }
}

export default WrapperModal;


language: node_js

matrix:
  include:
    - name: Release Core
      os: osx # High Sierra for older libcurl compatibility
      osx_image: xcode10.1
      if: (tag =~ ^core@)
      env:
        - GH_TOKEN=$GITHUB_TOKEN
        - APPLE_ID=$APPLE_ID
        - APPLE_ID_PASSWORD=$APPLE_ID_PASSWORD
        - CSC_LINK=$MAC_CSC_LINK
        - CSC_KEY_PASSWORD=$MAC_CSC_KEY_PASSWORD
    - name: Release Designer
      os: osx # High Sierra for older libcurl compatibility
      osx_image: xcode10.1
      if: (tag =~ ^designer@)
      env:
        - GH_TOKEN=$GITHUB_TOKEN
        - APPLE_ID=$DESIGNER_APPLE_ID
        - APPLE_ID_PASSWORD=$DESIGNER_APPLE_ID_PASSWORD
        - CSC_LINK=$DESIGNER_MAC_CSC_LINK
        - CSC_KEY_PASSWORD=$DESIGNER_MAC_CSC_KEY_PASSWORD

cache:
  directories:
    - node_modules
    - packages/insomnia-app/node_modules
    - packages/insomnia-app/build/node_modules

script:
  - node --version
  - npm --version
  - npm run bootstrap
  - npm test
  # Setup branch because Travis doesn't provide a good way to get it
  - export TRAVIS_CURRENT_BRANCH=$(if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then echo $TRAVIS_BRANCH; else echo $TRAVIS_PULL_REQUEST_BRANCH; fi)
  - npm run app-release


class Pedometer

  CAP = 1.2

  attr_reader :raw_data, :parsed_data
  attr_reader :steps, :distance, :time, :interval

  def initialize(mobile_output)
    @raw_data = mobile_output
    @steps    = 0
    @distance = 0
    @time     = 0
    @interval = 'seconds'

    verify_data_format
    parse_raw_data
  end

  # -- Measurement Methods --------------------------------------------------

  # TODO: Introduce user object passed in to:
  # - Get stride length, height, etc.
  # - Request info in metric vs. imperial
  # - Request info in different reporting formats

  def measure
    measure_steps
    measure_distance
  end

  def measure_steps
    @parsed_data.each do |x, y, z|
      @steps += 1 if (x > CAP || y > CAP || z > CAP)
    end
  end

  def measure_distance
    # TODO: Get stride length from user object
    stride_length = 0.0009 # average stride length in km
    @distance = stride_length * @steps
  end

  def measure_time
    # TODO: Get sampling rate from user object
    sampling_rate = 5.0 # samples/second
    seconds = @parsed_data.count/sampling_rate

    if seconds > 3600
      @time = (seconds/3600).round(2)
      @interval = 'hours'
    elsif seconds > 60
      @time = (seconds/60).round(2)
      @interval = 'minutes'
    else
      @time = seconds.round(2)
      @interval = 'seconds'
    end
  end

  # -- Data Manipulation ----------------------------------------------------

  def verify_data_format
    regexp = Regexp.new(/^((-?\d+(?:\.\d+)?,){2}-?\d+(?:\.\d+)?;)+$/)
    unless regexp.match(@raw_data)
      raise "Bad Input. Ensure data is a series of comma separated x,y,z coordiantes separated by semicolons."
    end
  end

  def parse_raw_data
    @parsed_data = @raw_data.split(';').inject([]) do |a, row|
      a << row.split(',').map { |coord| coord.to_f.abs }
      a
    end
  end

end


Time to start digging down to the socket and parsing layers.  This
"version" shows how socket connections are handled and how HTTP
requests are parsed.

To run:

*   `python echo-server.py 8080` in one window, `python echo-client.py 127.0.0.1 8080 hello` in another.
*   `python telnet-server.py 8080` in one window, `python telnet-client.py 8080 < test.txt` in another.


Pedometer
=========

A pedometer implemented in Ruby.

The pedometer takes accelerometer data from a mobile device, and outputs step count, distance, speed, and other relevant information typically found in native mobile applications.

While a pedometer application for a mobile device would usually be written natively for the specific platform, this application is written in Ruby, and exposed through a simple API. This illustrates the design choices that are made when writing an application of this sort, without being bound to the specifics of one platform with quickly evolving APIs and native tools.


require 'catechism/matchers/equal'
require 'catechism/matchers/raise_error'
require 'catechism/matchers/send'

class Catechism::SubjectWrapper < Struct.new(:subject)
  attr_reader :negated

  def to_equal(expected)
    matcher = Catechism::Matchers::Equal.new(subject, expected, negated)
    raise matcher.failure_message unless matcher.valid?
  end

  def to_be_nil
    matcher = Catechism::Matchers::Equal.new(subject, nil, negated)
    raise matcher.failure_message unless matcher.valid?
  end

  def to_raise_error
    matcher = Catechism::Matchers::RaiseError.new(subject, negated)
    raise matcher.failure_message unless matcher.valid?
  end

  def to_send(method_name)
    Catechism::Matchers::Send.new(subject, method_name, negated)
  end

  def not
    @negated = true
    self
  end
end


# TODO: Get sampling rate from user object

keep keep keep keep replace keep keep keep

require 'test/unit'
require './models/pedometer.rb'

class PedometerTest < Test::Unit::TestCase

  # -- Creation Tests -------------------------------------------------------

  def test_create
    input = "0.123,-0.123,5;"
    pedometer = Pedometer.new(input)

    assert_equal 0, pedometer.steps
    assert_equal 0, pedometer.distance

    assert_equal 0, pedometer.time
    assert_equal 'seconds', pedometer.interval

    assert_equal input, pedometer.raw_data
    assert_equal [[0.123, 0.123, 5.0]], pedometer.parsed_data
  end

  def test_create_nil_input
    message = "Bad Input. Ensure data is a series of comma separated x,y,z coordiantes separated by semicolons."
    assert_raise_with_message(RuntimeError, message) do
      Pedometer.new(nil)
    end
  end

  def test_create_empty_input
    message = "Bad Input. Ensure data is a series of comma separated x,y,z coordiantes separated by semicolons."
    assert_raise_with_message(RuntimeError, message) do
      Pedometer.new('')
    end
  end

  def test_create_bad_input_strings
    message = "Bad Input. Ensure data is a series of comma separated x,y,z coordiantes separated by semicolons."
    assert_raise_with_message(RuntimeError, message) do
      Pedometer.new("0.123,-0.123,5;a,b,c;")
    end
  end

  def test_create_bad_input_too_many_values
    message = "Bad Input. Ensure data is a series of comma separated x,y,z coordiantes separated by semicolons."
    assert_raise_with_message(RuntimeError, message) do
      Pedometer.new("0.123,-0.123,5;0.123,-0.123,5,9;")
    end
  end

  def test_create_bad_input_too_few_values
    message = "Bad Input. Ensure data is a series of comma separated x,y,z coordiantes separated by semicolons."
    assert_raise_with_message(RuntimeError, message) do
      Pedometer.new("0.123,-0.123,5;0.123,-0.123;")
    end
  end

  # -- Measurement Tests ----------------------------------------------------

  def test_measure_steps
    pedometer = Pedometer.new(File.read('test/data/results-0-steps.txt'))
    pedometer.measure_steps
    assert_equal 0, pedometer.steps

    pedometer = Pedometer.new(File.read('test/data/results-15-steps.txt'))
    pedometer.measure_steps
    assert_equal 15, pedometer.steps
  end

  def test_measure_distance_before_steps
    pedometer = Pedometer.new(File.read('test/data/results-0-steps.txt'))
    pedometer.measure_distance
    assert_equal 0, pedometer.distance

    pedometer = Pedometer.new(File.read('test/data/results-15-steps.txt'))
    pedometer.measure_distance
    assert_equal 0, pedometer.distance
  end

  def test_measure_distance_after_steps
    pedometer = Pedometer.new(File.read('test/data/results-0-steps.txt'))
    pedometer.measure_steps
    pedometer.measure_distance
    assert_equal 0, pedometer.distance

    pedometer = Pedometer.new(File.read('test/data/results-15-steps.txt'))
    pedometer.measure_steps
    pedometer.measure_distance
    assert_equal 0.0135, pedometer.distance
  end

  def test_measure_time_seconds
    pedometer = Pedometer.new(File.read('test/data/results-15-steps.txt'))
    pedometer.measure_time
    assert_equal 5.8, pedometer.time
    assert_equal 'seconds', pedometer.interval
  end

  def measure_time_minutes
    # Fake out 1000 samples
    pedometer = Pedometer.new(1000.times.inject('') {|a| a+='1,1,1;';a})
    pedometer.measure_time
    assert_equal 3.33, pedometer.time
    assert_equal 'minutes', pedometer.interval
  end

  def measure_time_hours
    # Fake out 20000 samples
    pedometer = Pedometer.new(20000.times.inject('') {|a| a+='1,1,1;';a})
    pedometer.measure_time
    assert_equal 1.11, pedometer.time
    assert_equal 'hours', pedometer.interval
  end

  def test_measure
    pedometer = Pedometer.new(File.read('test/data/results-0-steps.txt'))
    pedometer.measure
    assert_equal 0, pedometer.steps
    assert_equal 0, pedometer.distance

    pedometer = Pedometer.new(File.read('test/data/results-15-steps.txt'))
    pedometer.measure
    assert_equal 15, pedometer.steps
    assert_equal 0.0135, pedometer.distance
  end

end


This version responds to HTTP requests with static HTML files or
directory listings.

*   Run with `python server.py .` (or some other base directory name).
*   Point browser at `http://localhost:8080/some/path`.


keep keep keep keep keep replace keep keep keep keep

assert_equal '{"steps":1,"distance":0.0009,"time":"0.2 seconds"}', last_response.body


import sys
import logging
from network import Node

# Remove from final copy:
#  - logging

class Member(Node):

    def __init__(self, execute_fn):
        Node.__init__(self)
        self.execute_fn = execute_fn

    def start(self, initial_value=None):
        self.state = initial_value
        self.run()

    def invoke(self, input):
        self.state, output = self.execute_fn(self.state, input)
        return output

    def do_INVOKE(self, input, caller):
        self.send([caller], 'INVOKED', output=self.invoke(input))

def sequence_generator(state, input):
    return state + input, range(state, state + input)

if __name__ == "__main__":
    logging.basicConfig(
        format="%(asctime)s %(name)s %(message)s", level=logging.DEBUG)
    member = Member(sequence_generator)
    print member.address
    member.start(initial_value=0)

# tests

import unittest
import threading

class FakeClient(Node):

    def do_INVOKED(self, output):
        self.output = output
        self.stop()

class MemberTests(unittest.TestCase):

    def test_invoke(self):
        member = Member(sequence_generator)
        client = FakeClient()
        client.member = member
        memberthd = threading.Thread(target=member.start, args=(0,))
        memberthd.daemon = 1
        memberthd.start()
        client.send([member.address], 'INVOKE', input=5, caller=client.address)
        client.run()
        self.assertEqual(client.output, [0, 1, 2, 3, 4])


This version:

*   adds HTTP error codes for missing items;
*   does path normalization to prevent users fetching files that aren't
    below the specified root directory; and
*   has some logging built in.

If nothing corresponds to the requested path, a 404 (File Not Found)
error is returned.  If the thing corresponding to the path can't be
read, a 403 (No Permissions) error is returned.  If something else
goes wrong, a 500 (Internal) error is returned.


<title>Nitinat Test Page</title>

Nitinat Test Page

This is an HTML page which displays an image.


require 'test/unit'
require './models/user.rb'

class UserTest < Test::Unit::TestCase

  def test_create_no_parameters
    user = User.new(nil)

    assert_nil user.gender
    assert_nil user.height
    assert_equal 74, user.stride
    assert_equal 'metric', user.system
  end

  def test_create_with_gender
    assert_equal 'female', User.new(:gender => 'Female').gender
    assert_equal 'male',   User.new(:gender => 'MALE').gender

    assert_nil User.new(:gender => 'invalid value').gender
    assert_nil User.new(:gender => 1).gender
  end

  def test_create_with_system
    assert_equal 'metric',   User.new(:system => 'MetrIC').system
    assert_equal 'imperial', User.new(:system => 'imperial').system

    assert_equal 'metric', User.new(:system => 'invalid value').system
    assert_equal 'metric', User.new(:system => 1).system
  end

  def test_create_bad_input
    flunk
  end

  def test_calculate_stride
    assert_equal 74,   User.new(nil).stride
    assert_equal 78,   User.new(:gender => 'male').stride
    assert_equal 70,   User.new(:gender => 'female').stride
    assert_equal 83,   User.new(:height => 200).stride
    assert_equal 83,   User.new(:gender => 'male', :height => 200).stride
    assert_equal 82.6, User.new(:gender => 'female', :height => 200).stride
  end

end


all : commands

## commands : show all commands
commands :
	@grep -E '^##' Makefile | sed -e 's/## //g'

## check    : build locally into _site directory for checking
check :
	jekyll -t build -d _site

## clean    : clean up
clean :
	rm -rf _site $$(find . -name '*~' -print)


Licenses
========

Written Material
----------------

All written material in this project is made available under the
Creative Commons Attribution license. You are free:

* to **Share**---to copy, distribute and transmit the work
* to **Remix**---to adapt the work

Under the following conditions:

* **Attribution**---You must attribute the work using
  "Copyright (c) [chapter author's name]"
  (but not in any way that suggests that we endorse you or your use of the work).
  Where practical, you must also include a hyperlink to http://aosabook.org.

With the understanding that:

* **Waiver**---Any of the above conditions can be waived if you get permission from the copyright holder.
* **Other Rights**---In no way are any of the following rights affected by the license:
    * Your fair dealing or fair use rights;
    * The author's moral rights;
    * Rights other persons may have either in the work itself or in
      how the work is used, such as publicity or privacy rights.
* **Notice**---For any reuse or distribution, you must make clear to others the license terms of this work.
  The best way to do this is with a link to
  [http://creativecommons.org/licenses/by/3.0/](http://creativecommons.org/licenses/by/3.0/).

For the full legal text of this license, please see
[http://creativecommons.org/licenses/by/3.0/legalcode](http://creativecommons.org/licenses/by/3.0/legalcode).

Software
--------

The example programs and other software included in this repository are made available under the
[OSI](http://opensource.org)-approved
[MIT license](http://opensource.org/licenses/mit-license.html).

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.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. 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.


# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'catechism/version'

Gem::Specification.new do |spec|
  spec.name          = 'catechism'
  spec.version       = Catechism::VERSION
  spec.authors       = ['Doc Ritezel and Sarah Mei']
  spec.email         = ['pair+doc+sarah@ministryofvelocity.com']
  spec.description   = 'An object-oriented testing framework'
  spec.summary       = 'Put your code through an object-oriented trial by fire.'
  spec.homepage      = 'https://github.com/aosabook/500lines/catechism'
  spec.license       = 'MIT'

  spec.files         = `git ls-files`.split($/)
  spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
  spec.test_files    = spec.files.grep(%r{^trials/})
  spec.require_paths = ['lib']
  spec.bindir        = 'bin'

  spec.add_dependency 'thor'

  spec.add_development_dependency 'bundler', '~> 1.3'
  spec.add_development_dependency 'gem-release'
  spec.add_development_dependency 'guard-shell'
end


Catechism
=========

Catechism is a very small test framework for Ruby.

Prerequisites
-------------

* Ruby 2.0.0
* A Unix environment

Installation
------------

Add this line to your application's Gemfile:

    gem 'catechism'

And then execute:

    $ bundle

Or install it yourself as:

    $ gem install catechism

Usage
-----

Create a `trials` directory in the root of your project.

Create files in any path underneath it ending in `_trial.rb`.  Examples can be found in `trials/lib/catechism`.

Then, run your test suite:

    $ catechism

Contributing
------------

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request


-module(bencode).

-ifdef(TEST).
-compile(export_all).
-endif.

-export([decode/1,encode/1,find/2,get/2]).

encode(Data) -> {ok, erlang:iolist_to_binary( encode2(Data) )}.
decode(Bin)  -> {Result, <<>>} = decode2(Bin),
                {ok, Result}.

find({OrdDict}, Key) -> orddict:find(Key, OrdDict).
get({OrdDict}, Key)  -> orddict:fetch(Key, OrdDict).

decode2(<<$i,I,Rest/binary>>) -> decode_int(I-$0, Rest);
decode2(<<$l,Rest/binary>>)   -> decode_list(Rest, []);
decode2(<<$d,Rest/binary>>)   -> decode_dictionary(Rest, []);
decode2(Bin)                  -> decode_string(0, Bin).

decode_int(Val, <<$e, Rest/binary>>) -> {Val, Rest};
decode_int(Val, <<N, Rest/binary>>)  -> decode_int(Val * 10 + N-$0, Rest).

decode_list(<<$e,Rest/binary>>, Acc) -> {lists:reverse(Acc), Rest};
decode_list(Bin, Acc)                -> {Elm, Rest} = decode2(Bin),
                                        decode_list(Rest, [Elm|Acc]).

decode_dictionary(<<$e,Rest/binary>>, Acc) ->
    {{lists:reverse(Acc)}, Rest};
decode_dictionary(Bin, Acc) ->
    {Key,   Rest1} = decode2(Bin),
    {Value, Rest2} = decode2(Rest1),
    decode_dictionary(Rest2, [{binary_to_atom(Key,latin1),Value}|Acc]).

decode_string(Len, <<$:, Rest/binary>>) -> <<String:Len/binary, Rest2/binary>> = Rest, {String, Rest2};
decode_string(Len, <<N, Rest/binary>>)  -> decode_string(Len*10 + (N-$0), Rest).

encode2(I) when is_integer(I) -> [$i, erlang:integer_to_binary(I, 10),$e];
encode2(S) when is_binary(S)  -> [erlang:integer_to_list(byte_size(S)), $:, S];
encode2(L) when is_list(L)    -> [$l, lists:map(fun encode2/1, L), $e];
encode2({D}) when is_list(D)  -> [$d, [ [encode2(atom_to_binary(K,latin1)), encode2(V)] || {K,V}<-lists:sort(D) ], $e].

-ifdef(TEST).

bdecode_test() ->
    {ok, {[{cow, <<"moo">>}, {spam, <<"eggs">>}]}} = decode(<<"d3:cow3:moo4:spam4:eggse">>),
    {ok, [<<"spam">>, <<"eggs">>]} = decode(<<"l4:spam4:eggse">>).

bencode_test() ->
    {ok, <<"l4:spam4:eggse">>} = encode([<<"spam">>, <<"eggs">>]),
    ok.

-endif.


exports.EDIT_LINE_UP                = "edit.lineUp";

exports.TOGGLE_CLOSE_BRACKETS       = "edit.autoCloseBrackets";

/*
 * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
 *
 * 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.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 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.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define */

define(function (require, exports, module) {
    "use strict";

    /**
     * List of constants for global command IDs.
     */

    // FILE
    exports.FILE_NEW                    = "file.new";
    exports.FILE_NEW_FOLDER             = "file.newFolder";
    exports.FILE_OPEN                   = "file.open";
    exports.FILE_OPEN_FOLDER            = "file.openFolder";
    exports.FILE_SAVE                   = "file.save";
    exports.FILE_SAVE_ALL               = "file.saveAll";
    exports.FILE_CLOSE                  = "file.close";
    exports.FILE_CLOSE_ALL              = "file.close_all";
    exports.FILE_CLOSE_WINDOW           = "file.close_window"; // string must MATCH string in native code (brackets_extensions)
    exports.FILE_ADD_TO_WORKING_SET     = "file.addToWorkingSet";
    exports.FILE_LIVE_FILE_PREVIEW      = "file.liveFilePreview";
    exports.FILE_LIVE_HIGHLIGHT         = "file.previewHighlight";
    exports.FILE_PROJECT_SETTINGS       = "file.projectSettings";
    exports.FILE_RENAME                 = "file.rename";
    exports.FILE_QUIT                   = "file.quit"; // string must MATCH string in native code (brackets_extensions)

    // EDIT
    exports.EDIT_UNDO                   = "edit.undo";
    exports.EDIT_REDO                   = "edit.redo";
    exports.EDIT_CUT                    = "edit.cut";
    exports.EDIT_COPY                   = "edit.copy";
    exports.EDIT_PASTE                  = "edit.paste";
    exports.EDIT_SELECT_ALL             = "edit.selectAll";
    exports.EDIT_SELECT_LINE            = "edit.selectLine";
    exports.EDIT_FIND                   = "edit.find";
    exports.EDIT_FIND_IN_FILES          = "edit.findInFiles";
    exports.EDIT_FIND_IN_SUBTREE        = "edit.findInSubtree";
    exports.EDIT_FIND_NEXT              = "edit.findNext";
    exports.EDIT_FIND_PREVIOUS          = "edit.findPrevious";
    exports.EDIT_REPLACE                = "edit.replace";
    exports.EDIT_INDENT                 = "edit.indent";
    exports.EDIT_UNINDENT               = "edit.unindent";
    exports.EDIT_DUPLICATE              = "edit.duplicate";
    exports.EDIT_DELETE_LINES           = "edit.deletelines";
    exports.EDIT_LINE_COMMENT           = "edit.lineComment";
    exports.EDIT_BLOCK_COMMENT          = "edit.blockComment";
    exports.EDIT_LINE_UP                = "edit.lineUp";
    exports.EDIT_LINE_DOWN              = "edit.lineDown";

    // VIEW
    exports.VIEW_HIDE_SIDEBAR           = "view.hideSidebar";
    exports.VIEW_INCREASE_FONT_SIZE     = "view.increaseFontSize";
    exports.VIEW_DECREASE_FONT_SIZE     = "view.decreaseFontSize";
    exports.VIEW_RESTORE_FONT_SIZE      = "view.restoreFontSize";
    exports.TOGGLE_CLOSE_BRACKETS       = "view.autoCloseBrackets";
    exports.TOGGLE_JSLINT               = "debug.jslint";
    exports.SORT_WORKINGSET_BY_ADDED    = "view.sortWorkingSetByAdded";
    exports.SORT_WORKINGSET_BY_NAME     = "view.sortWorkingSetByName";
    exports.SORT_WORKINGSET_BY_TYPE     = "view.sortWorkingSetByType";
    exports.SORT_WORKINGSET_AUTO        = "view.sortWorkingSetAuto";

    // Navigate
    exports.NAVIGATE_NEXT_DOC           = "navigate.nextDoc";
    exports.NAVIGATE_PREV_DOC           = "navigate.prevDoc";
    exports.NAVIGATE_SHOW_IN_FILE_TREE  = "navigate.showInFileTree";
    exports.NAVIGATE_QUICK_OPEN         = "navigate.quickOpen";
    exports.NAVIGATE_GOTO_DEFINITION    = "navigate.gotoDefinition";
    exports.NAVIGATE_GOTO_JSLINT_ERROR  = "navigate.gotoJSLintError";
    exports.NAVIGATE_GOTO_LINE          = "navigate.gotoLine";
    exports.TOGGLE_QUICK_EDIT           = "navigate.toggleQuickEdit";
    exports.QUICK_EDIT_NEXT_MATCH       = "navigate.nextMatch";
    exports.QUICK_EDIT_PREV_MATCH       = "navigate.previousMatch";

    // Help
    exports.HELP_CHECK_FOR_UPDATE       = "help.checkForUpdate";
    exports.HELP_HOW_TO_USE_BRACKETS    = "help.howToUseBrackets";
    exports.HELP_FORUM                  = "help.forum";
    exports.HELP_RELEASE_NOTES          = "help.releaseNotes";
    exports.HELP_REPORT_AN_ISSUE        = "help.reportAnIssue";
    exports.HELP_SHOW_EXT_FOLDER        = "help.showExtensionsFolder";
    exports.HELP_TWITTER                = "help.twitter";
    exports.HELP_ABOUT                  = "help.about";

    // File shell callbacks
    exports.APP_ABORT_QUIT              = "app.abort_quit"; // string must MATCH string in native code (appshell_extensions)
});


alt coords href hreflang media rel shape target type

autoplay controls loop mediagroup muted preload src

onafterprint onbeforeprint onbeforeunload onhashchange onmessage onoffline ononline onpagehide onpageshow onpopstate onredo onresize onstorage onundo onunload

autofocus disabled form formaction formenctype formmethod formnovalidate formtarget name type value

checked disabled icon label radiogroup type

accept-charset action autocomplete enctype method name novalidate target

height name sandbox seamless src srcdoc width

alt height ismap longdesc src usemap width

accept alt autocomplete autofocus checked dirname disabled form formaction formenctype formmethod formnovalidate formtarget height list max maxlength min multiple name pattern placeholder readonly required size src step type value width

autofocus challenge disabled form keytype name

disabled href hreflang media rel sizes type

align behavior bgcolor direction height hspace loop scrollamount scrolldelay truespeed vspace width

archive codebase codetype data declare form height name standby type usemap width

autofocus disabled form multiple name required size

autofocus cols dirname disabled form label maxlength name placeholder readonly required rows wrap

autoplay controls height loop mediagroup muted poster preload src width


/*
 * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
 *
 * 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.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 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.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, describe, it, xit, expect, beforeEach, afterEach, waitsFor, runs, $, brackets, waitsForDone */

define(function (require, exports, module) {
    "use strict";

    var CommandManager,         // loaded from brackets.test
        EditorManager,          // loaded from brackets.test
        FileIndexManager,       // loaded from brackets.test
        PerfUtils,              // loaded from brackets.test
        JSUtils,                // loaded from brackets.test

        FileUtils           = brackets.getModule("file/FileUtils"),
        NativeFileSystem    = brackets.getModule("file/NativeFileSystem").NativeFileSystem,
        SpecRunnerUtils     = brackets.getModule("spec/SpecRunnerUtils"),
        UnitTestReporter    = brackets.getModule("test/UnitTestReporter");

    var extensionPath = FileUtils.getNativeModuleDirectoryPath(module),
        testPath = extensionPath + "/unittest-files/syntax",
        tempPath = SpecRunnerUtils.getTempDirectory(),
        testWindow,
        initInlineTest;

    function rewriteProject(spec) {
        var result = new $.Deferred(),
            infos = {},
            options = {
                parseOffsets    : true,
                infos           : infos,
                removePrefix    : true
            };

        SpecRunnerUtils.copyPath(testPath, tempPath, options).done(function () {
            spec.infos = infos;
            result.resolve();
        }).fail(function () {
            result.reject();
        });

        return result.promise();
    }

    /**
     * Performs setup for an inline editor test. Parses offsets (saved to Spec.offsets) for all files in
     * the test project (testPath) and saves files back to disk without offset markup.
     * When finished, open an editor for the specified project relative file path
     * then attempts opens an inline editor at the given offset. Installs an after()
     * function restore all file content back to original state with offset markup.
     *
     * @param {!string} openFile Project relative file path to open in a main editor.
     * @param {!number} openOffset The offset index location within openFile to open an inline editor.
     * @param {?boolean} expectInline Use false to verify that an inline editor should not be opened. Omit otherwise.
     */
    var _initInlineTest = function (openFile, openOffset, expectInline, workingSet) {
        var allFiles,
            inlineOpened = null,
            spec = this;

        workingSet = workingSet || [];
        expectInline = (expectInline !== undefined) ? expectInline : true;

        runs(function () {
            waitsForDone(rewriteProject(spec), "rewriteProject");
        });

        SpecRunnerUtils.loadProjectInTestWindow(tempPath);

        runs(function () {
            workingSet.push(openFile);
            waitsForDone(SpecRunnerUtils.openProjectFiles(workingSet), "openProjectFiles");
        });

        if (openOffset !== undefined) {
            runs(function () {
                // open inline editor at specified offset index
                waitsForDone(SpecRunnerUtils.toggleQuickEditAtOffset(
                    EditorManager.getCurrentFullEditor(),
                    spec.infos[openFile].offsets[openOffset]
                ), "toggleQuickEditAtOffset");
            });
        }
    };

    describe("JSQuickEdit", function () {

        /*
         *
         */
        describe("javaScriptFunctionProvider", function () {

            beforeEach(function () {
                initInlineTest = _initInlineTest.bind(this);
                SpecRunnerUtils.createTestWindowAndRun(this, function (w) {
                    testWindow          = w;
                    EditorManager       = testWindow.brackets.test.EditorManager;
                    CommandManager      = testWindow.brackets.test.CommandManager;
                    FileIndexManager    = testWindow.brackets.test.FileIndexManager;
                    JSUtils             = testWindow.brackets.test.JSUtils;
                });

                this.addMatchers({

                    toHaveInlineEditorRange: function (range) {
                        var i = 0,
                            editor = this.actual,
                            hidden,
                            lineCount = editor.lineCount(),
                            shouldHide = [],
                            shouldShow = [],
                            startLine = range.startLine,
                            endLine = range.endLine,
                            visibleRangeCheck;

                        for (i = 0; i < lineCount; i++) {
                            hidden = editor._codeMirror.getLineHandle(i).hidden || false;

                            if (i < startLine) {
                                if (!hidden) {
                                    shouldHide.push(i); // lines above start line should be hidden
                                }
                            } else if ((i >= startLine) && (i <= endLine)) {
                                if (hidden) {
                                    shouldShow.push(i); // lines in the range should be visible
                                }
                            } else if (i > endLine) {
                                if (!hidden) {
                                    shouldHide.push(i); // lines below end line should be hidden
                                }
                            }
                        }

                        visibleRangeCheck = (editor._visibleRange.startLine === startLine) &&
                            (editor._visibleRange.endLine === endLine);

                        this.message = function () {
                            var msg = "";

                            if (shouldHide.length > 0) {
                                msg += "Expected inline editor to hide [" + shouldHide.toString() + "].\n";
                            }

                            if (shouldShow.length > 0) {
                                msg += "Expected inline editor to show [" + shouldShow.toString() + "].\n";
                            }

                            if (!visibleRangeCheck) {
                                msg += "Editor._visibleRange [" +
                                    editor._visibleRange.startLine + "," +
                                    editor._visibleRange.endLine + "] should be [" +
                                    startLine + "," + endLine + "].";
                            }

                            return msg;
                        };

                        return (shouldHide.length === 0) &&
                            (shouldShow.length === 0) &&
                            visibleRangeCheck;
                    }
                });
            });

            afterEach(function () {
                //debug visual confirmation of inline editor
                //waits(1000);

                // revert files to original content with offset markup
                SpecRunnerUtils.closeTestWindow();
            });

            it("should ignore tokens that are not function calls or references", function () {
                var editor,
                    extensionRequire,
                    jsQuickEditMain,
                    tokensFile = "tokens.js",
                    promise,
                    offsets;

                initInlineTest(tokensFile);

                runs(function () {
                    extensionRequire = testWindow.brackets.getModule("utils/ExtensionLoader").getRequireContextForExtension("JavaScriptQuickEdit");
                    jsQuickEditMain = extensionRequire("main");
                    editor = EditorManager.getCurrentFullEditor();
                    offsets = this.infos[tokensFile];

                    // regexp token
                    promise = jsQuickEditMain.javaScriptFunctionProvider(editor, offsets[0]);
                    expect(promise).toBeNull();

                    // multi-line comment
                    promise = jsQuickEditMain.javaScriptFunctionProvider(editor, offsets[1]);
                    expect(promise).toBeNull();

                    // single-line comment
                    promise = jsQuickEditMain.javaScriptFunctionProvider(editor, offsets[2]);
                    expect(promise).toBeNull();

                    // string, double quotes
                    promise = jsQuickEditMain.javaScriptFunctionProvider(editor, offsets[3]);
                    expect(promise).toBeNull();

                    // string, single quotes
                    promise = jsQuickEditMain.javaScriptFunctionProvider(editor, offsets[4]);
                    expect(promise).toBeNull();
                });
            });

            it("should open a function with  form: function functionName()", function () {
                initInlineTest("test1main.js", 0);

                runs(function () {
                    var inlineWidget = EditorManager.getCurrentFullEditor().getInlineWidgets()[0];
                    var inlinePos = inlineWidget.editors[0].getCursorPos();

                    // verify cursor position in inline editor
                    expect(inlinePos).toEqual(this.infos["test1inline.js"].offsets[0]);
                });
            });

            it("should open a function with  form: functionName = function()", function () {
                initInlineTest("test1main.js", 1);

                runs(function () {
                    var inlineWidget = EditorManager.getCurrentFullEditor().getInlineWidgets()[0];
                    var inlinePos = inlineWidget.editors[0].getCursorPos();

                    // verify cursor position in inline editor
                    expect(inlinePos).toEqual(this.infos["test1inline.js"].offsets[1]);
                });
            });

            it("should open a function with  form: functionName: function()", function () {
                initInlineTest("test1main.js", 2);

                runs(function () {
                    var inlineWidget = EditorManager.getCurrentFullEditor().getInlineWidgets()[0];
                    var inlinePos = inlineWidget.editors[0].getCursorPos();

                    // verify cursor position in inline editor
                    expect(inlinePos).toEqual(this.infos["test1inline.js"].offsets[2]);
                });
            });
        });

        describe("Performance suite", function () {

            this.category = "performance";

            var testPath = extensionPath + "/unittest-files/jquery-ui";

            beforeEach(function () {
                SpecRunnerUtils.createTestWindowAndRun(this, function (w) {
                    testWindow = w;
                    CommandManager      = testWindow.brackets.test.CommandManager;
                    EditorManager       = testWindow.brackets.test.EditorManager;
                    PerfUtils           = testWindow.brackets.test.PerfUtils;
                });
            });

            afterEach(function () {
                SpecRunnerUtils.closeTestWindow();
            });

            it("should open inline editors", function () {
                SpecRunnerUtils.loadProjectInTestWindow(testPath);

                var extensionRequire,
                    JavaScriptQuickEdit,
                    i,
                    perfMeasurements;

                runs(function () {
                    perfMeasurements = [
                        {
                            measure: PerfUtils.JAVASCRIPT_INLINE_CREATE,
                            children: [
                                {
                                    measure: PerfUtils.FILE_INDEX_MANAGER_SYNC
                                },
                                {
                                    measure: PerfUtils.JAVASCRIPT_FIND_FUNCTION,
                                    children: [
                                        {
                                            measure: PerfUtils.JSUTILS_GET_ALL_FUNCTIONS,
                                            children: [
                                                {
                                                    measure: PerfUtils.DOCUMENT_MANAGER_GET_DOCUMENT_FOR_PATH,
                                                    name: "Document creation during this search",
                                                    operation: "sum"
                                                },
                                                {
                                                    measure: PerfUtils.JSUTILS_REGEXP,
                                                    operation: "sum"
                                                }
                                            ]
                                        },
                                        {
                                            measure: PerfUtils.JSUTILS_END_OFFSET,
                                            operation: "sum"
                                        }
                                    ]
                                }
                            ]
                        }
                    ];
                });

                runs(function () {
                    extensionRequire = testWindow.brackets.getModule("utils/ExtensionLoader").getRequireContextForExtension("JavaScriptQuickEdit");
                    JavaScriptQuickEdit = extensionRequire("main");

                    waitsForDone(SpecRunnerUtils.openProjectFiles(["ui/jquery.effects.core.js"]), "openProjectFiles");
                });

                var runCreateInlineEditor = function () {
                    waitsForDone(
                        JavaScriptQuickEdit._createInlineEditor(EditorManager.getCurrentFullEditor(), "extend"),
                        "createInlineEditor"
                    );
                };

                function logPerf() {
                    var reporter = UnitTestReporter.getActiveReporter();
                    reporter.logTestWindow(perfMeasurements);
                    reporter.clearTestWindow();
                }

                // repeat 5 times
                for (i = 0; i < 5; i++) {
                    runs(runCreateInlineEditor);
                    runs(logPerf);
                }
            });

        });
    });
});


<!DOCTYPE html>

	<meta charset="utf-8">
	<title>jQuery UI Progressbar - Animated</title>
	<link rel="stylesheet" href="../../themes/base/jquery.ui.all.css">

	<link rel="stylesheet" href="../demos.css">

This progressbar has an animated fill by setting the
background-image
on the
.ui-progressbar-value
element, using css.


exports.VIEW_DECREASE_FONT_SIZE     = "view.decreaseFontSize";

exports.VIEW_RESTORE_FONT_SIZE      = "view.restoreFontSize";

exports.TOGGLE_CLOSE_BRACKETS       = "view.autoCloseBrackets";

exports.TOGGLE_JSLINT               = "debug.jslint";

exports.SORT_WORKINGSET_BY_ADDED    = "view.sortWorkingSetByAdded";

exports.SORT_WORKINGSET_BY_NAME     = "view.sortWorkingSetByName";

exports.SORT_WORKINGSET_BY_TYPE     = "view.sortWorkingSetByType";

/*
 * Copyright (c) 2012 Adobe Systems Incorporated. All rights reserved.
 *
 * 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.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 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.
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define */

define({
    /**
     * Errors
     */

    // General file io error strings
    "GENERIC_ERROR"                     : "(error {0})",
    "NOT_FOUND_ERR"                     : "The file could not be found.",
    "NOT_READABLE_ERR"                  : "The file could not be read.",
    "NO_MODIFICATION_ALLOWED_ERR"       : "The target directory cannot be modified.",
    "NO_MODIFICATION_ALLOWED_ERR_FILE"  : "The permissions do not allow you to make modifications.",
    "FILE_EXISTS_ERR"                   : "The file already exists.",

    // Project error strings
    "ERROR_LOADING_PROJECT"             : "Error loading project",
    "OPEN_DIALOG_ERROR"                 : "An error occurred when showing the open file dialog. (error {0})",
    "REQUEST_NATIVE_FILE_SYSTEM_ERROR"  : "An error occurred when trying to load the directory {0}. (error {1})",
    "READ_DIRECTORY_ENTRIES_ERROR"      : "An error occurred when reading the contents of the directory {0}. (error {1})",

    // File open/save error string
    "ERROR_OPENING_FILE_TITLE"          : "Error opening file",
    "ERROR_OPENING_FILE"                : "An error occurred when trying to open the file {0}. {1}",
    "ERROR_RELOADING_FILE_TITLE"        : "Error reloading changes from disk",
    "ERROR_RELOADING_FILE"              : "An error occurred when trying to reload the file {0}. {1}",
    "ERROR_SAVING_FILE_TITLE"           : "Error saving file",
    "ERROR_SAVING_FILE"                 : "An error occurred when trying to save the file {0}. {1}",
    "ERROR_RENAMING_FILE_TITLE"         : "Error renaming file",
    "ERROR_RENAMING_FILE"               : "An error occurred when trying to rename the file {0}. {1}",
    "INVALID_FILENAME_TITLE"            : "Invalid file name",
    "INVALID_FILENAME_MESSAGE"          : "Filenames cannot contain the following characters: /?*:;{}<>\\|",
    "FILE_ALREADY_EXISTS"               : "The file {0} already exists.",
    "ERROR_CREATING_FILE_TITLE"         : "Error creating file",
    "ERROR_CREATING_FILE"               : "An error occurred when trying to create the file {0}. {1}",

    // Application error strings
    "ERROR_IN_BROWSER_TITLE"            : "Oops! {APP_NAME} doesn't run in browsers yet.",
    "ERROR_IN_BROWSER"                  : "{APP_NAME} is built in HTML, but right now it runs as a desktop app so you can use it to edit local files. Please use the application shell in the github.com/adobe/brackets-shell repo to run {APP_NAME}.",

    // FileIndexManager error string
    "ERROR_MAX_FILES_TITLE"             : "Error Indexing Files",
    "ERROR_MAX_FILES"                   : "The maximum number of files have been indexed. Actions that look up files in the index may function incorrectly.",

    // Live Development error strings
    "ERROR_LAUNCHING_BROWSER_TITLE"     : "Error launching browser",
    "ERROR_CANT_FIND_CHROME"            : "The Google Chrome browser could not be found. Please make sure it is installed.",
    "ERROR_LAUNCHING_BROWSER"           : "An error occurred when launching the browser. (error {0})",

    "LIVE_DEVELOPMENT_ERROR_TITLE"      : "Live Preview Error",
    "LIVE_DEVELOPMENT_RELAUNCH_TITLE"   : "Connecting to Browser",
    "LIVE_DEVELOPMENT_ERROR_MESSAGE"    : "In order for Live Preview to connect, Chrome needs to be relaunched with remote debugging enabled.

Would you like to relaunch Chrome and enable remote debugging?",
    "LIVE_DEV_NEED_HTML_MESSAGE"        : "Open an HTML file in order to launch live preview.",
    "LIVE_DEV_NEED_BASEURL_MESSAGE"     : "To launch live preview with a server-side file, you need to specify a Base URL for this project.",
    "LIVE_DEV_SERVER_NOT_READY_MESSAGE" : "Error starting up the HTTP server for live development files. Please try again.",
    "LIVE_DEVELOPMENT_INFO_TITLE"       : "Welcome to Live Preview!",
    "LIVE_DEVELOPMENT_INFO_MESSAGE"     : "Live Preview connects {APP_NAME} to your browser. It launches a preview of your HTML file in the browser, then updates the preview instantly as you edit your code.

In this early version of {APP_NAME}, Live Preview only works with Google Chrome and updates live as you edit CSS files. Changes to HTML or JavaScript files are automatically reloaded when you save.

(You'll only see this message once.)",
    "LIVE_DEVELOPMENT_TROUBLESHOOTING"  : "For more information, see Troubleshooting Live Development connection errors.",

    "LIVE_DEV_STATUS_TIP_NOT_CONNECTED" : "Live Preview",
    "LIVE_DEV_STATUS_TIP_PROGRESS1"     : "Live Preview: Connecting\u2026",
    "LIVE_DEV_STATUS_TIP_PROGRESS2"     : "Live Preview: Initializing\u2026",
    "LIVE_DEV_STATUS_TIP_CONNECTED"     : "Disconnect Live Preview",
    "LIVE_DEV_STATUS_TIP_OUT_OF_SYNC"   : "Live Preview: Click to disconnect (Save file to update)",

    "SAVE_CLOSE_TITLE"                  : "Save Changes",
    "SAVE_CLOSE_MESSAGE"                : "Do you want to save the changes you made in the document {0}?",
    "SAVE_CLOSE_MULTI_MESSAGE"          : "Do you want to save your changes to the following files?",
    "EXT_MODIFIED_TITLE"                : "External Changes",
    "EXT_MODIFIED_MESSAGE"              : "{0} has been modified on disk, but also has unsaved changes in {APP_NAME}.

Which version do you want to keep?",
    "EXT_DELETED_MESSAGE"               : "{0} has been deleted on disk, but has unsaved changes in {APP_NAME}.

Do you want to keep your changes?",

    // Find, Replace, Find in Files
    "SEARCH_REGEXP_INFO"                : "Use /re/ syntax for regexp search",
    "FIND_RESULT_COUNT"                 : "{0} results",
    "WITH"                              : "With",
    "BUTTON_YES"                        : "Yes",
    "BUTTON_NO"                         : "No",
    "BUTTON_STOP"                       : "Stop",

    "OPEN_FILE"                         : "Open File",
    "CHOOSE_FOLDER"                     : "Choose a folder",

    "RELEASE_NOTES"                     : "Release Notes",
    "NO_UPDATE_TITLE"                   : "You're up to date!",
    "NO_UPDATE_MESSAGE"                 : "You are running the latest version of {APP_NAME}.",

    "FIND_IN_FILES_TITLE"               : "for \"{4}\" {5} - {0} {1} in {2} {3}",
    "FIND_IN_FILES_SCOPED"              : "in {0}",
    "FIND_IN_FILES_NO_SCOPE"            : "in project",
    "FIND_IN_FILES_FILE"                : "file",
    "FIND_IN_FILES_FILES"               : "files",
    "FIND_IN_FILES_MATCH"               : "match",
    "FIND_IN_FILES_MATCHES"             : "matches",
    "FIND_IN_FILES_MORE_THAN"           : "More than ",
    "FIND_IN_FILES_MAX"                 : " (showing the first {0} matches)",
    "FIND_IN_FILES_FILE_PATH"           : "File: {0}",
    "FIND_IN_FILES_LINE"                : "line: {0}",

    "ERROR_FETCHING_UPDATE_INFO_TITLE"  : "Error getting update info",
    "ERROR_FETCHING_UPDATE_INFO_MSG"    : "There was a problem getting the latest update information from the server. Please make sure you are connected to the internet and try again.",

    // Switch language
    "LANGUAGE_TITLE"                    : "Switch Language",
    "LANGUAGE_MESSAGE"                  : "Please select the desired language from the list below:",
    "LANGUAGE_SUBMIT"                   : "Reload {APP_NAME}",
    "LANGUAGE_CANCEL"                   : "Cancel",

    /**
     * ProjectManager
     */

    "UNTITLED" : "Untitled",

    /**
     * Keyboard modifier names
     */

    "KEYBOARD_CTRL"   : "Ctrl",
    "KEYBOARD_SHIFT"  : "Shift",
    "KEYBOARD_SPACE"  : "Space",

    /**
     * StatusBar strings
     */
    "STATUSBAR_CURSOR_POSITION"             : "Line {0}, Column {1}",
    "STATUSBAR_INDENT_TOOLTIP_SPACES"       : "Click to switch indentation to spaces",
    "STATUSBAR_INDENT_TOOLTIP_TABS"         : "Click to switch indentation to tabs",
    "STATUSBAR_INDENT_SIZE_TOOLTIP_SPACES"  : "Click to change number of spaces used when indenting",
    "STATUSBAR_INDENT_SIZE_TOOLTIP_TABS"    : "Click to change tab character width",
    "STATUSBAR_SPACES"                      : "Spaces",
    "STATUSBAR_TAB_SIZE"                    : "Tab Size",
    "STATUSBAR_LINE_COUNT"                  : "{0} Lines",

    /**
     * Command Name Constants
     */

    // File menu commands
    "FILE_MENU"                           : "File",
    "CMD_FILE_NEW"                        : "New File",
    "CMD_FILE_NEW_FOLDER"                 : "New Folder",
    "CMD_FILE_OPEN"                       : "Open\u2026",
    "CMD_ADD_TO_WORKING_SET"              : "Add To Working Set",
    "CMD_OPEN_FOLDER"                     : "Open Folder\u2026",
    "CMD_FILE_CLOSE"                      : "Close",
    "CMD_FILE_CLOSE_ALL"                  : "Close All",
    "CMD_FILE_SAVE"                       : "Save",
    "CMD_FILE_SAVE_ALL"                   : "Save All",
    "CMD_LIVE_FILE_PREVIEW"               : "Live Preview",
    "CMD_LIVE_HIGHLIGHT"                  : "Live Highlight",
    "CMD_PROJECT_SETTINGS"                : "Project Settings\u2026",
    "CMD_FILE_RENAME"                     : "Rename",
    "CMD_QUIT"                            : "Quit",
    // Used in native File menu on Windows
    "CMD_EXIT"                            : "Exit",

    // Edit menu commands
    "EDIT_MENU"                           : "Edit",
    "CMD_UNDO"                            : "Undo",
    "CMD_REDO"                            : "Redo",
    "CMD_CUT"                             : "Cut",
    "CMD_COPY"                            : "Copy",
    "CMD_PASTE"                           : "Paste",
    "CMD_SELECT_ALL"                      : "Select All",
    "CMD_SELECT_LINE"                     : "Select Line",
    "CMD_FIND"                            : "Find",
    "CMD_FIND_IN_FILES"                   : "Find in Files",
    "CMD_FIND_IN_SUBTREE"                 : "Find in\u2026",
    "CMD_FIND_NEXT"                       : "Find Next",
    "CMD_FIND_PREVIOUS"                   : "Find Previous",
    "CMD_REPLACE"                         : "Replace",
    "CMD_INDENT"                          : "Indent",
    "CMD_UNINDENT"                        : "Unindent",
    "CMD_DUPLICATE"                       : "Duplicate",
    "CMD_DELETE_LINES"                    : "Delete Line",
    "CMD_COMMENT"                         : "Toggle Line Comment",
    "CMD_BLOCK_COMMENT"                   : "Toggle Block Comment",
    "CMD_LINE_UP"                         : "Move Line Up",
    "CMD_LINE_DOWN"                       : "Move Line Down",

    // View menu commands
    "VIEW_MENU"                           : "View",
    "CMD_HIDE_SIDEBAR"                    : "Hide Sidebar",
    "CMD_SHOW_SIDEBAR"                    : "Show Sidebar",
    "CMD_INCREASE_FONT_SIZE"              : "Increase Font Size",
    "CMD_DECREASE_FONT_SIZE"              : "Decrease Font Size",
    "CMD_RESTORE_FONT_SIZE"               : "Restore Font Size",
    "CMD_TOGGLE_CLOSE_BRACKETS"           : "Enable Close Brackets",
    "CMD_SORT_WORKINGSET_BY_ADDED"        : "Sort by Added",
    "CMD_SORT_WORKINGSET_BY_NAME"         : "Sort by Name",
    "CMD_SORT_WORKINGSET_BY_TYPE"         : "Sort by Type",
    "CMD_SORT_WORKINGSET_AUTO"            : "Automatic Sort",

    // Navigate menu Commands
    "NAVIGATE_MENU"                       : "Navigate",
    "CMD_QUICK_OPEN"                      : "Quick Open",
    "CMD_GOTO_LINE"                       : "Go to Line",
    "CMD_GOTO_DEFINITION"                 : "Go to Definition",
    "CMD_JSLINT_FIRST_ERROR"              : "Go to First JSLint Error",
    "CMD_TOGGLE_QUICK_EDIT"               : "Quick Edit",
    "CMD_QUICK_EDIT_PREV_MATCH"           : "Previous Match",
    "CMD_QUICK_EDIT_NEXT_MATCH"           : "Next Match",
    "CMD_NEXT_DOC"                        : "Next Document",
    "CMD_PREV_DOC"                        : "Previous Document",
    "CMD_SHOW_IN_TREE"                    : "Show in File Tree",

    // Debug menu commands
    "DEBUG_MENU"                          : "Debug",
    "CMD_REFRESH_WINDOW"                  : "Reload {APP_NAME}",
    "CMD_SHOW_DEV_TOOLS"                  : "Show Developer Tools",
    "CMD_RUN_UNIT_TESTS"                  : "Run Tests",
    "CMD_JSLINT"                          : "Enable JSLint",
    "CMD_SHOW_PERF_DATA"                  : "Show Performance Data",
    "CMD_NEW_BRACKETS_WINDOW"             : "New {APP_NAME} Window",
    "CMD_SHOW_EXTENSIONS_FOLDER"          : "Show Extensions Folder",
    "CMD_SWITCH_LANGUAGE"                 : "Switch Language",
    "CMD_ENABLE_NODE_DEBUGGER"            : "Enable Node Debugger",
    "CMD_LOG_NODE_STATE"                  : "Log Node State to Console",
    "CMD_RESTART_NODE"                    : "Restart Node",

    // Help menu commands
    "HELP_MENU"                           : "Help",
    "CMD_CHECK_FOR_UPDATE"                : "Check for Updates",
    "CMD_HOW_TO_USE_BRACKETS"             : "How to Use {APP_NAME}",
    "CMD_FORUM"                           : "{APP_NAME} Forum",
    "CMD_RELEASE_NOTES"                   : "Release Notes",
    "CMD_REPORT_AN_ISSUE"                 : "Report an Issue",
    "CMD_TWITTER"                         : "{TWITTER_NAME} on Twitter",
    "CMD_ABOUT"                           : "About {APP_TITLE}",

    // Special commands invoked by the native shell
    "CMD_CLOSE_WINDOW"                    : "Close Window",
    "CMD_ABORT_QUIT"                      : "Abort Quit",

    // Strings for main-view.html
    "EXPERIMENTAL_BUILD"                   : "experimental build",
    "DEVELOPMENT_BUILD"                    : "development build",
    "JSLINT_ERRORS"                        : "JSLint Errors",
    "JSLINT_ERROR_INFORMATION"             : "1 JSLint Error",
    "JSLINT_ERRORS_INFORMATION"            : "{0} JSLint Errors",
    "JSLINT_NO_ERRORS"                     : "No JSLint errors - good job!",
    "JSLINT_DISABLED"                      : "JSLint disabled or not working for the current file",
    "SEARCH_RESULTS"                       : "Search Results",
    "OK"                                   : "OK",
    "DONT_SAVE"                            : "Don't Save",
    "SAVE"                                 : "Save",
    "CANCEL"                               : "Cancel",
    "RELOAD_FROM_DISK"                     : "Reload from Disk",
    "KEEP_CHANGES_IN_EDITOR"               : "Keep Changes in Editor",
    "CLOSE_DONT_SAVE"                      : "Close (Don't Save)",
    "RELAUNCH_CHROME"                      : "Relaunch Chrome",
    "ABOUT"                                : "About",
    "APP_NAME"                             : "Brackets",
    "CLOSE"                                : "Close",
    "ABOUT_TEXT_LINE1"                     : "sprint {VERSION_MINOR} {BUILD_TYPE} {VERSION}",
    "ABOUT_TEXT_LINE3"                     : "Notices, terms and conditions pertaining to third party software are located at http://www.adobe.com/go/thirdparty/ and incorporated by reference herein.",
    "ABOUT_TEXT_LINE4"                     : "Documentation and source at https://github.com/adobe/brackets/",
    "ABOUT_TEXT_LINE5"                     : "Made with \u2764 and JavaScript by:",
    "ABOUT_TEXT_LINE6"                     : "Lots of people (but we're having trouble loading that data right now).",
    "UPDATE_NOTIFICATION_TOOLTIP"          : "There's a new build of {APP_NAME} available! Click here for details.",
    "UPDATE_AVAILABLE_TITLE"               : "Update Available",
    "UPDATE_MESSAGE"                       : "Hey, there's a new build of {APP_NAME} available. Here are some of the new features:",
    "GET_IT_NOW"                           : "Get it now!",
    "PROJECT_SETTINGS_TITLE"               : "Project Settings for: {0}",
    "PROJECT_SETTING_BASE_URL"             : "Live Preview Base URL",
    "PROJECT_SETTING_BASE_URL_HINT"        : "(to use a local server, specify url)",
    "BASEURL_ERROR_INVALID_PROTOCOL"       : "The {0} protocol isn't supported by Live Preview—please use http: or https: .",
    "BASEURL_ERROR_SEARCH_DISALLOWED"      : "The base URL can't contain search parameters like \"{0}\".",
    "BASEURL_ERROR_HASH_DISALLOWED"        : "The base URL can't contain hashes like \"{0}\".",
    "BASEURL_ERROR_INVALID_CHAR"           : "Special characters like '{0}' must be %-encoded.",
    "BASEURL_ERROR_UNKOWN_ERROR"           : "Unknown error parsing Base URL",

    // extensions/default/InlineColorEditor
    "COLOR_EDITOR_CURRENT_COLOR_SWATCH_TIP"     : "Current Color",
    "COLOR_EDITOR_ORIGINAL_COLOR_SWATCH_TIP"    : "Original Color",
    "COLOR_EDITOR_RGBA_BUTTON_TIP"              : "RGBa Format",
    "COLOR_EDITOR_HEX_BUTTON_TIP"               : "Hex Format",
    "COLOR_EDITOR_HSLA_BUTTON_TIP"              : "HSLa Format",
    "COLOR_EDITOR_USED_COLOR_TIP_SINGULAR"      : "{0} (Used {1} time)",
    "COLOR_EDITOR_USED_COLOR_TIP_PLURAL"        : "{0} (Used {1} times)"
});