diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml new file mode 100644 index 0000000..f28d053 --- /dev/null +++ b/.github/workflows/workflow.yml @@ -0,0 +1,23 @@ +name: main +on: [push] +jobs: + run: + name: Run + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: [ubuntu-latest] + steps: + - uses: actions/checkout@master + - name: Set Node.js 12.x + uses: actions/setup-node@master + with: + version: 12.x + - name: npm install + run: npm ci + - name: lint + run: npm run lint + - name: build + run: npm run build + - name: npm test + run: npm test diff --git a/.gitignore b/.gitignore index d431b88..fe1c0d9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ -node_modules/* -doc/* \ No newline at end of file +node_modules +doc +*.js +*.d.ts +!src/index.d.ts diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index 7f111c0..0000000 --- a/Gruntfile.js +++ /dev/null @@ -1,45 +0,0 @@ -module.exports = function (grunt) { -grunt.loadNpmTasks('grunt-browserify'); -grunt.loadNpmTasks('grunt-simple-mocha'); -grunt.loadNpmTasks('grunt-jsdoc'); -grunt.initConfig({ - browserify: { - dist: { - src: './coordinate-systems.js', - dest: 'build/coordinate-systems.min.js', - options: { - keepalive: true, - watch: true, - transform: ['uglifyify'] - }, - } - }, - simplemocha: { - options: { - globals: ['should'], - timeout: 3000, - ignoreLeaks: true, - ui: 'bdd', - reporter: 'spec' - }, - all: { - src: 'test/test.js' - } - }, - jsdoc : { - dist : { - src: ['*.js'], - options: { - destination: 'doc', - template : "node_modules/grunt-jsdoc/node_modules/ink-docstrap/template", - configure : "node_modules/grunt-jsdoc/node_modules/ink-docstrap/template/jsdoc.conf.json" - } - } - } -}); - -grunt.registerTask('test', ['simplemocha']); -grunt.registerTask('doc', ['jsdoc']); -grunt.registerTask('default', ['test', 'browserify', 'jsdoc']); - -}; \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 3ed78e2..0000000 --- a/README.md +++ /dev/null @@ -1,78 +0,0 @@ -[ ![Codeship Status for cdaringe/coordinate-systems](https://codeship.com/projects/17a94530-8285-0132-f7da-56a1ab730b01/status?branch=master)](https://codeship.com/projects/57887) - - -# coordinate-systems -Convert between common 2d and 3d coordinate systems! Supports: - -1. cartesian (2d) -1. cartesian (3d) -1. polar (2d) -1. cylindrical (3d) -1. spherical (3d) - -# Usage -Checkout the docs for reference (`docs/index.html`). The code is short and well documented too! Module interface shown below, too. Generally, construct a `Coordinate` using one of the provided static constructor functions. -Run the conversion member function to convert to an array of values in [x, y, z?]/[r, t, p?/z?] format. - -```js -var Coordinate = require('coordinate-systems'); - -var xy = Coordinate.cart([0, 5]); // 2d cartesian -var xyz = Coordinate.cart([1, 2, 3]); // 3d cartesian - -xy.polar(); // [ 5, 1.5707963267948966 ] (i.e. radius 5, theta π/2 radians) -xyz.spherical(); // [ 3.74..., 1.10..., 0.64... ] (radius, theta, phi) -``` - -If you want to use degrees, extend the construction function as such: - -```js -var xy = Coordinate.cart({ - coords: [0, 5], - isDegree: true -}); - -xy.polar(); // [ 5, 90 ] heyo! who uses degrees anyway :) -``` - -# Summarized Interface -```js -// static constructor functions -// e.g. var myCoord = Coordinate.polar([10, Math.PI/8]); - - cart(coordinates) → {Coordinate} - cartesian(coordinates) → {Coordinate} - cyl(coordinates) → {Coordinate} - cylindrical(coordinates) → {Coordinate} - pol(coordinates) → {Coordinate} - polar(coordinates) → {Coordinate} - sph(coordinates) → {Coordinate} - spherical(coordinates) → {Coordinate} - -// conversion functions -// e.g. myCoord.cyl(); // renders cylindrical coords, [r, t, z] -.cart() -.cartesian() - -.cyl() -.cylindrical() - -.pol() -.polar() - -.spherical() -.sph() - -// under-the-hood conversion functions (no need to use these directly) - cartesian2dToPolar(xy, isDegree, center) → {Array} - cartesian3dToCylindrical(argument, isDegree, center) → {Array} - cartesian3dToSpherical(argument, isDegree, center) → {Array} - cylindricalToSpherical(rtz, isDegree) → {Array} - polarToCart2d(rt, isDegree) → {Array} - sphericalToCart3d(rtz, isDegree) → {Array} - sphericalToCylindrical(rtz, isDegree) → {Array} -``` - -# Notes -Tests are generated and passing. These have not run through extensive use cases yet, -so additional testing and feedback is gladly welcomed! diff --git a/build/coordinate-systems.min.js b/build/coordinate-systems.min.js deleted file mode 100644 index 03ae366..0000000 --- a/build/coordinate-systems.min.js +++ /dev/null @@ -1,42 +0,0 @@ -(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o3)throw new Error("expected exactly 2 or exactly 3 cartesian options");return t={label:"cart2d",options:r.coords},t=extend(t,r),2===r.coords.length?new Coordinate(t):(t.label="cart3d",new Coordinate(t))}throw new Error("expected options w/ array of [x,y,(z?)] coords")},Coordinate.cylindrical=function(r){return Coordinate.cyl(r)},Coordinate.cyl=function(r){var t;if(isArray(r)&&(r={coords:r}),isObject(r)&&isArray(r.coords)){if(Coordinate.arrToNumeric(r.coords),3!==r.coords.length)throw new Error("expected exactly 3 params [r, t, z]");return t={label:"cylindrical",coords:r.coords},t=extend(t,r),new Coordinate(t)}throw new Error("expected options w/ array of [r, t, z] coords")},Coordinate.polar=function(r){return Coordinate.pol(r)},Coordinate.pol=function(r){var t;if(isArray(r)&&(r={coords:r}),isObject(r)&&isArray(r.coords)){if(Coordinate.arrToNumeric(r.coords),2!==r.coords.length)throw new Error("expected exactly 2 params [r, t]");return t={label:"polar",coords:r.coords},t=extend(t,r),new Coordinate(t)}throw new Error("expected array of [r, t] options")},Coordinate.spherical=function(r){return Coordinate.sph(r)},Coordinate.sph=function(r){var t;if(isArray(r)&&(r={coords:r}),isObject(r)&&isArray(r.coords)){if(Coordinate.arrToNumeric(r.coords),3!==r.coords.length)throw new Error("expected exactly 3 params [r, t, p]");return t={label:"spherical",coords:r.coords},t=extend(t,r),new Coordinate(t)}throw new Error("expected options w/ array of [r, t, p] coords")},Coordinate.arrToNumeric=function(r){var t;if(!isArray(r))throw new TypeError("expected array of number-like values");for(var e=r.length-1;e>=0;e--)if(t=r[e],"string"==typeof t&&(t=parseFloat(t)),!isNumber(t))throw new TypeError(t+" not numeric")},Coordinate.polarToCart2d=function(r,t){var e,o,i,a;return e=r[0],o=r[1],t&&(o*=1/degPerRadian),i=e*Math.cos(o),a=e*Math.sin(o),[i,a]},Coordinate.cart2dToPolar=function(r,t,e){var o,i,a,n;if(!isArray(r)&&2!==r.length)throw new TypeError("expected [x, y] xy array");if(o=r[0],i=r[1],e&&!isArray(e)&&2!==e.length)throw new TypeError("expected [x, y] center array");return e&&(o-=e[0],i-=e[1]),a=Math.sqrt(o*o+i*i),n=Math.atan2(i,o),t&&(n*=degPerRadian),[a,n]},Coordinate.cart3dToCylindrical=function(r,t,e){var o,i=r[0],a=r[1],n=r[2];return o=Coordinate.cart2dToPolar([i,a],t,e),[o[0],o[1],n]},Coordinate.cart3dToSpherical=function(r,t,e){if(e&&3!==e.length)throw new Error("expected center value to have [x, y, z] coordsfor locating sphere center");var o,i,a,n,s,c,d=r[0],p=r[1],l=r[2];return e&&(d-=e[0],p-=e[1],l-=e[2]),o=d*d,i=p*p,a=l*l,n=Math.sqrt(o+i+a),n?(s=Math.atan2(p,d),c=Math.atan2(Math.sqrt(o+i),l),t&&(s*=degPerRadian,c*=degPerRadian)):c=s=0,[n,s,c]},Coordinate.cylToSpherical=function(r,t){var e,o,i=r[0],a=r[1],n=r[2];return t&&(a/=degPerRadian),e=Math.sqrt(i*i+n*n),o=Math.atan2(i,n),t&&(o*=degPerRadian,a*=degPerRadian),[e,a,o]},Coordinate.sphericalToCart3d=function(r,t){var e,o,i,a=r[0],n=r[1],s=r[2];return t&&(n/=degPerRadian,s/=degPerRadian),e=a*Math.sin(s)*Math.cos(n),o=a*Math.sin(s)*Math.sin(n),i=a*Math.cos(s),[e,o,i]},Coordinate.sphToCylindrical=function(r,t){var e,o,i=r[0],a=r[1],n=r[2];return t&&(a/=degPerRadian,n/=degPerRadian),e=i*Math.sin(n),o=i*Math.cos(n),t&&(a*=degPerRadian,n*=degPerRadian),[e,a,o]},module.exports=Coordinate; -},{"amp-extend":"/Users/cdaringe/node/coordinate-systems/node_modules/amp-extend/extend.js","amp-is-array":"/Users/cdaringe/node/coordinate-systems/node_modules/amp-is-array/is-array.js","amp-is-number":"/Users/cdaringe/node/coordinate-systems/node_modules/amp-is-number/is-number.js","amp-is-object":"/Users/cdaringe/node/coordinate-systems/node_modules/amp-is-object/is-object.js"}],"/Users/cdaringe/node/coordinate-systems/node_modules/amp-extend/extend.js":[function(require,module,exports){ -var isObject = require('amp-is-object'); - - -module.exports = function(obj) { - if (!isObject(obj)) return obj; - var source, prop; - for (var i = 1, length = arguments.length; i < length; i++) { - source = arguments[i]; - for (prop in source) { - obj[prop] = source[prop]; - } - } - return obj; -}; - -},{"amp-is-object":"/Users/cdaringe/node/coordinate-systems/node_modules/amp-is-object/is-object.js"}],"/Users/cdaringe/node/coordinate-systems/node_modules/amp-is-array/is-array.js":[function(require,module,exports){ -var toString = Object.prototype.toString; -var nativeIsArray = Array.isArray; - - -module.exports = nativeIsArray || function isArray(obj) { - return toString.call(obj) === '[object Array]'; -}; - -},{}],"/Users/cdaringe/node/coordinate-systems/node_modules/amp-is-number/is-number.js":[function(require,module,exports){ -var toString = Object.prototype.toString; - - -module.exports = function isNumber(obj) { - return toString.call(obj) === '[object Number]'; -}; - -},{}],"/Users/cdaringe/node/coordinate-systems/node_modules/amp-is-object/is-object.js":[function(require,module,exports){ -module.exports = function isObject(obj) { - var type = typeof obj; - return !!obj && (type === 'function' || type === 'object'); -}; - -},{}]},{},["/Users/cdaringe/node/coordinate-systems/coordinate-systems.js"]); diff --git a/coordinate-systems.js b/coordinate-systems.js deleted file mode 100644 index 69afe96..0000000 --- a/coordinate-systems.js +++ /dev/null @@ -1,566 +0,0 @@ -"use strict"; -var isArray = require('amp-is-array'); -var isNumber = require('amp-is-number'); -var isObject = require('amp-is-object'); -var extend = require('amp-extend'); -var degPerRadian = 180 / Math.PI; - -/** - * @constructor Coordinate - * @description Defines object which can convert between coordinate systems. - * It is recommended to use one of the Coodinate.STATIC_CONSTRUCTOR functions - * to generate your first coordinate before conversions. e.g. Coodinate.spherical(...) - * @param {Object} config - * { - * label: 'type of initial coordinate', - * coords: { - * x/y/z/r/t/p: 'k-v pairs' - * }, - * isDegree: Boolean - * } - */ -var Coordinate = function (config) { - var isRadian, - isDegree, - pos = {}, - _x, _y, _z, _r, _t, _p; - - // Override select setters/getts - Object.defineProperty(this, "isRadian", { - get: function (x) { return isRadian; }, - set: function (x) { - isRadian = !!x; - if (isDegree !== !x) { isDegree = !x; } // jshint ignore:line - } - }); - Object.defineProperty(this, "isDegree", { - get: function (x) { return isDegree; }, - set: function (x) { - isDegree = x; - if (isRadian !== !x) { isRadian = !x; } // jshint ignore:line - } - }); - Object.defineProperty(pos, "cartesian2d", { - get: function (x) { return [_x, _y]; }, - set: function (x) { _x = x[0]; _y = x[1]; } - }); - Object.defineProperty(pos, "cartesian3d", { - get: function (x) { return [_x, _y, _z]; }, - set: function (x) { _x = x[0]; _y = x[1]; _z = x[2]; } - }); - Object.defineProperty(pos, "polar", { - get: function (x) { return [_r, _t]; }, - set: function (x) { _r = x[0]; _t = x[1]; } - }); - Object.defineProperty(pos, "cylindrical", { - get: function (x) { return [_r, _t, _z]; }, - set: function (x) { _r = x[0]; _t = x[1]; _z = x[2]; } - }); - Object.defineProperty(pos, "spherical", { - get: function (x) { return [_r, _t, _p]; }, - set: function (x) { _r = x[0]; _t = x[1]; _p = x[2]; } - }); - - // init from config - if (config.isDegree && !config.isRadian) { - this.isDegree = true; - } else { - this.isRadian = true; - } - if (!config.label || !config.coords) { - throw new Error("no coordinate type defined"); - } - this.initialType = config.label; - this.pos = pos; - this.pos[config.label] = config.coords; -}; - - - -/** - * @method cartesian - * Converts current coordinate to cartesian - * @function cartesian - * @memberof Coordinate - * @param {Object} options - * @return {Array} coordinates in respective coordinate format - */ -Coordinate.prototype.cartesian = function () { return this.cart.apply(this, arguments); }; -/** - * @method cart - * Converts current coordinate to cartesian - * @param {Object} options - * @return {Array} coordinates in respective coordinate format - */ -Coordinate.prototype.cart = function (options) { - var temp; - options = options || {}; - switch (this.initialType) { - case 'cartesian2d': - return this.pos.cartesian2d; - case 'cartesian3d': - return this.pos.cartesian3d; - case 'polar': - this.pos.cartesian2d = Coordinate.polarToCart2d(this.pos.polar, this.isDegree); - return this.pos.cartesian2d; - case 'cylindrical': - temp = Coordinate.polarToCart2d(this.pos.polar, this.isDegree); - this.pos.cartesian3d = [temp[0], temp[1], this.pos.cylindrical[2]]; - return this.pos.cartesian3d; - case 'spherical': - this.pos.cartesian3d = Coordinate.sphericalToCart3d(this.pos.spherical, this.isDegree); - return this.pos.cartesian3d; - default: - throw new Error('cannot convert to/from original/requested types'); - } -}; - - - -/** - * @method cylindrical - * Converts current coordinate to cylindrical - * @function cylindrical - * @memberof Coordinate - * @param {Object} options - * @return {Array} coordinates in respective coordinate format - */ -Coordinate.prototype.cylindrical = function () { return this.cyl.apply(this, arguments); }; -/** - * @method cyl - * Converts current coordinate to cylindrical - * @param {Object} options - * @return {Array} coordinates in respective coordinate format - */ -Coordinate.prototype.cyl = function (options) { - var temp; - options = options || {}; - switch (this.initialType) { - case 'cartesian2d': - temp = Coordinate.cartesian2dToPolar(this.pos.cartesian2d, this.isDegree, options.center); - this.pos.cylindrical = [temp[0], temp[1], 0]; - return this.pos.cylindrical; - case 'cartesian3d': - this.pos.cylindrical = Coordinate.cartesian3dToCylindrical(this.pos.cartesian3d, this.isDegree, options.center); - return this.pos.cylindrical; - case 'polar': - temp = this.pos.polar; - return [temp[0], temp[1], 0]; - case 'cylindrical': - return this.pos.cylindrical; - case 'spherical': - this.pos.cylindrical = Coordinate.sphericalToCylindrical(this.pos.spherical, this.isDegree); - return this.pos.cylindrical; - default: - throw new Error('cannot convert to/from original/requested types'); - } -}; - -/** - * @method pol - * Converts current coordinate to polar - * @param {Object} options - * @return {Array} coordinates in respective coordinate format - */ -Coordinate.prototype.pol = function () { return this.polar.apply(this, arguments); }; -/** - * @method polar - * Converts current coordinate to polar - * @param {Object} options - * @return {Array} coordinates in respective coordinate format - */ -Coordinate.prototype.polar = function (options) { - options = options || {}; - switch (this.initialType) { - case 'cartesian2d': - this.pos.polar = Coordinate.cartesian2dToPolar(this.pos.cartesian2d, this.isDegree, options.center); - return this.pos.polar; - case 'polar': - return this.pos.polar; - default: - throw new Error('cannot convert to/from original/requested types'); - } -}; - - - -/** - * @method spherical - * Converts current coordinate to spherical - * @param {Object} options - * @return {Array} coordinates in respective coordinate format - */ -Coordinate.prototype.spherical = function () { return this.sph.apply(this, arguments); }; -/** - * @method sph - * Converts current coordinate to spherical - * @param {Object} options - * @return {Array} coordinates in respective coordinate format - */ -Coordinate.prototype.sph = function (options) { - var temp; - options = options || {}; - switch (this.initialType) { - case 'cartesian2d': - temp = Coordinate.cartesian2dToPolar(this.pos.cartesian2d, this.isDegree, options.center); - this.pos.spherical = [temp[0], temp[1], 0]; - return this.pos.spherical; - case 'cartesian3d': - this.pos.spherical = Coordinate.cartesian3dToSpherical(this.pos.cartesian3d, this.isDegree, options.center); - return this.pos.spherical; - case 'polar': - temp = this.pos.polar; - return [temp[0], temp[1], 0]; - case 'cylindrical': - this.pos.spherical = Coordinate.cylindricalToSpherical(this.pos.cylindrical, this.isDegree); - return this.pos.spherical; - case 'spherical': - return this.pos.spherical; - default: - throw new Error('cannot convert to/from original/requested types'); - } -}; - - -/// -/// Static Constructor Functions -/// - -/** - * Create a point provided x, y, and optionally z coordinates - * @param {Object} coordinates - * @return {Coordinate} - */ -Coordinate.cartesian = function(x) { return Coordinate.cart(x); }; -/** - * Create a point provided x, y, and optionally z coordinates - * @param {Object} coordinates - * @return {Coordinate} - */ -Coordinate.cart = function(options) { - var baseCoord; - if (isArray(options)) { - options = {coords: options}; - } - if (isObject(options) && isArray(options.coords)) { - Coordinate.arrToNumeric(options.coords); - if (options.coords.length < 2 || options.coords.length > 3) { - throw new Error('expected exactly 2 or exactly 3 cartesian options'); - } - baseCoord = { - label: 'cartesian2d', - options: options.coords - }; - baseCoord = extend(baseCoord, options); - if (options.coords.length === 2) { - return new Coordinate(baseCoord); - } - baseCoord.label = 'cartesian3d'; - return new Coordinate(baseCoord); - } - throw new Error('expected options w/ array of [x,y,(z?)] coords'); -}; - - - -/** - * Create point provided [radius, theta, z] - * @param {Object} coordinates - * @return {Coordinate} - */ -Coordinate.cylindrical = function(x) { return Coordinate.cyl(x); }; -/** - * Create point provided [radius, theta, z] - * @param {Object} coordinates - * @return {Coordinate} - */ -Coordinate.cyl = function(options) { - var baseCoord; - if (isArray(options)) { - options = {coords: options}; - } - if (isObject(options) && isArray(options.coords)) { - Coordinate.arrToNumeric(options.coords); - if (options.coords.length !== 3) { - throw new Error('expected exactly 3 params [r, t, z]'); - } - baseCoord = { - label: 'cylindrical', - coords: options.coords - }; - baseCoord = extend(baseCoord, options); - return new Coordinate(baseCoord); - } - throw new Error('expected options w/ array of [r, t, z] coords'); -}; - - - -/** - * Create point provided [radius, theta] - * @param {Object} coordinates - * @return {Coordinate} - */ -Coordinate.polar = function(x) { return Coordinate.pol(x); }; -/** - * Create point provided [radius, theta] - * @param {Object} coordinates - * @return {Coordinate} - */ -Coordinate.pol = function(options) { - var baseCoord; - if (isArray(options)) { - options = {coords: options}; - } - if (isObject(options) && isArray(options.coords)) { - Coordinate.arrToNumeric(options.coords); - if (options.coords.length !== 2) { - throw new Error('expected exactly 2 params [r, t]'); - } - baseCoord = { - label: 'polar', - coords: options.coords - }; - baseCoord = extend(baseCoord, options); - return new Coordinate(baseCoord); - } - throw new Error('expected array of [r, t] options'); -}; - - - -/** - * Create point provided [radius, theta, phi] - * @param {Object} coordinates - * @return {Coordinate} - */ -Coordinate.spherical = function(options) { return Coordinate.sph(options); }; -/** - * Create point provided [radius, theta, phi] - * @param {Object} coordinates - * @return {Coordinate} - */ -Coordinate.sph = function(options) { - var baseCoord; - if (isArray(options)) { - options = {coords: options}; - } - if (isObject(options) && isArray(options.coords)) { - Coordinate.arrToNumeric(options.coords); - if (options.coords.length !== 3) { - throw new Error('expected exactly 3 params [r, t, p]'); - } - baseCoord = { - label: 'spherical', - coords: options.coords - }; - baseCoord = extend(baseCoord, options); - return new Coordinate(baseCoord); - } - throw new Error('expected options w/ array of [r, t, p] coords'); -}; - - - -/** - * Mutates an array of number-like looking values to purely numeric array - * @example - * [5, '2.4', '0'] => [5, 2.4, 0] - * @param {Array} nums - * @return {undefined} - */ -Coordinate.arrToNumeric = function(nums) { - var num; - if (!isArray(nums)) { - throw new TypeError("expected array of number-like values"); - } - for (var i = nums.length - 1; i >= 0; i--) { - num = nums[i]; - if (typeof num === 'string') { - num = parseFloat(num); - } - if (!isNumber(num)) { - throw new TypeError(num + ' not numeric or numeric-like'); - } - } -}; - - - -/** - * Convert polar to 2d cartesian coordinates - * @param {Array} rt [radis, theta] - * @param {Boolean} isDegree specifies units - * @return {Array} [x, y] - */ -Coordinate.polarToCart2d = function(rt, isDegree) { - var r, t, x, y; - r = rt[0]; - t = rt[1]; - if (isDegree) { - t = t * (1/degPerRadian); - } - x = r * Math.cos(t); - y = r * Math.sin(t); - return [x, y]; -}; - - - -/** - * Convert cartesian 2d to polar coordinates - * @param {Array} xy - * @param {Boolean=} isDegree overrides default radian theta assumption - * @param {Array=} center [x, y] coords of center of circle. Defaults to [0, 0], - * however may be offset. Note. Such functionality not supported yet for converting - * polar to cartesian - * @return {Array} [radius, theta] - */ -Coordinate.cartesian2dToPolar = function(xy, isDegree, center) { - var x, y, r, t; - if (!isArray(xy) && xy.length !== 2) { - throw new TypeError('expected [x, y] xy array'); - } - x = xy[0]; - y = xy[1]; - if (center && !isArray(center) && center.length !== 2) { - throw new TypeError('expected [x, y] center array'); - } - if (center) { - x = x - center[0]; - y = y - center[1]; - } - r = Math.sqrt(x*x + y*y); - t = Math.atan2(y, x); - if (isDegree) { - t = t * degPerRadian; - } - return [r, t]; -}; - - - -/** - * Convert 3d cartesian to 3d cylindrical coordinates - * @param {Array} argument [x, y, z] coords - * @param {Boolean=} isDegree overrides default radian theta assumption - * @param {Array=} center [x, y] coords of center of circle - * @return {Array} [radius, theta, z] - */ -Coordinate.cartesian3dToCylindrical = function (xyz, isDegree, center) { - var x = xyz[0], - y = xyz[1], - z = xyz[2], - rt; - rt = Coordinate.cartesian2dToPolar([x, y], isDegree, center); - return [rt[0], rt[1], z]; -}; - - - -/** - * Convert 3d cartesian to 3d spherical coordinates - * @param {Array} argument [x, y, z] coords - * @param {Boolean=} isDegree overrides default radian theta assumption - * @param {Array=} center [x, y, z] coords of center of circle - * @return {Array} [radius, theta, phi] - */ -Coordinate.cartesian3dToSpherical = function (xyz, isDegree, center) { - if (center && center.length !== 3) { - throw new Error('expected center value to have [x, y, z] coords' + - 'for locating sphere center'); - } - var x = xyz[0], - y = xyz[1], - z = xyz[2], - x2, y2, z2, - r, t, p; - if (center) { - x = x - center[0]; - y = y - center[1]; - z = z - center[2]; - } - x2 = x*x; y2 = y*y; z2 = z*z; - r = Math.sqrt(x2 + y2 + z2); - if (!r) { - p = t = 0; - } else { - t = Math.atan2(y,x); - p = Math.atan2(Math.sqrt(x2 + y2), z); - if (isDegree) { - t = t * degPerRadian; - p = p * degPerRadian; - } - } - return [r, t, p]; -}; - - - -/** - * Convert a cylindrical to a spherical coordinates - * @param {Array} rtz - * @param {Boolean} isDegree - * @return {Array} [radius, theta, phi] - */ -Coordinate.cylindricalToSpherical = function(rtz, isDegree) { - var r = rtz[0], t = rtz[1], z = rtz[2]; - var sr, sp; // sphere radius, sphere theta... - if (isDegree) { - t = t / degPerRadian; - } - sr = Math.sqrt(r*r + z*z); - sp = Math.atan2(r, z); - if (isDegree) { - sp = sp * degPerRadian; - t = t * degPerRadian; - } - return [sr, t, sp]; -}; - - - -/** - * Convert spherical to a cartesian coordinates - * @param {Array} rtz - * @param {Boolean} isDegree - * @return {Array} - */ -Coordinate.sphericalToCart3d = function (rtp, isDegree) { - var r = rtp[0], t = rtp[1], p = rtp[2], - x,y,z; - if (isDegree) { - t = t / degPerRadian; - p = p / degPerRadian; - } - x = r * Math.sin(p) * Math.cos(t); - y = r * Math.sin(p) * Math.sin(t); - z = r * Math.cos(p); - return [x, y, z]; -}; - - - -/** - * Convert spherical to cylindrical coordinates - * @param {Array} rtz - * @param {Boolean} isDegree - * @return {Array} - */ -Coordinate.sphericalToCylindrical = function (rtp, isDegree) { - var r = rtp[0], t = rtp[1], p = rtp[2], - cr, z; - if (isDegree) { - t = t / degPerRadian; - p = p / degPerRadian; - } - cr = r * Math.sin(p); - z = r * Math.cos(p); - if (isDegree) { - t = t * degPerRadian; - p = p * degPerRadian; - } - return [cr, t, z]; -}; - -module.exports = Coordinate; diff --git a/doc/Coordinate.html b/doc/Coordinate.html deleted file mode 100644 index 5eca659..0000000 --- a/doc/Coordinate.html +++ /dev/null @@ -1,3069 +0,0 @@ - - - - - - DocStrap Class: Coordinate - - - - - - - - - -
- - -
- - -
- -
- - - -

Class: Coordinate

-
- -
-

- Coordinate -

- -
- -
-
- - - - -
-

new Coordinate(config)

- - -
-
- - -
-

Defines object which can convert between coordinate systems. -It is recommended to use one of the Coodinate.STATIC_CONSTRUCTOR functions -to generate your first coordinate before conversions. e.g. Coodinate.spherical(...)

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
config - - -Object - - - -

{ - label: 'type of initial coordinate', - coords: { - x/y/z/r/t/p: 'k-v pairs' - }, - isDegree: Boolean -}

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - - - -
- - -
- - - - - - - - - - - - - - -

Methods

- -
- -
-

<static> arrToNumeric(nums) → {undefined}

- - -
-
- - -
-

Mutates an array of number-like looking values to purely numeric array

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
nums - - -Array - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -undefined - - -
-
- - - - - -
Example
- -
[5, '2.4', '0'] => [5, 2.4, 0]
- - - -
- - - -
-

<static> cart(coordinates) → {Coordinate}

- - -
-
- - -
-

Create a point provided x, y, and optionally z coordinates

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
coordinates - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Coordinate - - -
-
- - - - - -
- - - -
-

<static> cartesian(coordinates) → {Coordinate}

- - -
-
- - -
-

Create a point provided x, y, and optionally z coordinates

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
coordinates - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Coordinate - - -
-
- - - - - -
- - - -
-

<static> cartesian2dToPolar(xy, isDegree, center) → {Array}

- - -
-
- - -
-

Convert cartesian 2d to polar coordinates

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
xy - - -Array - - - - - - - - - -
isDegree - - -Boolean - - - - - - <optional>
- - - - - -

overrides default radian theta assumption

center - - -Array - - - - - - <optional>
- - - - - -

[x, y] coords of center of circle. Defaults to [0, 0], -however may be offset. Note. Such functionality not supported yet for converting -polar to cartesian

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

[radius, theta]

-
- - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- - - -
-

<static> cartesian3dToCylindrical(argument, isDegree, center) → {Array}

- - -
-
- - -
-

Convert 3d cartesian to 3d cylindrical coordinates

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
argument - - -Array - - - - - - - - - -

[x, y, z] coords

isDegree - - -Boolean - - - - - - <optional>
- - - - - -

overrides default radian theta assumption

center - - -Array - - - - - - <optional>
- - - - - -

[x, y] coords of center of circle

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

[radius, theta, z]

-
- - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- - - -
-

<static> cartesian3dToSpherical(argument, isDegree, center) → {Array}

- - -
-
- - -
-

Convert 3d cartesian to 3d spherical coordinates

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeArgumentDescription
argument - - -Array - - - - - - - - - -

[x, y, z] coords

isDegree - - -Boolean - - - - - - <optional>
- - - - - -

overrides default radian theta assumption

center - - -Array - - - - - - <optional>
- - - - - -

[x, y, z] coords of center of circle

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

[radius, theta, phi]

-
- - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- - - -
-

<static> cyl(coordinates) → {Coordinate}

- - -
-
- - -
-

Create point provided [radius, theta, z]

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
coordinates - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Coordinate - - -
-
- - - - - -
- - - -
-

<static> cylindrical(coordinates) → {Coordinate}

- - -
-
- - -
-

Create point provided [radius, theta, z]

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
coordinates - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Coordinate - - -
-
- - - - - -
- - - -
-

<static> cylindricalToSpherical(rtz, isDegree) → {Array}

- - -
-
- - -
-

Convert a cylindrical to a spherical coordinates

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
rtz - - -Array - - - -
isDegree - - -Boolean - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

[radius, theta, phi]

-
- - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- - - -
-

<static> pol(coordinates) → {Coordinate}

- - -
-
- - -
-

Create point provided [radius, theta]

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
coordinates - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Coordinate - - -
-
- - - - - -
- - - -
-

<static> polar(coordinates) → {Coordinate}

- - -
-
- - -
-

Create point provided [radius, theta]

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
coordinates - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Coordinate - - -
-
- - - - - -
- - - -
-

<static> polarToCart2d(rt, isDegree) → {Array}

- - -
-
- - -
-

Convert polar to 2d cartesian coordinates

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
rt - - -Array - - - -

[radis, theta]

isDegree - - -Boolean - - - -

specifies units

- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

[x, y]

-
- - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- - - -
-

<static> sph(coordinates) → {Coordinate}

- - -
-
- - -
-

Create point provided [radius, theta, phi]

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
coordinates - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Coordinate - - -
-
- - - - - -
- - - -
-

<static> spherical(coordinates) → {Coordinate}

- - -
-
- - -
-

Create point provided [radius, theta, phi]

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
coordinates - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Coordinate - - -
-
- - - - - -
- - - -
-

<static> sphericalToCart3d(rtz, isDegree) → {Array}

- - -
-
- - -
-

Convert spherical to a cartesian coordinates

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
rtz - - -Array - - - -
isDegree - - -Boolean - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- - - -
-

<static> sphericalToCylindrical(rtz, isDegree) → {Array}

- - -
-
- - -
-

Convert spherical to cylindrical coordinates

-
- - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
rtz - - -Array - - - -
isDegree - - -Boolean - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- -
- - - - - -
- -
- - - - -
- -
- -
- - -
-
-
- -
-
- -
- - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/doc/classes.list.html b/doc/classes.list.html deleted file mode 100644 index 3220396..0000000 --- a/doc/classes.list.html +++ /dev/null @@ -1,323 +0,0 @@ - - - - - - DocStrap Classes - - - - - - - - - -
- - -
- - -
- -
- - - -

Classes

-
- -
-

- -

- -
- -
-
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
- - - - - - - - -

Classes

- -
-
Coordinate
-
-
- - - - - - - - - - - -
- -
- - - - -
- -
- -
- - -
-
-
- -
-
- -
- - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/doc/coordinate-systems.js.html b/doc/coordinate-systems.js.html deleted file mode 100644 index 5ea1481..0000000 --- a/doc/coordinate-systems.js.html +++ /dev/null @@ -1,810 +0,0 @@ - - - - - - DocStrap Source: coordinate-systems.js - - - - - - - - - -
- - -
- - -
- -
- - - -

Source: coordinate-systems.js

- -
-
-
"use strict";
-var isArray = require('amp-is-array');
-var isNumber = require('amp-is-number');
-var isObject = require('amp-is-object');
-var extend = require('amp-extend');
-var degPerRadian = 180 / Math.PI;
-
-/**
- * @constructor Coordinate
- * @description Defines object which can convert between coordinate systems.
- * It is recommended to use one of the Coodinate.STATIC_CONSTRUCTOR functions
- * to generate your first coordinate before conversions. e.g. Coodinate.spherical(...)
- * @param {Object} config
- * {
- *     label: 'type of initial coordinate',
- *     coords: {
- *         x/y/z/r/t/p: 'k-v pairs'
- *     },
- *     isDegree: Boolean
- * }
- */
-var Coordinate = function (config) {
-    var isRadian,
-        isDegree,
-        pos = {},
-        _x, _y, _z, _r, _t, _p;
-
-    // Override select setters/getts
-    Object.defineProperty(this, "isRadian", {
-        get: function (x) { return isRadian; },
-        set: function (x) {
-            isRadian = !!x;
-            if (isDegree !== !x) { isDegree = !x; } // jshint ignore:line
-        }
-    });
-    Object.defineProperty(this, "isDegree", {
-        get: function (x) { return isDegree; },
-        set: function (x) {
-            isDegree = x;
-            if (isRadian !== !x) { isRadian = !x; } // jshint ignore:line
-        }
-    });
-    Object.defineProperty(pos, "cartesian2d", {
-        get: function (x) { return [_x, _y]; },
-        set: function (x) { _x = x[0]; _y = x[1]; }
-    });
-    Object.defineProperty(pos, "cartesian3d", {
-        get: function (x) { return [_x, _y, _z]; },
-        set: function (x) { _x = x[0]; _y = x[1]; _z = x[2]; }
-    });
-    Object.defineProperty(pos, "polar", {
-        get: function (x) { return [_r, _t]; },
-        set: function (x) { _r = x[0]; _t = x[1]; }
-    });
-    Object.defineProperty(pos, "cylindrical", {
-        get: function (x) { return [_r, _t, _z]; },
-        set: function (x) { _r = x[0]; _t = x[1]; _z = x[2]; }
-    });
-    Object.defineProperty(pos, "spherical", {
-        get: function (x) { return [_r, _t, _p]; },
-        set: function (x) { _r = x[0]; _t = x[1]; _p = x[2]; }
-    });
-
-    // init from config
-    if (config.isDegree && !config.isRadian) {
-        this.isDegree = true;
-    } else {
-        this.isRadian = true;
-    }
-    if (!config.label || !config.coords) {
-        throw new Error("no coordinate type defined");
-    }
-    this.initialType = config.label;
-    this.pos = pos;
-    this.pos[config.label] = config.coords;
-};
-
-
-
-/**
- * @method cartesian
- * Converts current coordinate to cartesian
- * @param  {Object} options
- * @return {Array}  coordinates in respective coordinate format
- */
-Coordinate.prototype.cartesian = function () { return this.cart.apply(this, arguments); };
-/**
- * @method cart
- * Converts current coordinate to cartesian
- * @param  {Object} options
- * @return {Array}  coordinates in respective coordinate format
- */
-Coordinate.prototype.cart = function (options) {
-    var temp;
-    options = options || {};
-    switch (this.initialType) {
-        case 'cartesian2d':
-            return this.pos.cartesian2d;
-        case 'cartesian3d':
-            return this.pos.cartesian3d;
-        case 'polar':
-            this.pos.cartesian2d = Coordinate.polarToCart2d(this.pos.polar, this.isDegree);
-            return this.pos.cartesian2d;
-        case 'cylindrical':
-            temp = Coordinate.polarToCart2d(this.pos.polar, this.isDegree);
-            this.pos.cartesian3d = [temp[0], temp[1], this.pos.cylindrical[2]];
-            return this.pos.cartesian3d;
-        case 'spherical':
-            this.pos.cartesian3d = Coordinate.sphericalToCart3d(this.pos.spherical, this.isDegree);
-            return this.pos.cartesian3d;
-        default:
-            throw new Error('cannot convert to/from original/requested types');
-    }
-};
-
-
-
-/**
- * @method cylindrical
- * Converts current coordinate to cylindrical
- * @param  {Object} options
- * @return {Array}  coordinates in respective coordinate format
- */
-Coordinate.prototype.cylindrical = function () { return this.cyl.apply(this, arguments); };
-/**
- * @method cyl
- * Converts current coordinate to cylindrical
- * @param  {Object} options
- * @return {Array}  coordinates in respective coordinate format
- */
-Coordinate.prototype.cyl = function (options) {
-    var temp;
-    options = options || {};
-    switch (this.initialType) {
-        case 'cartesian2d':
-            temp = Coordinate.cartesian2dToPolar(this.pos.cartesian2d, this.isDegree, options.center);
-            this.pos.cylindrical = [temp[0], temp[1], 0];
-            return this.pos.cylindrical;
-        case 'cartesian3d':
-            this.pos.cylindrical = Coordinate.cartesian3dToCylindrical(this.pos.cartesian3d, this.isDegree, options.center);
-            return this.pos.cylindrical;
-        case 'polar':
-            temp = this.pos.polar;
-            return [temp[0], temp[1], 0];
-        case 'cylindrical':
-            return this.pos.cylindrical;
-        case 'spherical':
-            this.pos.cylindrical = Coordinate.sphericalToCylindrical(this.pos.spherical, this.isDegree);
-            return this.pos.cylindrical;
-        default:
-            throw new Error('cannot convert to/from original/requested types');
-    }
-};
-
-/**
- * @method pol
- * Converts current coordinate to polar
- * @param  {Object} options
- * @return {Array}  coordinates in respective coordinate format
- */
-Coordinate.prototype.pol = function () { return this.polar.apply(this, arguments); };
-/**
- * @method polar
- * Converts current coordinate to polar
- * @param  {Object} options
- * @return {Array}  coordinates in respective coordinate format
- */
-Coordinate.prototype.polar = function (options) {
-    options = options || {};
-    switch (this.initialType) {
-        case 'cartesian2d':
-            this.pos.polar = Coordinate.cartesian2dToPolar(this.pos.cartesian2d, this.isDegree, options.center);
-            return this.pos.polar;
-        case 'polar':
-            return this.pos.polar;
-        default:
-            throw new Error('cannot convert to/from original/requested types');
-    }
-};
-
-
-
-/**
- * @method spherical
- * Converts current coordinate to spherical
- * @param  {Object} options
- * @return {Array}  coordinates in respective coordinate format
- */
-Coordinate.prototype.spherical = function () { return this.sph.apply(this, arguments); };
-/**
- * @method spherical
- * Converts current coordinate to spherical
- * @param  {Object} options
- * @return {Array}  coordinates in respective coordinate format
- */
-Coordinate.prototype.sph = function (options) {
-    var temp;
-    options = options || {};
-    switch (this.initialType) {
-        case 'cartesian2d':
-            temp = Coordinate.cartesian2dToPolar(this.pos.cartesian2d, this.isDegree, options.center);
-            this.pos.spherical = [temp[0], temp[1], 0];
-            return this.pos.spherical;
-        case 'cartesian3d':
-            this.pos.spherical = Coordinate.cartesian3dToSpherical(this.pos.cartesian3d, this.isDegree, options.center);
-            return this.pos.spherical;
-        case 'polar':
-            temp = this.pos.polar;
-            return [temp[0], temp[1], 0];
-        case 'cylindrical':
-            this.pos.spherical = Coordinate.cylindricalToSpherical(this.pos.cylindrical, this.isDegree);
-            return this.pos.spherical;
-        case 'spherical':
-            return this.pos.spherical;
-        default:
-            throw new Error('cannot convert to/from original/requested types');
-    }
-};
-
-
-///
-/// Static Constructor Functions
-///
-
-/**
- * Create a point provided x, y, and optionally z coordinates
- * @param  {Object} coordinates
- * @return {Coordinate}
- */
-Coordinate.cartesian = function(x) { return Coordinate.cart(x); };
-/**
- * Create a point provided x, y, and optionally z coordinates
- * @param  {Object} coordinates
- * @return {Coordinate}
- */
-Coordinate.cart = function(options) {
-    var baseCoord;
-    if (isArray(options)) {
-        options = {coords: options};
-    }
-    if (isObject(options) && isArray(options.coords)) {
-        Coordinate.arrToNumeric(options.coords);
-        if (options.coords.length < 2 || options.coords.length > 3) {
-            throw new Error('expected exactly 2 or exactly 3 cartesian options');
-        }
-        baseCoord = {
-            label: 'cartesian2d',
-            options: options.coords
-        };
-        baseCoord = extend(baseCoord, options);
-        if (options.coords.length === 2) {
-            return new Coordinate(baseCoord);
-        }
-        baseCoord.label = 'cartesian3d';
-        return new Coordinate(baseCoord);
-    }
-    throw new Error('expected options w/ array of [x,y,(z?)] coords');
-};
-
-
-
-/**
- * Create point provided [radius, theta, z]
- * @param  {Object} coordinates
- * @return {Coordinate}
- */
-Coordinate.cylindrical = function(x) { return Coordinate.cyl(x); };
-/**
- * Create point provided [radius, theta, z]
- * @param  {Object} coordinates
- * @return {Coordinate}
- */
-Coordinate.cyl = function(options) {
-    var baseCoord;
-    if (isArray(options)) {
-        options = {coords: options};
-    }
-    if (isObject(options) && isArray(options.coords)) {
-        Coordinate.arrToNumeric(options.coords);
-        if (options.coords.length !== 3) {
-            throw new Error('expected exactly 3 params [r, t, z]');
-        }
-        baseCoord = {
-            label: 'cylindrical',
-            coords: options.coords
-        };
-        baseCoord = extend(baseCoord, options);
-        return new Coordinate(baseCoord);
-    }
-    throw new Error('expected options w/ array of [r, t, z] coords');
-};
-
-
-
-/**
- * Create point provided [radius, theta]
- * @param  {Object} coordinates
- * @return {Coordinate}
- */
-Coordinate.polar = function(x) { return Coordinate.pol(x); };
-/**
- * Create point provided [radius, theta]
- * @param  {Object} coordinates
- * @return {Coordinate}
- */
-Coordinate.pol = function(options) {
-    var baseCoord;
-    if (isArray(options)) {
-        options = {coords: options};
-    }
-    if (isObject(options) && isArray(options.coords)) {
-        Coordinate.arrToNumeric(options.coords);
-        if (options.coords.length !== 2) {
-            throw new Error('expected exactly 2 params [r, t]');
-        }
-        baseCoord = {
-            label: 'polar',
-            coords: options.coords
-        };
-        baseCoord = extend(baseCoord, options);
-        return new Coordinate(baseCoord);
-    }
-    throw new Error('expected array of [r, t] options');
-};
-
-
-
-/**
- * Create point provided [radius, theta, phi]
- * @param  {Object} coordinates
- * @return {Coordinate}
- */
-Coordinate.spherical = function(options) { return Coordinate.sph(options); };
-/**
- * Create point provided [radius, theta, phi]
- * @param  {Object} coordinates
- * @return {Coordinate}
- */
-Coordinate.sph = function(options) {
-    var baseCoord;
-    if (isArray(options)) {
-        options = {coords: options};
-    }
-    if (isObject(options) && isArray(options.coords)) {
-        Coordinate.arrToNumeric(options.coords);
-        if (options.coords.length !== 3) {
-            throw new Error('expected exactly 3 params [r, t, p]');
-        }
-        baseCoord = {
-            label: 'spherical',
-            coords: options.coords
-        };
-        baseCoord = extend(baseCoord, options);
-        return new Coordinate(baseCoord);
-    }
-    throw new Error('expected options w/ array of [r, t, p] coords');
-};
-
-
-
-/**
- * Mutates an array of number-like looking values to purely numeric array
- * @example
- * [5, '2.4', '0'] => [5, 2.4, 0]
- * @param  {Array} nums
- * @return {undefined}
- */
-Coordinate.arrToNumeric = function(nums) {
-    var num;
-    if (!isArray(nums)) {
-        throw new TypeError("expected array of number-like values");
-    }
-    for (var i = nums.length - 1; i >= 0; i--) {
-        num = nums[i];
-        if (typeof num === 'string') {
-            num = parseFloat(num);
-        }
-        if (!isNumber(num)) {
-            throw new TypeError(num + ' not numeric or numeric-like');
-        }
-    }
-};
-
-
-
-/**
- * Convert polar to 2d cartesian coordinates
- * @param  {Array}   rt        [radis, theta]
- * @param  {Boolean} isDegree specifies units
- * @return {Array}  [x, y]
- */
-Coordinate.polarToCart2d = function(rt, isDegree) {
-    var r, t, x, y;
-    r = rt[0];
-    t = rt[1];
-    if (isDegree) {
-        t = t * (1/degPerRadian);
-    }
-    x = r * Math.cos(t);
-    y = r * Math.sin(t);
-    return [x, y];
-};
-
-
-
-/**
- * Convert cartesian 2d to polar coordinates
- * @param  {Array}  xy
- * @param {Boolean=} isDegree overrides default radian theta assumption
- * @param  {Array=} center [x, y] coords of center of circle.  Defaults to [0, 0],
- * however may be offset.  Note. Such functionality not supported yet for converting
- * polar to cartesian
- * @return {Array}  [radius, theta]
- */
-Coordinate.cartesian2dToPolar = function(xy, isDegree, center) {
-    var x, y, r, t;
-    if (!isArray(xy) && xy.length !== 2) {
-        throw new TypeError('expected [x, y] xy array');
-    }
-    x = xy[0];
-    y = xy[1];
-    if (center && !isArray(center) && center.length !== 2) {
-        throw new TypeError('expected [x, y] center array');
-    }
-    if (center) {
-        x = x - center[0];
-        y = y - center[1];
-    }
-    r = Math.sqrt(x*x + y*y);
-    t = Math.atan2(y, x);
-    if (isDegree) {
-        t = t * degPerRadian;
-    }
-    return [r, t];
-};
-
-
-
-/**
- * Convert 3d cartesian to 3d cylindrical coordinates
- * @param  {Array}      argument [x, y, z] coords
- * @param  {Boolean=}   isDegree overrides default radian theta assumption
- * @param  {Array=}     center [x, y] coords of center of circle
- * @return {Array}      [radius, theta, z]
- */
-Coordinate.cartesian3dToCylindrical = function (xyz, isDegree, center) {
-    var x = xyz[0],
-        y = xyz[1],
-        z = xyz[2],
-        rt;
-    rt = Coordinate.cartesian2dToPolar([x, y], isDegree, center);
-    return [rt[0], rt[1], z];
-};
-
-
-
-/**
- * Convert 3d cartesian to 3d spherical coordinates
- * @param  {Array}      argument [x, y, z] coords
- * @param  {Boolean=}   isDegree overrides default radian theta assumption
- * @param  {Array=}     center [x, y, z] coords of center of circle
- * @return {Array}      [radius, theta, phi]
- */
-Coordinate.cartesian3dToSpherical = function (xyz, isDegree, center) {
-    if (center && center.length !== 3) {
-        throw new Error('expected center value to have [x, y, z] coords' +
-            'for locating sphere center');
-    }
-    var x = xyz[0],
-        y = xyz[1],
-        z = xyz[2],
-        x2, y2, z2,
-        r, t, p;
-    if (center) {
-        x = x - center[0];
-        y = y - center[1];
-        z = z - center[2];
-    }
-    x2 = x*x; y2 = y*y; z2 = z*z;
-    r = Math.sqrt(x2 + y2 + z2);
-    if (!r) {
-        p = t = 0;
-    } else {
-        t = Math.atan2(y,x);
-        p = Math.atan2(Math.sqrt(x2 + y2), z);
-        if (isDegree) {
-            t = t * degPerRadian;
-            p = p * degPerRadian;
-        }
-    }
-    return [r, t, p];
-};
-
-
-
-/**
- * Convert a cylindrical to a spherical coordinates
- * @param  {Array}   rtz
- * @param  {Boolean} isDegree
- * @return {Array}   [radius, theta, phi]
- */
-Coordinate.cylindricalToSpherical = function(rtz, isDegree) {
-    var r = rtz[0], t = rtz[1], z = rtz[2];
-    var sr, sp; // sphere radius, sphere theta...
-    if (isDegree) {
-        t = t / degPerRadian;
-    }
-    sr = Math.sqrt(r*r + z*z);
-    sp = Math.atan2(r, z);
-    if (isDegree) {
-        sp = sp * degPerRadian;
-        t = t * degPerRadian;
-    }
-    return [sr, t, sp];
-};
-
-
-
-/**
- * Convert spherical to a cartesian coordinates
- * @param  {Array}  rtz
- * @param  {Boolean} isDegree
- * @return {Array}
- */
-Coordinate.sphericalToCart3d = function (rtp, isDegree) {
-    var r = rtp[0], t = rtp[1], p = rtp[2],
-        x,y,z;
-    if (isDegree) {
-        t = t / degPerRadian;
-        p = p / degPerRadian;
-    }
-    x = r * Math.sin(p) * Math.cos(t);
-    y = r * Math.sin(p) * Math.sin(t);
-    z = r * Math.cos(p);
-    return [x, y, z];
-};
-
-
-
-/**
- * Convert spherical to cylindrical coordinates
- * @param  {Array}  rtz
- * @param  {Boolean} isDegree
- * @return {Array}
- */
-Coordinate.sphericalToCylindrical = function (rtp, isDegree) {
-    var r = rtp[0], t = rtp[1], p = rtp[2],
-        cr, z;
-    if (isDegree) {
-        t = t / degPerRadian;
-        p = p / degPerRadian;
-    }
-    cr = r * Math.sin(p);
-    z = r * Math.cos(p);
-    if (isDegree) {
-        t = t * degPerRadian;
-        p = p * degPerRadian;
-    }
-    return [cr, t, z];
-};
-
-module.exports = Coordinate;
-
-
-
- - - - - -
- -
- -
- - -
-
- -
- - - - - - - - - - - - - - - - - - - - diff --git a/doc/global.html b/doc/global.html deleted file mode 100644 index e6b6530..0000000 --- a/doc/global.html +++ /dev/null @@ -1,1488 +0,0 @@ - - - - - - DocStrap Global - - - - - - - - - -
- - -
- - -
- -
- - - -

Global

-
- -
-

- -

- -
- -
-
- - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - - -
- - - - - - - - - - - - - - -

Methods

- -
- -
-

cart -Converts current coordinate to cartesian(options) → {Array}

- - -
-
- - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
options - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

coordinates in respective coordinate format

-
- - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- - - -
-

cartesian -Converts current coordinate to cartesian(options) → {Array}

- - -
-
- - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
options - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

coordinates in respective coordinate format

-
- - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- - - -
-

cyl -Converts current coordinate to cylindrical(options) → {Array}

- - -
-
- - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
options - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

coordinates in respective coordinate format

-
- - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- - - -
-

cylindrical -Converts current coordinate to cylindrical(options) → {Array}

- - -
-
- - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
options - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

coordinates in respective coordinate format

-
- - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- - - -
-

pol -Converts current coordinate to polar(options) → {Array}

- - -
-
- - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
options - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

coordinates in respective coordinate format

-
- - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- - - -
-

polar -Converts current coordinate to polar(options) → {Array}

- - -
-
- - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
options - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

coordinates in respective coordinate format

-
- - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- - - -
-

spherical -Converts current coordinate to spherical(options) → {Array}

- - -
-
- - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
options - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

coordinates in respective coordinate format

-
- - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- - - -
-

spherical -Converts current coordinate to spherical(options) → {Array}

- - -
-
- - - - - - - - -
Parameters:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NameTypeDescription
options - - -Object - - - -
- - - - -
- - - - - - - - - - - - - - - - - - - - - -
Source:
-
- -
- - - - - - - -
- - - - - - - - - - - -
Returns:
- - -
-

coordinates in respective coordinate format

-
- - - -
-
- Type -
-
- -Array - - -
-
- - - - - -
- -
- - - - - -
- -
- - - - -
- -
- -
- - -
-
-
- -
-
- -
- - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/doc/img/glyphicons-halflings-white.png b/doc/img/glyphicons-halflings-white.png deleted file mode 100644 index 3bf6484..0000000 Binary files a/doc/img/glyphicons-halflings-white.png and /dev/null differ diff --git a/doc/img/glyphicons-halflings.png b/doc/img/glyphicons-halflings.png deleted file mode 100644 index a996999..0000000 Binary files a/doc/img/glyphicons-halflings.png and /dev/null differ diff --git a/doc/index.html b/doc/index.html deleted file mode 100644 index 21592ec..0000000 --- a/doc/index.html +++ /dev/null @@ -1,268 +0,0 @@ - - - - - - DocStrap Index - - - - - - - - - -
- - -
- - -
- -
- - - - - Index - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- -
- - -
-
-
- -
-
- -
- - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/doc/scripts/URI.js b/doc/scripts/URI.js deleted file mode 100644 index f8546c7..0000000 --- a/doc/scripts/URI.js +++ /dev/null @@ -1,1429 +0,0 @@ -/*! - * URI.js - Mutating URLs - * - * Version: 1.8.3 - * - * Author: Rodney Rehm - * Web: http://medialize.github.com/URI.js/ - * - * Licensed under - * MIT License http://www.opensource.org/licenses/mit-license - * GPL v3 http://opensource.org/licenses/GPL-3.0 - * - */ -(function(root, factory) { - // https://github.com/umdjs/umd/blob/master/returnExports.js - if (typeof exports === 'object') { - // Node - module.exports = factory(require('./punycode'), require('./IPv6'), require('./SecondLevelDomains')); - } else if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(['./punycode', './IPv6', './SecondLevelDomains'], factory); - } else { - // Browser globals (root is window) - root.URI = factory(root.punycode, root.IPv6, root.SecondLevelDomains); - } -}(this, function(punycode, IPv6, SLD) { - "use strict"; - - function URI(url, base) { - // Allow instantiation without the 'new' keyword - if (!(this instanceof URI)) { - return new URI(url, base); - } - if (url === undefined) { - if (typeof location !== 'undefined') { - url = location.href + ""; - } else { - url = ""; - } - } - this.href(url); - // resolve to base according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#constructor - if (base !== undefined) { - return this.absoluteTo(base); - } - return this; - }; - var p = URI.prototype; - var hasOwn = Object.prototype.hasOwnProperty; - - function escapeRegEx(string) { - // https://github.com/medialize/URI.js/commit/85ac21783c11f8ccab06106dba9735a31a86924d#commitcomment-821963 - return string.replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); - } - - function isArray(obj) { - return String(Object.prototype.toString.call(obj)) === "[object Array]"; - } - - function filterArrayValues(data, value) { - var lookup = {}; - var i, length; - if (isArray(value)) { - for (i = 0, length = value.length; i < length; i++) { - lookup[value[i]] = true; - } - } else { - lookup[value] = true; - } - for (i = 0, length = data.length; i < length; i++) { - if (lookup[data[i]] !== undefined) { - data.splice(i, 1); - length--; - i--; - } - } - return data; - } - URI._parts = function() { - return { - protocol: null, - username: null, - password: null, - hostname: null, - urn: null, - port: null, - path: null, - query: null, - fragment: null, - // state - duplicateQueryParameters: URI.duplicateQueryParameters - }; - }; - // state: allow duplicate query parameters (a=1&a=1) - URI.duplicateQueryParameters = false; - // static properties - URI.protocol_expression = /^[a-z][a-z0-9-+-]*$/i; - URI.idn_expression = /[^a-z0-9\.-]/i; - URI.punycode_expression = /(xn--)/i; - // well, 333.444.555.666 matches, but it sure ain't no IPv4 - do we care? - URI.ip4_expression = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/; - // credits to Rich Brown - // source: http://forums.intermapper.com/viewtopic.php?p=1096#1096 - // specification: http://www.ietf.org/rfc/rfc4291.txt - URI.ip6_expression = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/; - // gruber revised expression - http://rodneyrehm.de/t/url-regex.html - URI.find_uri_expression = /\b((?:[a-z][\w-]+:(?:\/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/ig; - // http://www.iana.org/assignments/uri-schemes.html - // http://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Well-known_ports - URI.defaultPorts = { - http: "80", - https: "443", - ftp: "21", - gopher: "70", - ws: "80", - wss: "443" - }; - // allowed hostname characters according to RFC 3986 - // ALPHA DIGIT "-" "." "_" "~" "!" "$" "&" "'" "(" ")" "*" "+" "," ";" "=" %encoded - // I've never seen a (non-IDN) hostname other than: ALPHA DIGIT . - - URI.invalid_hostname_characters = /[^a-zA-Z0-9\.-]/; - // encoding / decoding according to RFC3986 - - function strictEncodeURIComponent(string) { - // see https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/encodeURIComponent - return encodeURIComponent(string).replace(/[!'()*]/g, escape).replace(/\*/g, "%2A"); - } - URI.encode = strictEncodeURIComponent; - URI.decode = decodeURIComponent; - URI.iso8859 = function() { - URI.encode = escape; - URI.decode = unescape; - }; - URI.unicode = function() { - URI.encode = strictEncodeURIComponent; - URI.decode = decodeURIComponent; - }; - URI.characters = { - pathname: { - encode: { - // RFC3986 2.1: For consistency, URI producers and normalizers should - // use uppercase hexadecimal digits for all percent-encodings. - expression: /%(24|26|2B|2C|3B|3D|3A|40)/ig, - map: { - // -._~!'()* - "%24": "$", - "%26": "&", - "%2B": "+", - "%2C": ",", - "%3B": ";", - "%3D": "=", - "%3A": ":", - "%40": "@" - } - }, - decode: { - expression: /[\/\?#]/g, - map: { - "/": "%2F", - "?": "%3F", - "#": "%23" - } - } - }, - reserved: { - encode: { - // RFC3986 2.1: For consistency, URI producers and normalizers should - // use uppercase hexadecimal digits for all percent-encodings. - expression: /%(21|23|24|26|27|28|29|2A|2B|2C|2F|3A|3B|3D|3F|40|5B|5D)/ig, - map: { - // gen-delims - "%3A": ":", - "%2F": "/", - "%3F": "?", - "%23": "#", - "%5B": "[", - "%5D": "]", - "%40": "@", - // sub-delims - "%21": "!", - "%24": "$", - "%26": "&", - "%27": "'", - "%28": "(", - "%29": ")", - "%2A": "*", - "%2B": "+", - "%2C": ",", - "%3B": ";", - "%3D": "=" - } - } - } - }; - URI.encodeQuery = function(string) { - return URI.encode(string + "").replace(/%20/g, '+'); - }; - URI.decodeQuery = function(string) { - return URI.decode((string + "").replace(/\+/g, '%20')); - }; - URI.recodePath = function(string) { - var segments = (string + "").split('/'); - for (var i = 0, length = segments.length; i < length; i++) { - segments[i] = URI.encodePathSegment(URI.decode(segments[i])); - } - return segments.join('/'); - }; - URI.decodePath = function(string) { - var segments = (string + "").split('/'); - for (var i = 0, length = segments.length; i < length; i++) { - segments[i] = URI.decodePathSegment(segments[i]); - } - return segments.join('/'); - }; - // generate encode/decode path functions - var _parts = { - 'encode': 'encode', - 'decode': 'decode' - }; - var _part; - var generateAccessor = function(_group, _part) { - return function(string) { - return URI[_part](string + "").replace(URI.characters[_group][_part].expression, function(c) { - return URI.characters[_group][_part].map[c]; - }); - }; - }; - for (_part in _parts) { - URI[_part + "PathSegment"] = generateAccessor("pathname", _parts[_part]); - } - URI.encodeReserved = generateAccessor("reserved", "encode"); - URI.parse = function(string, parts) { - var pos, t; - if (!parts) { - parts = {}; - } - // [protocol"://"[username[":"password]"@"]hostname[":"port]"/"?][path]["?"querystring]["#"fragment] - // extract fragment - pos = string.indexOf('#'); - if (pos > -1) { - // escaping? - parts.fragment = string.substring(pos + 1) || null; - string = string.substring(0, pos); - } - // extract query - pos = string.indexOf('?'); - if (pos > -1) { - // escaping? - parts.query = string.substring(pos + 1) || null; - string = string.substring(0, pos); - } - // extract protocol - if (string.substring(0, 2) === '//') { - // relative-scheme - parts.protocol = ''; - string = string.substring(2); - // extract "user:pass@host:port" - string = URI.parseAuthority(string, parts); - } else { - pos = string.indexOf(':'); - if (pos > -1) { - parts.protocol = string.substring(0, pos); - if (parts.protocol && !parts.protocol.match(URI.protocol_expression)) { - // : may be within the path - parts.protocol = undefined; - } else if (parts.protocol === 'file') { - // the file scheme: does not contain an authority - string = string.substring(pos + 3); - } else if (string.substring(pos + 1, pos + 3) === '//') { - string = string.substring(pos + 3); - // extract "user:pass@host:port" - string = URI.parseAuthority(string, parts); - } else { - string = string.substring(pos + 1); - parts.urn = true; - } - } - } - // what's left must be the path - parts.path = string; - // and we're done - return parts; - }; - URI.parseHost = function(string, parts) { - // extract host:port - var pos = string.indexOf('/'); - var bracketPos; - var t; - if (pos === -1) { - pos = string.length; - } - if (string[0] === "[") { - // IPv6 host - http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-04#section-6 - // I claim most client software breaks on IPv6 anyways. To simplify things, URI only accepts - // IPv6+port in the format [2001:db8::1]:80 (for the time being) - bracketPos = string.indexOf(']'); - parts.hostname = string.substring(1, bracketPos) || null; - parts.port = string.substring(bracketPos + 2, pos) || null; - } else if (string.indexOf(':') !== string.lastIndexOf(':')) { - // IPv6 host contains multiple colons - but no port - // this notation is actually not allowed by RFC 3986, but we're a liberal parser - parts.hostname = string.substring(0, pos) || null; - parts.port = null; - } else { - t = string.substring(0, pos).split(':'); - parts.hostname = t[0] || null; - parts.port = t[1] || null; - } - if (parts.hostname && string.substring(pos)[0] !== '/') { - pos++; - string = "/" + string; - } - return string.substring(pos) || '/'; - }; - URI.parseAuthority = function(string, parts) { - string = URI.parseUserinfo(string, parts); - return URI.parseHost(string, parts); - }; - URI.parseUserinfo = function(string, parts) { - // extract username:password - var pos = string.indexOf('@'); - var firstSlash = string.indexOf('/'); - var t; - // authority@ must come before /path - if (pos > -1 && (firstSlash === -1 || pos < firstSlash)) { - t = string.substring(0, pos).split(':'); - parts.username = t[0] ? URI.decode(t[0]) : null; - t.shift(); - parts.password = t[0] ? URI.decode(t.join(':')) : null; - string = string.substring(pos + 1); - } else { - parts.username = null; - parts.password = null; - } - return string; - }; - URI.parseQuery = function(string) { - if (!string) { - return {}; - } - // throw out the funky business - "?"[name"="value"&"]+ - string = string.replace(/&+/g, '&').replace(/^\?*&*|&+$/g, ''); - if (!string) { - return {}; - } - var items = {}; - var splits = string.split('&'); - var length = splits.length; - var v, name, value; - for (var i = 0; i < length; i++) { - v = splits[i].split('='); - name = URI.decodeQuery(v.shift()); - // no "=" is null according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#collect-url-parameters - value = v.length ? URI.decodeQuery(v.join('=')) : null; - if (items[name]) { - if (typeof items[name] === "string") { - items[name] = [items[name]]; - } - items[name].push(value); - } else { - items[name] = value; - } - } - return items; - }; - URI.build = function(parts) { - var t = ""; - if (parts.protocol) { - t += parts.protocol + ":"; - } - if (!parts.urn && (t || parts.hostname)) { - t += '//'; - } - t += (URI.buildAuthority(parts) || ''); - if (typeof parts.path === "string") { - if (parts.path[0] !== '/' && typeof parts.hostname === "string") { - t += '/'; - } - t += parts.path; - } - if (typeof parts.query === "string" && parts.query) { - t += '?' + parts.query; - } - if (typeof parts.fragment === "string" && parts.fragment) { - t += '#' + parts.fragment; - } - return t; - }; - URI.buildHost = function(parts) { - var t = ""; - if (!parts.hostname) { - return ""; - } else if (URI.ip6_expression.test(parts.hostname)) { - if (parts.port) { - t += "[" + parts.hostname + "]:" + parts.port; - } else { - // don't know if we should always wrap IPv6 in [] - // the RFC explicitly says SHOULD, not MUST. - t += parts.hostname; - } - } else { - t += parts.hostname; - if (parts.port) { - t += ':' + parts.port; - } - } - return t; - }; - URI.buildAuthority = function(parts) { - return URI.buildUserinfo(parts) + URI.buildHost(parts); - }; - URI.buildUserinfo = function(parts) { - var t = ""; - if (parts.username) { - t += URI.encode(parts.username); - if (parts.password) { - t += ':' + URI.encode(parts.password); - } - t += "@"; - } - return t; - }; - URI.buildQuery = function(data, duplicates) { - // according to http://tools.ietf.org/html/rfc3986 or http://labs.apache.org/webarch/uri/rfc/rfc3986.html - // being »-._~!$&'()*+,;=:@/?« %HEX and alnum are allowed - // the RFC explicitly states ?/foo being a valid use case, no mention of parameter syntax! - // URI.js treats the query string as being application/x-www-form-urlencoded - // see http://www.w3.org/TR/REC-html40/interact/forms.html#form-content-type - var t = ""; - var unique, key, i, length; - for (key in data) { - if (hasOwn.call(data, key) && key) { - if (isArray(data[key])) { - unique = {}; - for (i = 0, length = data[key].length; i < length; i++) { - if (data[key][i] !== undefined && unique[data[key][i] + ""] === undefined) { - t += "&" + URI.buildQueryParameter(key, data[key][i]); - if (duplicates !== true) { - unique[data[key][i] + ""] = true; - } - } - } - } else if (data[key] !== undefined) { - t += '&' + URI.buildQueryParameter(key, data[key]); - } - } - } - return t.substring(1); - }; - URI.buildQueryParameter = function(name, value) { - // http://www.w3.org/TR/REC-html40/interact/forms.html#form-content-type -- application/x-www-form-urlencoded - // don't append "=" for null values, according to http://dvcs.w3.org/hg/url/raw-file/tip/Overview.html#url-parameter-serialization - return URI.encodeQuery(name) + (value !== null ? "=" + URI.encodeQuery(value) : ""); - }; - URI.addQuery = function(data, name, value) { - if (typeof name === "object") { - for (var key in name) { - if (hasOwn.call(name, key)) { - URI.addQuery(data, key, name[key]); - } - } - } else if (typeof name === "string") { - if (data[name] === undefined) { - data[name] = value; - return; - } else if (typeof data[name] === "string") { - data[name] = [data[name]]; - } - if (!isArray(value)) { - value = [value]; - } - data[name] = data[name].concat(value); - } else { - throw new TypeError("URI.addQuery() accepts an object, string as the name parameter"); - } - }; - URI.removeQuery = function(data, name, value) { - var i, length, key; - if (isArray(name)) { - for (i = 0, length = name.length; i < length; i++) { - data[name[i]] = undefined; - } - } else if (typeof name === "object") { - for (key in name) { - if (hasOwn.call(name, key)) { - URI.removeQuery(data, key, name[key]); - } - } - } else if (typeof name === "string") { - if (value !== undefined) { - if (data[name] === value) { - data[name] = undefined; - } else if (isArray(data[name])) { - data[name] = filterArrayValues(data[name], value); - } - } else { - data[name] = undefined; - } - } else { - throw new TypeError("URI.addQuery() accepts an object, string as the first parameter"); - } - }; - URI.commonPath = function(one, two) { - var length = Math.min(one.length, two.length); - var pos; - // find first non-matching character - for (pos = 0; pos < length; pos++) { - if (one[pos] !== two[pos]) { - pos--; - break; - } - } - if (pos < 1) { - return one[0] === two[0] && one[0] === '/' ? '/' : ''; - } - // revert to last / - if (one[pos] !== '/') { - pos = one.substring(0, pos).lastIndexOf('/'); - } - return one.substring(0, pos + 1); - }; - URI.withinString = function(string, callback) { - // expression used is "gruber revised" (@gruber v2) determined to be the best solution in - // a regex sprint we did a couple of ages ago at - // * http://mathiasbynens.be/demo/url-regex - // * http://rodneyrehm.de/t/url-regex.html - return string.replace(URI.find_uri_expression, callback); - }; - URI.ensureValidHostname = function(v) { - // Theoretically URIs allow percent-encoding in Hostnames (according to RFC 3986) - // they are not part of DNS and therefore ignored by URI.js - if (v.match(URI.invalid_hostname_characters)) { - // test punycode - if (!punycode) { - throw new TypeError("Hostname '" + v + "' contains characters other than [A-Z0-9.-] and Punycode.js is not available"); - } - if (punycode.toASCII(v).match(URI.invalid_hostname_characters)) { - throw new TypeError("Hostname '" + v + "' contains characters other than [A-Z0-9.-]"); - } - } - }; - p.build = function(deferBuild) { - if (deferBuild === true) { - this._deferred_build = true; - } else if (deferBuild === undefined || this._deferred_build) { - this._string = URI.build(this._parts); - this._deferred_build = false; - } - return this; - }; - p.clone = function() { - return new URI(this); - }; - p.valueOf = p.toString = function() { - return this.build(false)._string; - }; - // generate simple accessors - _parts = { - protocol: 'protocol', - username: 'username', - password: 'password', - hostname: 'hostname', - port: 'port' - }; - generateAccessor = function(_part) { - return function(v, build) { - if (v === undefined) { - return this._parts[_part] || ""; - } else { - this._parts[_part] = v; - this.build(!build); - return this; - } - }; - }; - for (_part in _parts) { - p[_part] = generateAccessor(_parts[_part]); - } - // generate accessors with optionally prefixed input - _parts = { - query: '?', - fragment: '#' - }; - generateAccessor = function(_part, _key) { - return function(v, build) { - if (v === undefined) { - return this._parts[_part] || ""; - } else { - if (v !== null) { - v = v + ""; - if (v[0] === _key) { - v = v.substring(1); - } - } - this._parts[_part] = v; - this.build(!build); - return this; - } - }; - }; - for (_part in _parts) { - p[_part] = generateAccessor(_part, _parts[_part]); - } - // generate accessors with prefixed output - _parts = { - search: ['?', 'query'], - hash: ['#', 'fragment'] - }; - generateAccessor = function(_part, _key) { - return function(v, build) { - var t = this[_part](v, build); - return typeof t === "string" && t.length ? (_key + t) : t; - }; - }; - for (_part in _parts) { - p[_part] = generateAccessor(_parts[_part][1], _parts[_part][0]); - } - p.pathname = function(v, build) { - if (v === undefined || v === true) { - var res = this._parts.path || (this._parts.urn ? '' : '/'); - return v ? URI.decodePath(res) : res; - } else { - this._parts.path = v ? URI.recodePath(v) : "/"; - this.build(!build); - return this; - } - }; - p.path = p.pathname; - p.href = function(href, build) { - var key; - if (href === undefined) { - return this.toString(); - } - this._string = ""; - this._parts = URI._parts(); - var _URI = href instanceof URI; - var _object = typeof href === "object" && (href.hostname || href.path); - // window.location is reported to be an object, but it's not the sort - // of object we're looking for: - // * location.protocol ends with a colon - // * location.query != object.search - // * location.hash != object.fragment - // simply serializing the unknown object should do the trick - // (for location, not for everything...) - if (!_URI && _object && Object.prototype.toString.call(href) !== "[object Object]") { - href = href.toString(); - } - if (typeof href === "string") { - this._parts = URI.parse(href, this._parts); - } else if (_URI || _object) { - var src = _URI ? href._parts : href; - for (key in src) { - if (hasOwn.call(this._parts, key)) { - this._parts[key] = src[key]; - } - } - } else { - throw new TypeError("invalid input"); - } - this.build(!build); - return this; - }; - // identification accessors - p.is = function(what) { - var ip = false; - var ip4 = false; - var ip6 = false; - var name = false; - var sld = false; - var idn = false; - var punycode = false; - var relative = !this._parts.urn; - if (this._parts.hostname) { - relative = false; - ip4 = URI.ip4_expression.test(this._parts.hostname); - ip6 = URI.ip6_expression.test(this._parts.hostname); - ip = ip4 || ip6; - name = !ip; - sld = name && SLD && SLD.has(this._parts.hostname); - idn = name && URI.idn_expression.test(this._parts.hostname); - punycode = name && URI.punycode_expression.test(this._parts.hostname); - } - switch (what.toLowerCase()) { - case 'relative': - return relative; - case 'absolute': - return !relative; - // hostname identification - case 'domain': - case 'name': - return name; - case 'sld': - return sld; - case 'ip': - return ip; - case 'ip4': - case 'ipv4': - case 'inet4': - return ip4; - case 'ip6': - case 'ipv6': - case 'inet6': - return ip6; - case 'idn': - return idn; - case 'url': - return !this._parts.urn; - case 'urn': - return !!this._parts.urn; - case 'punycode': - return punycode; - } - return null; - }; - // component specific input validation - var _protocol = p.protocol; - var _port = p.port; - var _hostname = p.hostname; - p.protocol = function(v, build) { - if (v !== undefined) { - if (v) { - // accept trailing :// - v = v.replace(/:(\/\/)?$/, ''); - if (v.match(/[^a-zA-z0-9\.+-]/)) { - throw new TypeError("Protocol '" + v + "' contains characters other than [A-Z0-9.+-]"); - } - } - } - return _protocol.call(this, v, build); - }; - p.scheme = p.protocol; - p.port = function(v, build) { - if (this._parts.urn) { - return v === undefined ? '' : this; - } - if (v !== undefined) { - if (v === 0) { - v = null; - } - if (v) { - v += ""; - if (v[0] === ":") { - v = v.substring(1); - } - if (v.match(/[^0-9]/)) { - throw new TypeError("Port '" + v + "' contains characters other than [0-9]"); - } - } - } - return _port.call(this, v, build); - }; - p.hostname = function(v, build) { - if (this._parts.urn) { - return v === undefined ? '' : this; - } - if (v !== undefined) { - var x = {}; - URI.parseHost(v, x); - v = x.hostname; - } - return _hostname.call(this, v, build); - }; - // compound accessors - p.host = function(v, build) { - if (this._parts.urn) { - return v === undefined ? '' : this; - } - if (v === undefined) { - return this._parts.hostname ? URI.buildHost(this._parts) : ""; - } else { - URI.parseHost(v, this._parts); - this.build(!build); - return this; - } - }; - p.authority = function(v, build) { - if (this._parts.urn) { - return v === undefined ? '' : this; - } - if (v === undefined) { - return this._parts.hostname ? URI.buildAuthority(this._parts) : ""; - } else { - URI.parseAuthority(v, this._parts); - this.build(!build); - return this; - } - }; - p.userinfo = function(v, build) { - if (this._parts.urn) { - return v === undefined ? '' : this; - } - if (v === undefined) { - if (!this._parts.username) { - return ""; - } - var t = URI.buildUserinfo(this._parts); - return t.substring(0, t.length - 1); - } else { - if (v[v.length - 1] !== '@') { - v += '@'; - } - URI.parseUserinfo(v, this._parts); - this.build(!build); - return this; - } - }; - p.resource = function(v, build) { - var parts; - if (v === undefined) { - return this.path() + this.search() + this.hash(); - } - parts = URI.parse(v); - this._parts.path = parts.path; - this._parts.query = parts.query; - this._parts.fragment = parts.fragment; - this.build(!build); - return this; - }; - // fraction accessors - p.subdomain = function(v, build) { - if (this._parts.urn) { - return v === undefined ? '' : this; - } - // convenience, return "www" from "www.example.org" - if (v === undefined) { - if (!this._parts.hostname || this.is('IP')) { - return ""; - } - // grab domain and add another segment - var end = this._parts.hostname.length - this.domain().length - 1; - return this._parts.hostname.substring(0, end) || ""; - } else { - var e = this._parts.hostname.length - this.domain().length; - var sub = this._parts.hostname.substring(0, e); - var replace = new RegExp('^' + escapeRegEx(sub)); - if (v && v[v.length - 1] !== '.') { - v += "."; - } - if (v) { - URI.ensureValidHostname(v); - } - this._parts.hostname = this._parts.hostname.replace(replace, v); - this.build(!build); - return this; - } - }; - p.domain = function(v, build) { - if (this._parts.urn) { - return v === undefined ? '' : this; - } - if (typeof v === 'boolean') { - build = v; - v = undefined; - } - // convenience, return "example.org" from "www.example.org" - if (v === undefined) { - if (!this._parts.hostname || this.is('IP')) { - return ""; - } - // if hostname consists of 1 or 2 segments, it must be the domain - var t = this._parts.hostname.match(/\./g); - if (t && t.length < 2) { - return this._parts.hostname; - } - // grab tld and add another segment - var end = this._parts.hostname.length - this.tld(build).length - 1; - end = this._parts.hostname.lastIndexOf('.', end - 1) + 1; - return this._parts.hostname.substring(end) || ""; - } else { - if (!v) { - throw new TypeError("cannot set domain empty"); - } - URI.ensureValidHostname(v); - if (!this._parts.hostname || this.is('IP')) { - this._parts.hostname = v; - } else { - var replace = new RegExp(escapeRegEx(this.domain()) + "$"); - this._parts.hostname = this._parts.hostname.replace(replace, v); - } - this.build(!build); - return this; - } - }; - p.tld = function(v, build) { - if (this._parts.urn) { - return v === undefined ? '' : this; - } - if (typeof v === 'boolean') { - build = v; - v = undefined; - } - // return "org" from "www.example.org" - if (v === undefined) { - if (!this._parts.hostname || this.is('IP')) { - return ""; - } - var pos = this._parts.hostname.lastIndexOf('.'); - var tld = this._parts.hostname.substring(pos + 1); - if (build !== true && SLD && SLD.list[tld.toLowerCase()]) { - return SLD.get(this._parts.hostname) || tld; - } - return tld; - } else { - var replace; - if (!v) { - throw new TypeError("cannot set TLD empty"); - } else if (v.match(/[^a-zA-Z0-9-]/)) { - if (SLD && SLD.is(v)) { - replace = new RegExp(escapeRegEx(this.tld()) + "$"); - this._parts.hostname = this._parts.hostname.replace(replace, v); - } else { - throw new TypeError("TLD '" + v + "' contains characters other than [A-Z0-9]"); - } - } else if (!this._parts.hostname || this.is('IP')) { - throw new ReferenceError("cannot set TLD on non-domain host"); - } else { - replace = new RegExp(escapeRegEx(this.tld()) + "$"); - this._parts.hostname = this._parts.hostname.replace(replace, v); - } - this.build(!build); - return this; - } - }; - p.directory = function(v, build) { - if (this._parts.urn) { - return v === undefined ? '' : this; - } - if (v === undefined || v === true) { - if (!this._parts.path && !this._parts.hostname) { - return ''; - } - if (this._parts.path === '/') { - return '/'; - } - var end = this._parts.path.length - this.filename().length - 1; - var res = this._parts.path.substring(0, end) || (this._parts.hostname ? "/" : ""); - return v ? URI.decodePath(res) : res; - } else { - var e = this._parts.path.length - this.filename().length; - var directory = this._parts.path.substring(0, e); - var replace = new RegExp('^' + escapeRegEx(directory)); - // fully qualifier directories begin with a slash - if (!this.is('relative')) { - if (!v) { - v = '/'; - } - if (v[0] !== '/') { - v = "/" + v; - } - } - // directories always end with a slash - if (v && v[v.length - 1] !== '/') { - v += '/'; - } - v = URI.recodePath(v); - this._parts.path = this._parts.path.replace(replace, v); - this.build(!build); - return this; - } - }; - p.filename = function(v, build) { - if (this._parts.urn) { - return v === undefined ? '' : this; - } - if (v === undefined || v === true) { - if (!this._parts.path || this._parts.path === '/') { - return ""; - } - var pos = this._parts.path.lastIndexOf('/'); - var res = this._parts.path.substring(pos + 1); - return v ? URI.decodePathSegment(res) : res; - } else { - var mutatedDirectory = false; - if (v[0] === '/') { - v = v.substring(1); - } - if (v.match(/\.?\//)) { - mutatedDirectory = true; - } - var replace = new RegExp(escapeRegEx(this.filename()) + "$"); - v = URI.recodePath(v); - this._parts.path = this._parts.path.replace(replace, v); - if (mutatedDirectory) { - this.normalizePath(build); - } else { - this.build(!build); - } - return this; - } - }; - p.suffix = function(v, build) { - if (this._parts.urn) { - return v === undefined ? '' : this; - } - if (v === undefined || v === true) { - if (!this._parts.path || this._parts.path === '/') { - return ""; - } - var filename = this.filename(); - var pos = filename.lastIndexOf('.'); - var s, res; - if (pos === -1) { - return ""; - } - // suffix may only contain alnum characters (yup, I made this up.) - s = filename.substring(pos + 1); - res = (/^[a-z0-9%]+$/i).test(s) ? s : ""; - return v ? URI.decodePathSegment(res) : res; - } else { - if (v[0] === '.') { - v = v.substring(1); - } - var suffix = this.suffix(); - var replace; - if (!suffix) { - if (!v) { - return this; - } - this._parts.path += '.' + URI.recodePath(v); - } else if (!v) { - replace = new RegExp(escapeRegEx("." + suffix) + "$"); - } else { - replace = new RegExp(escapeRegEx(suffix) + "$"); - } - if (replace) { - v = URI.recodePath(v); - this._parts.path = this._parts.path.replace(replace, v); - } - this.build(!build); - return this; - } - }; - p.segment = function(segment, v, build) { - var separator = this._parts.urn ? ':' : '/'; - var path = this.path(); - var absolute = path.substring(0, 1) === '/'; - var segments = path.split(separator); - if (typeof segment !== 'number') { - build = v; - v = segment; - segment = undefined; - } - if (segment !== undefined && typeof segment !== 'number') { - throw new Error("Bad segment '" + segment + "', must be 0-based integer"); - } - if (absolute) { - segments.shift(); - } - if (segment < 0) { - // allow negative indexes to address from the end - segment = Math.max(segments.length + segment, 0); - } - if (v === undefined) { - return segment === undefined ? segments : segments[segment]; - } else if (segment === null || segments[segment] === undefined) { - if (isArray(v)) { - segments = v; - } else if (v || (typeof v === "string" && v.length)) { - if (segments[segments.length - 1] === "") { - // empty trailing elements have to be overwritten - // to prefent results such as /foo//bar - segments[segments.length - 1] = v; - } else { - segments.push(v); - } - } - } else { - if (v || (typeof v === "string" && v.length)) { - segments[segment] = v; - } else { - segments.splice(segment, 1); - } - } - if (absolute) { - segments.unshift(""); - } - return this.path(segments.join(separator), build); - }; - // mutating query string - var q = p.query; - p.query = function(v, build) { - if (v === true) { - return URI.parseQuery(this._parts.query); - } else if (v !== undefined && typeof v !== "string") { - this._parts.query = URI.buildQuery(v, this._parts.duplicateQueryParameters); - this.build(!build); - return this; - } else { - return q.call(this, v, build); - } - }; - p.addQuery = function(name, value, build) { - var data = URI.parseQuery(this._parts.query); - URI.addQuery(data, name, value === undefined ? null : value); - this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters); - if (typeof name !== "string") { - build = value; - } - this.build(!build); - return this; - }; - p.removeQuery = function(name, value, build) { - var data = URI.parseQuery(this._parts.query); - URI.removeQuery(data, name, value); - this._parts.query = URI.buildQuery(data, this._parts.duplicateQueryParameters); - if (typeof name !== "string") { - build = value; - } - this.build(!build); - return this; - }; - p.addSearch = p.addQuery; - p.removeSearch = p.removeQuery; - // sanitizing URLs - p.normalize = function() { - if (this._parts.urn) { - return this.normalizeProtocol(false).normalizeQuery(false).normalizeFragment(false).build(); - } - return this.normalizeProtocol(false).normalizeHostname(false).normalizePort(false).normalizePath(false).normalizeQuery(false).normalizeFragment(false).build(); - }; - p.normalizeProtocol = function(build) { - if (typeof this._parts.protocol === "string") { - this._parts.protocol = this._parts.protocol.toLowerCase(); - this.build(!build); - } - return this; - }; - p.normalizeHostname = function(build) { - if (this._parts.hostname) { - if (this.is('IDN') && punycode) { - this._parts.hostname = punycode.toASCII(this._parts.hostname); - } else if (this.is('IPv6') && IPv6) { - this._parts.hostname = IPv6.best(this._parts.hostname); - } - this._parts.hostname = this._parts.hostname.toLowerCase(); - this.build(!build); - } - return this; - }; - p.normalizePort = function(build) { - // remove port of it's the protocol's default - if (typeof this._parts.protocol === "string" && this._parts.port === URI.defaultPorts[this._parts.protocol]) { - this._parts.port = null; - this.build(!build); - } - return this; - }; - p.normalizePath = function(build) { - if (this._parts.urn) { - return this; - } - if (!this._parts.path || this._parts.path === '/') { - return this; - } - var _was_relative; - var _was_relative_prefix; - var _path = this._parts.path; - var _parent, _pos; - // handle relative paths - if (_path[0] !== '/') { - if (_path[0] === '.') { - _was_relative_prefix = _path.substring(0, _path.indexOf('/')); - } - _was_relative = true; - _path = '/' + _path; - } - // resolve simples - _path = _path.replace(/(\/(\.\/)+)|\/{2,}/g, '/'); - // resolve parents - while (true) { - _parent = _path.indexOf('/../'); - if (_parent === -1) { - // no more ../ to resolve - break; - } else if (_parent === 0) { - // top level cannot be relative... - _path = _path.substring(3); - break; - } - _pos = _path.substring(0, _parent).lastIndexOf('/'); - if (_pos === -1) { - _pos = _parent; - } - _path = _path.substring(0, _pos) + _path.substring(_parent + 3); - } - // revert to relative - if (_was_relative && this.is('relative')) { - if (_was_relative_prefix) { - _path = _was_relative_prefix + _path; - } else { - _path = _path.substring(1); - } - } - _path = URI.recodePath(_path); - this._parts.path = _path; - this.build(!build); - return this; - }; - p.normalizePathname = p.normalizePath; - p.normalizeQuery = function(build) { - if (typeof this._parts.query === "string") { - if (!this._parts.query.length) { - this._parts.query = null; - } else { - this.query(URI.parseQuery(this._parts.query)); - } - this.build(!build); - } - return this; - }; - p.normalizeFragment = function(build) { - if (!this._parts.fragment) { - this._parts.fragment = null; - this.build(!build); - } - return this; - }; - p.normalizeSearch = p.normalizeQuery; - p.normalizeHash = p.normalizeFragment; - p.iso8859 = function() { - // expect unicode input, iso8859 output - var e = URI.encode; - var d = URI.decode; - URI.encode = escape; - URI.decode = decodeURIComponent; - this.normalize(); - URI.encode = e; - URI.decode = d; - return this; - }; - p.unicode = function() { - // expect iso8859 input, unicode output - var e = URI.encode; - var d = URI.decode; - URI.encode = strictEncodeURIComponent; - URI.decode = unescape; - this.normalize(); - URI.encode = e; - URI.decode = d; - return this; - }; - p.readable = function() { - var uri = this.clone(); - // removing username, password, because they shouldn't be displayed according to RFC 3986 - uri.username("").password("").normalize(); - var t = ''; - if (uri._parts.protocol) { - t += uri._parts.protocol + '://'; - } - if (uri._parts.hostname) { - if (uri.is('punycode') && punycode) { - t += punycode.toUnicode(uri._parts.hostname); - if (uri._parts.port) { - t += ":" + uri._parts.port; - } - } else { - t += uri.host(); - } - } - if (uri._parts.hostname && uri._parts.path && uri._parts.path[0] !== '/') { - t += '/'; - } - t += uri.path(true); - if (uri._parts.query) { - var q = ''; - for (var i = 0, qp = uri._parts.query.split('&'), l = qp.length; i < l; i++) { - var kv = (qp[i] || "").split('='); - q += '&' + URI.decodeQuery(kv[0]).replace(/&/g, '%26'); - if (kv[1] !== undefined) { - q += "=" + URI.decodeQuery(kv[1]).replace(/&/g, '%26'); - } - } - t += '?' + q.substring(1); - } - t += uri.hash(); - return t; - }; - // resolving relative and absolute URLs - p.absoluteTo = function(base) { - var resolved = this.clone(); - var properties = ['protocol', 'username', 'password', 'hostname', 'port']; - var basedir, i, p; - if (this._parts.urn) { - throw new Error('URNs do not have any generally defined hierachical components'); - } - if (this._parts.hostname) { - return resolved; - } - if (!(base instanceof URI)) { - base = new URI(base); - } - for (i = 0, p; p = properties[i]; i++) { - resolved._parts[p] = base._parts[p]; - } - properties = ['query', 'path']; - for (i = 0, p; p = properties[i]; i++) { - if (!resolved._parts[p] && base._parts[p]) { - resolved._parts[p] = base._parts[p]; - } - } - if (resolved.path()[0] !== '/') { - basedir = base.directory(); - resolved._parts.path = (basedir ? (basedir + '/') : '') + resolved._parts.path; - resolved.normalizePath(); - } - resolved.build(); - return resolved; - }; - p.relativeTo = function(base) { - var relative = this.clone(); - var properties = ['protocol', 'username', 'password', 'hostname', 'port']; - var common, _base, _this, _base_diff, _this_diff; - if (this._parts.urn) { - throw new Error('URNs do not have any generally defined hierachical components'); - } - if (!(base instanceof URI)) { - base = new URI(base); - } - if (this.path()[0] !== '/' || base.path()[0] !== '/') { - throw new Error('Cannot calculate common path from non-relative URLs'); - } - // determine common sub path - common = URI.commonPath(relative.path(), base.path()); - // no relation if there's nothing in common - if (!common || common === '/') { - return relative; - } - // relative paths don't have authority - for (var i = 0, p; p = properties[i]; i++) { - relative._parts[p] = null; - } - _base = base.directory(); - _this = this.directory(); - // base and this are on the same level - if (_base === _this) { - relative._parts.path = './' + relative.filename(); - return relative.build(); - } - _base_diff = _base.substring(common.length); - _this_diff = _this.substring(common.length); - // this is a descendant of base - if (_base + '/' === common) { - if (_this_diff) { - _this_diff += '/'; - } - relative._parts.path = './' + _this_diff + relative.filename(); - return relative.build(); - } - // this is a descendant of base - var parents = '../'; - var _common = new RegExp('^' + escapeRegEx(common)); - var _parents = _base.replace(_common, '/').match(/\//g).length - 1; - while (_parents--) { - parents += '../'; - } - relative._parts.path = relative._parts.path.replace(_common, parents); - return relative.build(); - }; - // comparing URIs - p.equals = function(uri) { - var one = this.clone(); - var two = new URI(uri); - var one_map = {}; - var two_map = {}; - var checked = {}; - var one_query, two_query, key; - one.normalize(); - two.normalize(); - // exact match - if (one.toString() === two.toString()) { - return true; - } - // extract query string - one_query = one.query(); - two_query = two.query(); - one.query(""); - two.query(""); - // definitely not equal if not even non-query parts match - if (one.toString() !== two.toString()) { - return false; - } - // query parameters have the same length, even if they're permutated - if (one_query.length !== two_query.length) { - return false; - } - one_map = URI.parseQuery(one_query); - two_map = URI.parseQuery(two_query); - for (key in one_map) { - if (hasOwn.call(one_map, key)) { - if (!isArray(one_map[key])) { - if (one_map[key] !== two_map[key]) { - return false; - } - } else { - if (!isArray(two_map[key])) { - return false; - } - // arrays can't be equal if they have different amount of content - if (one_map[key].length !== two_map[key].length) { - return false; - } - one_map[key].sort(); - two_map[key].sort(); - for (var i = 0, l = one_map[key].length; i < l; i++) { - if (one_map[key][i] !== two_map[key][i]) { - return false; - } - } - } - checked[key] = true; - } - } - for (key in two_map) { - if (hasOwn.call(two_map, key)) { - if (!checked[key]) { - // two contains a parameter not present in one - return false; - } - } - } - return true; - }; - // state - p.duplicateQueryParameters = function(v) { - this._parts.duplicateQueryParameters = !! v; - return this; - }; - return URI; -})); \ No newline at end of file diff --git a/doc/scripts/bootstrap-dropdown.js b/doc/scripts/bootstrap-dropdown.js deleted file mode 100644 index d04da5d..0000000 --- a/doc/scripts/bootstrap-dropdown.js +++ /dev/null @@ -1,169 +0,0 @@ -/* ============================================================ - * bootstrap-dropdown.js v2.3.2 - * http://getbootstrap.com/2.3.2/javascript.html#dropdowns - * ============================================================ - * Copyright 2013 Twitter, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============================================================ */ - - -!function ($) { - - "use strict"; // jshint ;_; - - - /* DROPDOWN CLASS DEFINITION - * ========================= */ - - var toggle = '[data-toggle=dropdown]' - , Dropdown = function (element) { - var $el = $(element).on('click.dropdown.data-api', this.toggle) - $('html').on('click.dropdown.data-api', function () { - $el.parent().removeClass('open') - }) - } - - Dropdown.prototype = { - - constructor: Dropdown - - , toggle: function (e) { - var $this = $(this) - , $parent - , isActive - - if ($this.is('.disabled, :disabled')) return - - $parent = getParent($this) - - isActive = $parent.hasClass('open') - - clearMenus() - - if (!isActive) { - if ('ontouchstart' in document.documentElement) { - // if mobile we we use a backdrop because click events don't delegate - $('